fix(shortcuts): change bookmark shortcut from Ctrl+D to Ctrl+B (#3691)
* fix(shortcuts): change bookmark shortcut from Ctrl+D to Ctrl+B, closes #3675 Ctrl+D was bound to both Toggle Bookmark (General) and Dictionary Lookup (Selection). When text was selected and Ctrl+D pressed, both actions fired — opening the dictionary AND adding an unwanted bookmark. Changed bookmark to Ctrl+B/Cmd+B to resolve the conflict. Added a unit test that detects identical keybinding lists across actions to prevent this class of bug in the future. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * i18n: mark shortcut section names for translation Wrap SHORTCUT_SECTIONS values with stubTranslation() so i18next-scanner picks them up. Translate the 4 new keys (General, Text to Speech, Zoom, Window) across all 29 locales. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1191,5 +1191,9 @@
|
||||
"Scroll Half Page Down": "تمرير نصف صفحة لأسفل",
|
||||
"Scroll Half Page Up": "تمرير نصف صفحة لأعلى",
|
||||
"Save Note": "حفظ الملاحظة",
|
||||
"Single Section Scroll": "التمرير بقسم واحد"
|
||||
"Single Section Scroll": "التمرير بقسم واحد",
|
||||
"General": "عام",
|
||||
"Text to Speech": "تحويل النص إلى كلام",
|
||||
"Zoom": "تكبير",
|
||||
"Window": "نافذة"
|
||||
}
|
||||
|
||||
@@ -1139,5 +1139,9 @@
|
||||
"Scroll Half Page Down": "অর্ধেক পৃষ্ঠা নিচে স্ক্রল করুন",
|
||||
"Scroll Half Page Up": "অর্ধেক পৃষ্ঠা উপরে স্ক্রল করুন",
|
||||
"Save Note": "নোট সংরক্ষণ করুন",
|
||||
"Single Section Scroll": "একক অধ্যায় স্ক্রল"
|
||||
"Single Section Scroll": "একক অধ্যায় স্ক্রল",
|
||||
"General": "সাধারণ",
|
||||
"Text to Speech": "পাঠ থেকে বাক্য",
|
||||
"Zoom": "জুম",
|
||||
"Window": "উইন্ডো"
|
||||
}
|
||||
|
||||
@@ -1126,5 +1126,9 @@
|
||||
"Scroll Half Page Down": "ཤོག་ངོས་ཕྱེད་ཀ་འོག་ཏུ།",
|
||||
"Scroll Half Page Up": "ཤོག་ངོས་ཕྱེད་ཀ་གོང་དུ།",
|
||||
"Save Note": "ཟིན་བྲིས་ཉར་བ།",
|
||||
"Single Section Scroll": "དོན་ཚན་གཅིག་འགུལ་བ།"
|
||||
"Single Section Scroll": "དོན་ཚན་གཅིག་འགུལ་བ།",
|
||||
"General": "སྤྱིར་བཏང་།",
|
||||
"Text to Speech": "ཡི་གེ་ནས་སྒྲ།",
|
||||
"Zoom": "ཆེ་རུ་གཏོང་།",
|
||||
"Window": "སྒེའུ་ཁུང་།"
|
||||
}
|
||||
|
||||
@@ -1139,5 +1139,9 @@
|
||||
"Scroll Half Page Down": "Halbe Seite nach unten scrollen",
|
||||
"Scroll Half Page Up": "Halbe Seite nach oben scrollen",
|
||||
"Save Note": "Notiz speichern",
|
||||
"Single Section Scroll": "Einzelabschnitt-Scrollen"
|
||||
"Single Section Scroll": "Einzelabschnitt-Scrollen",
|
||||
"General": "Allgemein",
|
||||
"Text to Speech": "Sprachausgabe",
|
||||
"Zoom": "Zoom",
|
||||
"Window": "Fenster"
|
||||
}
|
||||
|
||||
@@ -1139,5 +1139,9 @@
|
||||
"Scroll Half Page Down": "Κύλιση μισής σελίδας κάτω",
|
||||
"Scroll Half Page Up": "Κύλιση μισής σελίδας πάνω",
|
||||
"Save Note": "Αποθήκευση σημείωσης",
|
||||
"Single Section Scroll": "Κύλιση μεμονωμένης ενότητας"
|
||||
"Single Section Scroll": "Κύλιση μεμονωμένης ενότητας",
|
||||
"General": "Γενικά",
|
||||
"Text to Speech": "Κείμενο σε ομιλία",
|
||||
"Zoom": "Ζουμ",
|
||||
"Window": "Παράθυρο"
|
||||
}
|
||||
|
||||
@@ -1152,5 +1152,9 @@
|
||||
"Scroll Half Page Down": "Desplazar media página abajo",
|
||||
"Scroll Half Page Up": "Desplazar media página arriba",
|
||||
"Save Note": "Guardar nota",
|
||||
"Single Section Scroll": "Desplazamiento por sección"
|
||||
"Single Section Scroll": "Desplazamiento por sección",
|
||||
"General": "General",
|
||||
"Text to Speech": "Texto a voz",
|
||||
"Zoom": "Zoom",
|
||||
"Window": "Ventana"
|
||||
}
|
||||
|
||||
@@ -1139,5 +1139,9 @@
|
||||
"Scroll Half Page Down": "پیمایش نیم صفحه پایین",
|
||||
"Scroll Half Page Up": "پیمایش نیم صفحه بالا",
|
||||
"Save Note": "ذخیره یادداشت",
|
||||
"Single Section Scroll": "پیمایش تکبخشی"
|
||||
"Single Section Scroll": "پیمایش تکبخشی",
|
||||
"General": "عمومی",
|
||||
"Text to Speech": "تبدیل متن به گفتار",
|
||||
"Zoom": "بزرگنمایی",
|
||||
"Window": "پنجره"
|
||||
}
|
||||
|
||||
@@ -1152,5 +1152,9 @@
|
||||
"Scroll Half Page Down": "Défiler d'une demi-page vers le bas",
|
||||
"Scroll Half Page Up": "Défiler d'une demi-page vers le haut",
|
||||
"Save Note": "Enregistrer la note",
|
||||
"Single Section Scroll": "Défilement par section"
|
||||
"Single Section Scroll": "Défilement par section",
|
||||
"General": "Général",
|
||||
"Text to Speech": "Synthèse vocale",
|
||||
"Zoom": "Zoom",
|
||||
"Window": "Fenêtre"
|
||||
}
|
||||
|
||||
@@ -1152,5 +1152,9 @@
|
||||
"Scroll Half Page Down": "גלול חצי עמוד למטה",
|
||||
"Scroll Half Page Up": "גלול חצי עמוד למעלה",
|
||||
"Save Note": "שמור הערה",
|
||||
"Single Section Scroll": "גלילת קטע בודד"
|
||||
"Single Section Scroll": "גלילת קטע בודד",
|
||||
"General": "כללי",
|
||||
"Text to Speech": "טקסט לדיבור",
|
||||
"Zoom": "זום",
|
||||
"Window": "חלון"
|
||||
}
|
||||
|
||||
@@ -1139,5 +1139,9 @@
|
||||
"Scroll Half Page Down": "आधा पृष्ठ नीचे स्क्रॉल करें",
|
||||
"Scroll Half Page Up": "आधा पृष्ठ ऊपर स्क्रॉल करें",
|
||||
"Save Note": "नोट सहेजें",
|
||||
"Single Section Scroll": "एकल अनुभाग स्क्रॉल"
|
||||
"Single Section Scroll": "एकल अनुभाग स्क्रॉल",
|
||||
"General": "सामान्य",
|
||||
"Text to Speech": "पाठ से वाक्",
|
||||
"Zoom": "ज़ूम",
|
||||
"Window": "विंडो"
|
||||
}
|
||||
|
||||
@@ -1126,5 +1126,9 @@
|
||||
"Scroll Half Page Down": "Gulir setengah halaman ke bawah",
|
||||
"Scroll Half Page Up": "Gulir setengah halaman ke atas",
|
||||
"Save Note": "Simpan catatan",
|
||||
"Single Section Scroll": "Gulir Satu Bagian"
|
||||
"Single Section Scroll": "Gulir Satu Bagian",
|
||||
"General": "Umum",
|
||||
"Text to Speech": "Teks ke Suara",
|
||||
"Zoom": "Zoom",
|
||||
"Window": "Jendela"
|
||||
}
|
||||
|
||||
@@ -1152,5 +1152,9 @@
|
||||
"Scroll Half Page Down": "Scorri mezza pagina in basso",
|
||||
"Scroll Half Page Up": "Scorri mezza pagina in alto",
|
||||
"Save Note": "Salva nota",
|
||||
"Single Section Scroll": "Scorrimento a sezione singola"
|
||||
"Single Section Scroll": "Scorrimento a sezione singola",
|
||||
"General": "Generale",
|
||||
"Text to Speech": "Sintesi vocale",
|
||||
"Zoom": "Zoom",
|
||||
"Window": "Finestra"
|
||||
}
|
||||
|
||||
@@ -1126,5 +1126,9 @@
|
||||
"Scroll Half Page Down": "半ページ下にスクロール",
|
||||
"Scroll Half Page Up": "半ページ上にスクロール",
|
||||
"Save Note": "メモを保存",
|
||||
"Single Section Scroll": "単一セクションスクロール"
|
||||
"Single Section Scroll": "単一セクションスクロール",
|
||||
"General": "一般",
|
||||
"Text to Speech": "テキスト読み上げ",
|
||||
"Zoom": "ズーム",
|
||||
"Window": "ウィンドウ"
|
||||
}
|
||||
|
||||
@@ -1126,5 +1126,9 @@
|
||||
"Scroll Half Page Down": "반 페이지 아래로 스크롤",
|
||||
"Scroll Half Page Up": "반 페이지 위로 스크롤",
|
||||
"Save Note": "메모 저장",
|
||||
"Single Section Scroll": "단일 섹션 스크롤"
|
||||
"Single Section Scroll": "단일 섹션 스크롤",
|
||||
"General": "일반",
|
||||
"Text to Speech": "텍스트 음성 변환",
|
||||
"Zoom": "확대/축소",
|
||||
"Window": "창"
|
||||
}
|
||||
|
||||
@@ -1126,5 +1126,9 @@
|
||||
"Scroll Half Page Down": "Tatal separuh halaman ke bawah",
|
||||
"Scroll Half Page Up": "Tatal separuh halaman ke atas",
|
||||
"Save Note": "Simpan nota",
|
||||
"Single Section Scroll": "Tatal Satu Bahagian"
|
||||
"Single Section Scroll": "Tatal Satu Bahagian",
|
||||
"General": "Umum",
|
||||
"Text to Speech": "Teks ke Pertuturan",
|
||||
"Zoom": "Zum",
|
||||
"Window": "Tetingkap"
|
||||
}
|
||||
|
||||
@@ -1139,5 +1139,9 @@
|
||||
"Scroll Half Page Down": "Halve pagina naar beneden scrollen",
|
||||
"Scroll Half Page Up": "Halve pagina naar boven scrollen",
|
||||
"Save Note": "Notitie opslaan",
|
||||
"Single Section Scroll": "Scrollen per sectie"
|
||||
"Single Section Scroll": "Scrollen per sectie",
|
||||
"General": "Algemeen",
|
||||
"Text to Speech": "Tekst naar spraak",
|
||||
"Zoom": "Zoom",
|
||||
"Window": "Venster"
|
||||
}
|
||||
|
||||
@@ -1165,5 +1165,9 @@
|
||||
"Scroll Half Page Down": "Przewiń o pół strony w dół",
|
||||
"Scroll Half Page Up": "Przewiń o pół strony w górę",
|
||||
"Save Note": "Zapisz notatkę",
|
||||
"Single Section Scroll": "Przewijanie pojedynczej sekcji"
|
||||
"Single Section Scroll": "Przewijanie pojedynczej sekcji",
|
||||
"General": "Ogólne",
|
||||
"Text to Speech": "Tekst na mowę",
|
||||
"Zoom": "Powiększenie",
|
||||
"Window": "Okno"
|
||||
}
|
||||
|
||||
@@ -1152,5 +1152,9 @@
|
||||
"Scroll Half Page Down": "Rolar meia página para baixo",
|
||||
"Scroll Half Page Up": "Rolar meia página para cima",
|
||||
"Save Note": "Salvar nota",
|
||||
"Single Section Scroll": "Rolagem por seção"
|
||||
"Single Section Scroll": "Rolagem por seção",
|
||||
"General": "Geral",
|
||||
"Text to Speech": "Texto para fala",
|
||||
"Zoom": "Zoom",
|
||||
"Window": "Janela"
|
||||
}
|
||||
|
||||
@@ -1165,5 +1165,9 @@
|
||||
"Scroll Half Page Down": "Прокрутить на полстраницы вниз",
|
||||
"Scroll Half Page Up": "Прокрутить на полстраницы вверх",
|
||||
"Save Note": "Сохранить заметку",
|
||||
"Single Section Scroll": "Прокрутка одного раздела"
|
||||
"Single Section Scroll": "Прокрутка одного раздела",
|
||||
"General": "Общие",
|
||||
"Text to Speech": "Озвучивание",
|
||||
"Zoom": "Масштаб",
|
||||
"Window": "Окно"
|
||||
}
|
||||
|
||||
@@ -1139,5 +1139,9 @@
|
||||
"Scroll Half Page Down": "අඩ පිටුවක් පහළට අනුචලනය",
|
||||
"Scroll Half Page Up": "අඩ පිටුවක් ඉහළට අනුචලනය",
|
||||
"Save Note": "සටහන සුරකින්න",
|
||||
"Single Section Scroll": "තනි කොටස අනුචලනය"
|
||||
"Single Section Scroll": "තනි කොටස අනුචලනය",
|
||||
"General": "සාමාන්ය",
|
||||
"Text to Speech": "පෙළ කථනය",
|
||||
"Zoom": "විශාලනය",
|
||||
"Window": "කවුළුව"
|
||||
}
|
||||
|
||||
@@ -1165,5 +1165,9 @@
|
||||
"Scroll Half Page Down": "Drsi pol strani navzdol",
|
||||
"Scroll Half Page Up": "Drsi pol strani navzgor",
|
||||
"Save Note": "Shrani opombo",
|
||||
"Single Section Scroll": "Drsenje posameznega razdelka"
|
||||
"Single Section Scroll": "Drsenje posameznega razdelka",
|
||||
"General": "Splošno",
|
||||
"Text to Speech": "Besedilo v govor",
|
||||
"Zoom": "Povečava",
|
||||
"Window": "Okno"
|
||||
}
|
||||
|
||||
@@ -1139,5 +1139,9 @@
|
||||
"Scroll Half Page Down": "Rulla en halv sida nedåt",
|
||||
"Scroll Half Page Up": "Rulla en halv sida uppåt",
|
||||
"Save Note": "Spara anteckning",
|
||||
"Single Section Scroll": "Rullning per avsnitt"
|
||||
"Single Section Scroll": "Rullning per avsnitt",
|
||||
"General": "Allmänt",
|
||||
"Text to Speech": "Text till tal",
|
||||
"Zoom": "Zoom",
|
||||
"Window": "Fönster"
|
||||
}
|
||||
|
||||
@@ -1139,5 +1139,9 @@
|
||||
"Scroll Half Page Down": "அரை பக்கம் கீழே உருட்டுக",
|
||||
"Scroll Half Page Up": "அரை பக்கம் மேலே உருட்டுக",
|
||||
"Save Note": "குறிப்பைச் சேமிக்கவும்",
|
||||
"Single Section Scroll": "ஒற்றைப் பகுதி உருட்டல்"
|
||||
"Single Section Scroll": "ஒற்றைப் பகுதி உருட்டல்",
|
||||
"General": "பொது",
|
||||
"Text to Speech": "உரையிலிருந்து பேச்சு",
|
||||
"Zoom": "பெரிதாக்கு",
|
||||
"Window": "சாளரம்"
|
||||
}
|
||||
|
||||
@@ -1126,5 +1126,9 @@
|
||||
"Scroll Half Page Down": "เลื่อนลงครึ่งหน้า",
|
||||
"Scroll Half Page Up": "เลื่อนขึ้นครึ่งหน้า",
|
||||
"Save Note": "บันทึกโน้ต",
|
||||
"Single Section Scroll": "เลื่อนทีละส่วน"
|
||||
"Single Section Scroll": "เลื่อนทีละส่วน",
|
||||
"General": "ทั่วไป",
|
||||
"Text to Speech": "อ่านออกเสียง",
|
||||
"Zoom": "ซูม",
|
||||
"Window": "หน้าต่าง"
|
||||
}
|
||||
|
||||
@@ -1139,5 +1139,9 @@
|
||||
"Scroll Half Page Down": "Yarım sayfa aşağı kaydır",
|
||||
"Scroll Half Page Up": "Yarım sayfa yukarı kaydır",
|
||||
"Save Note": "Notu kaydet",
|
||||
"Single Section Scroll": "Tek Bölüm Kaydırma"
|
||||
"Single Section Scroll": "Tek Bölüm Kaydırma",
|
||||
"General": "Genel",
|
||||
"Text to Speech": "Metinden konuşmaya",
|
||||
"Zoom": "Yakınlaştırma",
|
||||
"Window": "Pencere"
|
||||
}
|
||||
|
||||
@@ -1165,5 +1165,9 @@
|
||||
"Scroll Half Page Down": "Прокрутити на півсторінки вниз",
|
||||
"Scroll Half Page Up": "Прокрутити на півсторінки вгору",
|
||||
"Save Note": "Зберегти нотатку",
|
||||
"Single Section Scroll": "Прокрутка одного розділу"
|
||||
"Single Section Scroll": "Прокрутка одного розділу",
|
||||
"General": "Загальне",
|
||||
"Text to Speech": "Озвучення",
|
||||
"Zoom": "Масштаб",
|
||||
"Window": "Вікно"
|
||||
}
|
||||
|
||||
@@ -1126,5 +1126,9 @@
|
||||
"Scroll Half Page Down": "Cuộn xuống nửa trang",
|
||||
"Scroll Half Page Up": "Cuộn lên nửa trang",
|
||||
"Save Note": "Lưu ghi chú",
|
||||
"Single Section Scroll": "Cuộn từng phần"
|
||||
"Single Section Scroll": "Cuộn từng phần",
|
||||
"General": "Chung",
|
||||
"Text to Speech": "Chuyển văn bản thành giọng nói",
|
||||
"Zoom": "Thu phóng",
|
||||
"Window": "Cửa sổ"
|
||||
}
|
||||
|
||||
@@ -1126,5 +1126,9 @@
|
||||
"Scroll Half Page Down": "向下滚动半页",
|
||||
"Scroll Half Page Up": "向上滚动半页",
|
||||
"Save Note": "保存笔记",
|
||||
"Single Section Scroll": "单章节滚动"
|
||||
"Single Section Scroll": "单章节滚动",
|
||||
"General": "常规",
|
||||
"Text to Speech": "文字转语音",
|
||||
"Zoom": "缩放",
|
||||
"Window": "窗口"
|
||||
}
|
||||
|
||||
@@ -1126,5 +1126,9 @@
|
||||
"Scroll Half Page Down": "向下捲動半頁",
|
||||
"Scroll Half Page Up": "向上捲動半頁",
|
||||
"Save Note": "儲存筆記",
|
||||
"Single Section Scroll": "單章節捲動"
|
||||
"Single Section Scroll": "單章節捲動",
|
||||
"General": "一般",
|
||||
"Text to Speech": "文字轉語音",
|
||||
"Zoom": "縮放",
|
||||
"Window": "視窗"
|
||||
}
|
||||
|
||||
@@ -56,6 +56,41 @@ describe('TTS navigation shortcuts', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('No identical keybinding lists across actions (#3675)', () => {
|
||||
// Pre-existing pairs where two actions intentionally share the exact
|
||||
// same key list — both handlers guard on runtime context.
|
||||
// TODO: consider giving these distinct bindings to avoid the same
|
||||
// class of bug as #3675.
|
||||
const KNOWN_PAIRS: ReadonlySet<string> = new Set([
|
||||
'onSearchSelection,onShowSearchBar', // ctrl+f / cmd+f
|
||||
'onCloseWindow,onWikipediaSelection', // ctrl+w / cmd+w
|
||||
]);
|
||||
|
||||
it('should not have two actions with exactly the same key list', async () => {
|
||||
const shortcuts = await getDefaults();
|
||||
const keyListToActions = new Map<string, string[]>();
|
||||
for (const [name, entry] of Object.entries(shortcuts)) {
|
||||
const id = [...entry.keys].sort().join(',').toLowerCase();
|
||||
const actions = keyListToActions.get(id) ?? [];
|
||||
actions.push(name);
|
||||
keyListToActions.set(id, actions);
|
||||
}
|
||||
const duplicates: string[] = [];
|
||||
for (const [keys, actions] of keyListToActions) {
|
||||
if (actions.length > 1) {
|
||||
const pairId = [...actions].sort().join(',');
|
||||
if (!KNOWN_PAIRS.has(pairId)) {
|
||||
duplicates.push(`[${keys}] is shared by: ${actions.join(', ')}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
expect(
|
||||
duplicates,
|
||||
`Actions with identical keybinding lists:\n${duplicates.join('\n')}`,
|
||||
).toEqual([]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('getShortcutsForDisplay', () => {
|
||||
it('returns sections in the correct order', async () => {
|
||||
const mod = await getModule();
|
||||
|
||||
@@ -39,7 +39,7 @@ const DEFAULT_SHORTCUTS = {
|
||||
section: 'General',
|
||||
},
|
||||
onToggleBookmark: {
|
||||
keys: ['ctrl+d', 'cmd+d'],
|
||||
keys: ['ctrl+b', 'cmd+b'],
|
||||
description: _('Toggle Bookmark'),
|
||||
section: 'General',
|
||||
},
|
||||
@@ -270,12 +270,12 @@ export type ShortcutConfig = {
|
||||
};
|
||||
|
||||
export const SHORTCUT_SECTIONS = [
|
||||
'General',
|
||||
'Navigation',
|
||||
'Text to Speech',
|
||||
'Selection',
|
||||
'Zoom',
|
||||
'Window',
|
||||
_('General'),
|
||||
_('Navigation'),
|
||||
_('Text to Speech'),
|
||||
_('Selection'),
|
||||
_('Zoom'),
|
||||
_('Window'),
|
||||
] as const;
|
||||
|
||||
type ShortcutDisplayItem = {
|
||||
|
||||
Reference in New Issue
Block a user