fix: prevent deadlock when wanted mnemonics conflict (#1200)

* fix: prevent deadlock when wanted mnemonics conflict

* fix: remove invalid mnemonics from translations
This commit is contained in:
Jann Stute
2026-01-23 06:55:03 +01:00
committed by GitHub
parent 2a2d279725
commit 4dc06835cb
11 changed files with 46 additions and 15 deletions

View File

@@ -1,10 +1,13 @@
# Licensed under the GPL-3.0 License.
# Created for TagStudio: https://github.com/CyanVoxel/TagStudio
import re
import structlog
from PySide6.QtGui import QAction
from PySide6.QtWidgets import QMenu
logger = structlog.get_logger(__name__)
def remove_mnemonic_marker(label: str) -> str:
"""Remove existing accelerator markers (&) from a label."""
@@ -25,6 +28,31 @@ def remove_mnemonic_marker(label: str) -> str:
return result
def get_wanted_mnemonics(text: str) -> list[str]:
matches = re.findall("(?:^|[^&])&([^&])", text)
return matches
def sanitise_mnemonics(actions: list[QAction]) -> None:
previous = []
for action in actions:
text = action.text()
m = get_wanted_mnemonics(text)
if len(m) == 0:
continue
elif len(m) > 1:
logger.warning("Found multiple wanted mnemonics, removing all", text=text)
action.setText(remove_mnemonic_marker(text))
continue
elif m[0] in previous:
logger.warning("Removing conflicting mnemonic", text=text)
action.setText(remove_mnemonic_marker(text))
continue
previous.append(m[0])
# Additional weight for first character in string
FIRST_CHARACTER_EXTRA_WEIGHT = 50
# Additional weight for the beginning of a word
@@ -97,6 +125,9 @@ def assign_mnemonics(menu: QMenu):
# Collect actions
actions = [a for a in menu.actions() if not a.isSeparator()]
# sanitise mnemonics to prevent deadlocks
sanitise_mnemonics(actions)
# Sequence map: mnemonic key -> QAction
sequence_to_action: dict[str, QAction] = {}

View File

@@ -224,7 +224,7 @@
"menu.file.open_create_library": "&Abrir/Crear biblioteca",
"menu.file.open_library": "Abrir biblioteca",
"menu.file.open_recent_library": "Abrir reciente",
"menu.file.refresh_directories": "&Actualizar directorios",
"menu.file.refresh_directories": "Actualizar directorios",
"menu.file.save_backup": "&Guardar copia de seguridad de la biblioteca",
"menu.file.save_library": "Guardar biblioteca",
"menu.help": "&Ayuda",

View File

@@ -33,7 +33,7 @@
"drop_import.progress.window_title": "Fájlok importálása",
"drop_import.title": "Fájlütközés",
"edit.color_manager": "&Színek kezelése",
"edit.copy_fields": "Mezők &másolása",
"edit.copy_fields": "Mezők másolása",
"edit.paste_fields": "Mezők &beillesztése",
"edit.tag_manager": "Címkék kezelése",
"entries.duplicate.merge": "Egyező elemek &egyesítése",
@@ -212,7 +212,7 @@
"menu.delete_selected_files_singular": "Fájl {trash_term} &helyezése",
"menu.edit": "S&zerkesztés",
"menu.edit.ignore_files": "Fájlok és mappák figyelmen kívül hagyása",
"menu.edit.manage_tags": "&Címkék ke&zelése",
"menu.edit.manage_tags": "Címkék kezelése",
"menu.edit.new_tag": "Ú&j címke",
"menu.file": "&Fájl",
"menu.file.clear_recent_libraries": "&Legutóbbi könyvtárak listájának törlése",

View File

@@ -224,7 +224,7 @@
"menu.file.open_create_library": "&Apri/Crea Biblioteca",
"menu.file.open_library": "Apri Biblioteca",
"menu.file.open_recent_library": "Apri Recenti",
"menu.file.refresh_directories": "&Aggiorna Cartelle",
"menu.file.refresh_directories": "Aggiorna Cartelle",
"menu.file.save_backup": "&Salva Backup della Biblioteca",
"menu.file.save_library": "Salva Biblioteca",
"menu.help": "&Aiuto",

View File

@@ -195,7 +195,7 @@
"menu.edit.new_tag": "Ny &Etikett",
"menu.file": "Fil",
"menu.file.clear_recent_libraries": "Fjern Nylige",
"menu.file.close_library": "&Lukk Bibliotek",
"menu.file.close_library": "Lukk Bibliotek",
"menu.file.missing_library.message": "Plasseringen til biblioteket \"{library}\" kan ikke finnes.",
"menu.file.missing_library.title": "Manglende Bibliotek",
"menu.file.new_library": "Nytt Bibliotek",
@@ -212,7 +212,7 @@
"menu.select": "Velg",
"menu.settings": "Innstillinger...",
"menu.tools": "Verktøy",
"menu.tools.fix_duplicate_files": "Fiks Duplikate &Filer",
"menu.tools.fix_duplicate_files": "Fiks Duplikate Filer",
"menu.tools.fix_unlinked_entries": "Fiks &Frakoblede Oppføringer",
"menu.view": "&Se",
"menu.window": "Vindu",

View File

@@ -181,14 +181,14 @@
"menu.edit.new_tag": "Nowy &Tag",
"menu.file": "&Plik",
"menu.file.clear_recent_libraries": "Wyczyść ostatnie",
"menu.file.close_library": "&Zamknij bibliotekę",
"menu.file.close_library": "Zamknij bibliotekę",
"menu.file.missing_library.message": "Lokalizacja biblioteki \"{library}\" nie została odnaleziona.",
"menu.file.missing_library.title": "Brakująca biblioteka",
"menu.file.new_library": "Nowa biblioteka",
"menu.file.open_create_library": "&Otwórz/Stwórz bibliotekę",
"menu.file.open_library": "Otwórz bibliotekę",
"menu.file.open_recent_library": "Otwórz ostatnie",
"menu.file.refresh_directories": "&Odśwież katalogi",
"menu.file.refresh_directories": "Odśwież katalogi",
"menu.file.save_backup": "&Zapisz kopię zapasową biblioteki",
"menu.file.save_library": "Zapisz bibliotekę",
"menu.help": "&Pomoc",

View File

@@ -181,7 +181,7 @@
"menu.file.open_create_library": "&Abrir/Criar Biblioteca",
"menu.file.open_library": "Abrir Biblioteca",
"menu.file.open_recent_library": "Abrir Recente",
"menu.file.refresh_directories": "&Atualizar Pastas",
"menu.file.refresh_directories": "Atualizar Pastas",
"menu.file.save_backup": "&Gravar Backup da Biblioteca",
"menu.file.save_library": "Gravar Biblioteca",
"menu.help": "&Ajuda",

View File

@@ -224,7 +224,7 @@
"menu.file.open_create_library": "&Abrir/Criar Biblioteca",
"menu.file.open_library": "Abrir Biblioteca",
"menu.file.open_recent_library": "Abrir Recente",
"menu.file.refresh_directories": "&Atualizar Pastas",
"menu.file.refresh_directories": "Atualizar Pastas",
"menu.file.save_backup": "&Salvar Backup da Biblioteca",
"menu.file.save_library": "Salvar Biblioteca",
"menu.help": "&Ajuda",

View File

@@ -195,7 +195,7 @@
"menu.file.open_create_library": "&Открыть/создать библиотеку",
"menu.file.open_library": "Открыть библиотеку",
"menu.file.open_recent_library": "Открыть последнюю",
"menu.file.refresh_directories": "&Обновить папки",
"menu.file.refresh_directories": "Обновить папки",
"menu.file.save_backup": "&Сохранить резервную копию библиотеки",
"menu.file.save_library": "Сохранить библиотеку",
"menu.help": "&Помощь",

View File

@@ -216,7 +216,7 @@
"menu.edit.new_tag": "புதிய & குறிச்சொல்",
"menu.file": "கோப்பு (&f)",
"menu.file.clear_recent_libraries": "சமீபத்தியதை அழிக்கவும்",
"menu.file.close_library": "& நூலகம் மூடு",
"menu.file.close_library": " நூலகம் மூடு",
"menu.file.missing_library.message": "\"{library}\" நூலகத்தின் இருப்பிடத்தைக் கண்டுபிடிக்க முடியாது.",
"menu.file.missing_library.title": "நூலகம் இல்லை",
"menu.file.new_library": "புதிய நூலகம்",
@@ -225,7 +225,7 @@
"menu.file.open_library": "திறந்த நூலகம்",
"menu.file.open_recent_library": "அண்மைக் கால திறப்பு",
"menu.file.refresh_directories": "கோப்பகத்தை புதுப்பிக்கவும்",
"menu.file.save_backup": "& நூலக காப்புப்பிரதியை சேமிக்கவும்",
"menu.file.save_backup": " நூலக காப்புப்பிரதியை சேமிக்கவும்",
"menu.file.save_library": "நூலகத்தை சேமிக்கவும்",
"menu.help": "உதவி (&h)",
"menu.help.about": "பற்றி",

View File

@@ -182,7 +182,7 @@
"menu.edit.new_tag": "Yeni &Etiket",
"menu.file": "&Dosya",
"menu.file.clear_recent_libraries": "Yakın Geçmişi Temizle",
"menu.file.close_library": "Kütüphaneyi &Kapat",
"menu.file.close_library": "Kütüphaneyi Kapat",
"menu.file.new_library": "Yeni Kütüphane",
"menu.file.open_create_library": "Kütüphane &Aç/Oluştur",
"menu.file.open_library": "Kütüphane Aç",