-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
feat: improve tab navigation and cycling #9441
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: dev
Are you sure you want to change the base?
Changes from all commits
4903575
b1253bf
c6769bf
42fd45d
f0c69b7
2e7ef05
b030f01
ae63f9d
1ebd642
f582029
4550322
9bc7609
f6f6b56
cf89eba
4462483
8237ee6
9d4d9e3
3183624
0b0ef8f
f1bb8f8
47e3779
6f608db
ed3f1ff
da26a8a
ed9ecc4
a75400a
5756c86
dc4547b
2c2344f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -230,10 +230,10 @@ class nsKeyShortcutModifiers { | |
| this.#control == other.#control && | ||
| (AppConstants.platform == 'macosx' | ||
| ? (this.#meta || this.#accel) == (other.#meta || other.#accel) && | ||
| this.#control == other.#control | ||
| this.#control == other.#control | ||
| : // In other platforms, we can have control and accel counting as the same thing | ||
| this.#meta == other.#meta && | ||
| (this.#control || this.#accel) == (other.#control || other.#accel)) | ||
| this.#meta == other.#meta && | ||
| (this.#control || this.#accel) == (other.#control || other.#accel)) | ||
| ); | ||
| } | ||
|
|
||
|
|
@@ -303,6 +303,7 @@ class KeyShortcut { | |
| #disabled = false; | ||
| #reserved = false; | ||
| #internal = false; | ||
| #isPrecedent = false; | ||
|
|
||
| constructor( | ||
| id, | ||
|
|
@@ -314,7 +315,8 @@ class KeyShortcut { | |
| l10nId, | ||
| disabled = false, | ||
| reserved = false, | ||
| internal = false | ||
| internal = false, | ||
| isPrecedent = false | ||
| ) { | ||
| this.#id = id; | ||
| this.#key = key?.toLowerCase(); | ||
|
|
@@ -331,6 +333,7 @@ class KeyShortcut { | |
| this.#disabled = disabled; | ||
| this.#reserved = reserved; | ||
| this.#internal = internal; | ||
| this.#isPrecedent = isPrecedent; | ||
| } | ||
|
|
||
| isEmpty() { | ||
|
|
@@ -369,7 +372,8 @@ class KeyShortcut { | |
| json['l10nId'], | ||
| json['disabled'], | ||
| json['reserved'], | ||
| json['internal'] | ||
| json['internal'], | ||
| json['isPrecedent'] | ||
| ); | ||
| } | ||
|
|
||
|
|
@@ -379,16 +383,17 @@ class KeyShortcut { | |
| key.getAttribute('key'), | ||
| key.getAttribute('keycode'), | ||
| group ?? | ||
| KeyShortcut.getGroupFromL10nId( | ||
| KeyShortcut.sanitizeL10nId(key.getAttribute('data-l10n-id')), | ||
| key.getAttribute('id') | ||
| ), | ||
| KeyShortcut.getGroupFromL10nId( | ||
| KeyShortcut.sanitizeL10nId(key.getAttribute('data-l10n-id')), | ||
| key.getAttribute('id') | ||
| ), | ||
| nsKeyShortcutModifiers.parseFromXHTMLAttribute(key.getAttribute('modifiers')), | ||
| key.getAttribute('command'), | ||
| key.getAttribute('data-l10n-id'), | ||
| key.getAttribute('disabled') == 'true', | ||
| key.getAttribute('reserved') == 'true', | ||
| key.getAttribute('internal') == 'true' | ||
| key.getAttribute('internal') == 'true', | ||
| key.getAttribute('isPrecedent') == 'true' | ||
| ); | ||
| } | ||
|
|
||
|
|
@@ -447,6 +452,9 @@ class KeyShortcut { | |
| if (this.#internal) { | ||
| key.setAttribute('internal', this.#internal); | ||
| } | ||
| if (this.#isPrecedent) { | ||
| key.setAttribute('isPrecedent', this.#isPrecedent); | ||
| } | ||
| key.setAttribute('zen-keybind', 'true'); | ||
|
|
||
| return key; | ||
|
|
@@ -512,6 +520,10 @@ class KeyShortcut { | |
| return this.#internal; | ||
| } | ||
|
|
||
| isPrecedent() { | ||
| return this.#isPrecedent; | ||
| } | ||
|
|
||
| isInvalid() { | ||
| return this.#key == '' && this.#keycode == '' && this.#l10nId == null; | ||
| } | ||
|
|
@@ -535,6 +547,7 @@ class KeyShortcut { | |
| disabled: this.#disabled, | ||
| reserved: this.#reserved, | ||
| internal: this.#internal, | ||
| isPrecedent: this.#isPrecedent, | ||
| }; | ||
| } | ||
|
|
||
|
|
@@ -1023,8 +1036,55 @@ class nsZenKeyboardShortcutsVersioner { | |
| } | ||
| } | ||
| if (version < 10) { | ||
| // Migrate from version 9 to 10 | ||
| // 1) Add the new pin/unpin tab toggle shortcut with Ctrl+Shift+D | ||
| // 1) Migrate from version 9 to 10 | ||
| // In this new version, we add customizable shortcuts for switching to the next/previous tab and toggling unloaded tab cycling. | ||
| data.push( | ||
| new KeyShortcut( | ||
| 'zen-tab-next-shortcut', | ||
| 'TAB', | ||
| 'VK_TAB', | ||
| 'windowAndTabManagement', | ||
| nsKeyShortcutModifiers.fromObject({ accel: true }), | ||
| 'cmd_zenTabNext', | ||
| 'zen-tab-next-shortcut', | ||
| false, // disabled | ||
| false, // reserved | ||
| false, // internal | ||
| true // isPrecedent | ||
| ) | ||
| ); | ||
| data.push( | ||
| new KeyShortcut( | ||
| 'zen-tab-prev-shortcut', | ||
| 'TAB', | ||
| 'VK_TAB', | ||
| 'windowAndTabManagement', | ||
| nsKeyShortcutModifiers.fromObject({ accel: true, shift: true }), | ||
| 'cmd_zenTabPrev', | ||
| 'zen-tab-prev-shortcut', | ||
| false, // disabled | ||
| false, // reserved | ||
| false, // internal | ||
| true // isPrecedent | ||
| ) | ||
| ); | ||
| data.push( | ||
| new KeyShortcut( | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Instead of a shortcut I would just have it as a global preference it can be toggled, removing |
||
| 'zen-toggle-unloaded-cycling-shortcut', | ||
| '', | ||
| '', | ||
| 'windowAndTabManagement', | ||
| nsKeyShortcutModifiers.fromObject({}), | ||
| 'cmd_zenToggleUnloadedCycling', | ||
| 'zen-toggle-unloaded-cycling-shortcut', | ||
| false, // disabled | ||
| false, // reserved | ||
| false, // internal | ||
| true // isPrecedent | ||
| ) | ||
| ); | ||
|
|
||
| // 2) Add the new pin/unpin tab toggle shortcut with Ctrl+Shift+D | ||
| data.push( | ||
| new KeyShortcut( | ||
| 'zen-toggle-pin-tab', | ||
|
|
@@ -1037,7 +1097,7 @@ class nsZenKeyboardShortcutsVersioner { | |
| ) | ||
| ); | ||
|
|
||
| // 2) Add shortcut to expand Glance into a full tab: Default Accel+O | ||
| // 3) Add shortcut to expand Glance into a full tab: Default Accel+O | ||
| data.push( | ||
| new KeyShortcut( | ||
| 'zen-glance-expand', | ||
|
|
@@ -1126,10 +1186,8 @@ var gZenKeyboardShortcutsManager = { | |
| async init() { | ||
| if (this.inBrowserView) { | ||
| const loadedShortcuts = await this._loadSaved(); | ||
|
|
||
| this._currentShortcutList = this.versioner.fixedKeyboardShortcuts(loadedShortcuts); | ||
| this._currentShortcutList = this.versioner.fixedKeyboardShortcuts(loadedShortcuts) || []; | ||
| this._applyShortcuts(); | ||
|
|
||
| await this._saveShortcuts(); | ||
| } | ||
| }, | ||
|
|
@@ -1234,6 +1292,46 @@ var gZenKeyboardShortcutsManager = { | |
| this.triggerShortcutRebuild(); | ||
| }, | ||
|
|
||
| _registerPrecedentShortcut(shortcut, browser) { | ||
nikvnt marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| const listener = (event) => { | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. A new event is being made on every key added, I would add a single event handler and check on a list of known precedent shortcuts |
||
| let keyMatch = false; | ||
| if (shortcut.getKeyName()) { | ||
| keyMatch = event.key.toLowerCase() === shortcut.getKeyName().toLowerCase(); | ||
| } else if (shortcut.getKeyCode()) { | ||
| for (const [mapKey, mapValue] of Object.entries(KEYCODE_MAP)) { | ||
| if (mapValue === shortcut.getKeyCode()) { | ||
| if (mapKey.toLowerCase() === event.code.toLowerCase()) { | ||
| keyMatch = true; | ||
| } | ||
| break; | ||
| } | ||
| } | ||
| } | ||
|
|
||
| if (!keyMatch) { | ||
| return; | ||
| } | ||
|
|
||
| const modifiers = shortcut.getModifiers(); | ||
| const accelPressed = AppConstants.platform === 'macosx' ? event.metaKey : event.ctrlKey; | ||
| const modifiersMatch = | ||
| modifiers.accel === accelPressed && | ||
| modifiers.alt === event.altKey && | ||
| modifiers.shift === event.shiftKey; | ||
|
|
||
| if (modifiersMatch) { | ||
| event.preventDefault(); | ||
| event.stopImmediatePropagation(); | ||
| const command = browser.document.getElementById(shortcut.getAction()); | ||
| if (command) { | ||
| command.doCommand(); | ||
| } | ||
| } | ||
| }; | ||
|
|
||
| browser.addEventListener('keydown', listener, true); | ||
| }, | ||
|
|
||
| _applyShortcuts() { | ||
| for (const browser of nsZenMultiWindowFeature.browsers) { | ||
| let mainKeyset = browser.document.getElementById(ZEN_MAIN_KEYSET_ID); | ||
|
|
@@ -1254,8 +1352,13 @@ var gZenKeyboardShortcutsManager = { | |
| if (key.isInternal()) { | ||
| continue; | ||
| } | ||
| let child = key.toXHTMLElement(browser); | ||
| keyset.appendChild(child); | ||
|
|
||
| if (key.isPrecedent()) { | ||
| this._registerPrecedentShortcut(key, browser); | ||
| } else { | ||
| let child = key.toXHTMLElement(browser); | ||
| keyset.appendChild(child); | ||
| } | ||
| } | ||
|
|
||
| this._applyDevtoolsShortcuts(browser); | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.