Skip to content
Open
Show file tree
Hide file tree
Changes from 12 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
4903575
feat: add new shortcuts
nikvnt Jul 9, 2025
b1253bf
patch: remove mozilla's ctrl+tab navigation
nikvnt Jul 9, 2025
c6769bf
feat: add menu & radio options & shortcuts logic
nikvnt Jul 9, 2025
42fd45d
change: trail some trash code and add more modifier options
nikvnt Jul 13, 2025
f0c69b7
Merge remote-tracking branch 'upstream/dev' into dev
nikvnt Jul 13, 2025
2e7ef05
change: leaving inputs for navigation unset + setting a default input…
nikvnt Jul 13, 2025
b030f01
change: move functionalities from workspaces to commonUtils & remove …
nikvnt Jul 22, 2025
ae63f9d
Merge remote-tracking branch upstream/dev into dev
nikvnt Jul 22, 2025
1ebd642
Merge remote-tracking branch 'upstream/dev' into dev
nikvnt Aug 14, 2025
f582029
test: add tests for unloaded navigation pref
nikvnt Sep 9, 2025
4550322
feat: use firefox's native tab navigation + other adjusts for PR
nikvnt Sep 9, 2025
9bc7609
chore(dev): sync with upstream repo
nikvnt Sep 9, 2025
f6f6b56
feat: make it so that unloaded cycling shortcut is unset by default
nikvnt Sep 10, 2025
cf89eba
feat: make tab navigation shortcuts take precedence over sites
nikvnt Sep 11, 2025
4462483
Merge branch 'dev' into dev
mr-cheffy Sep 13, 2025
8237ee6
chore: Updated to dev, b=no-bug, c=common, kbs, tests, tabs, workspaces
mr-cheffy Sep 13, 2025
9d4d9e3
chore: change key names so that they match l10n translations
nikvnt Sep 16, 2025
3183624
Merge remote-tracking branch 'refs/remotes/origin/dev' into dev
nikvnt Sep 16, 2025
0b0ef8f
chore: improve identation
nikvnt Sep 17, 2025
f1bb8f8
feat: make it so that cycling tabs wrap around + add a test case for …
nikvnt Sep 17, 2025
47e3779
fix: remove _precedentListeners array
nikvnt Sep 17, 2025
6f608db
feat: make it so that every key has isPrecedent as an attribute + set…
nikvnt Sep 18, 2025
ed3f1ff
Merge branch 'dev' into dev
mr-cheffy Sep 18, 2025
da26a8a
Merge branch 'dev' into dev
nikvnt Sep 19, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion src/browser/base/content/zen-commands.inc.xhtml
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,13 @@
<command id="cmd_zenCopyCurrentURL" />
<command id="cmd_zenCopyCurrentURLMarkdown" />

<command id="cmd_zenTabNext" />
<command id="cmd_zenTabPrev" />
<command id="cmd_zenToggleUnloadedCycling" />

<command id="cmd_zenGlanceClose" />
<command id="cmd_zenGlanceExpand" />
<command id="cmd_zenGlanceSplit" />

<command id="cmd_zenOpenFolderCreation" />
</commandset>
</commandset>
9 changes: 9 additions & 0 deletions src/browser/components/preferences/zen-settings.js
Original file line number Diff line number Diff line change
Expand Up @@ -776,6 +776,10 @@ var zenMissingKeyboardShortcutL10n = {
key_wrToggleCaptureSequenceCmd: 'zen-key-wr-toggle-capture-sequence-cmd',
key_undoCloseWindow: 'zen-key-undo-close-window',

key_zenTabNext: 'zen-key-tab-next-shortcut',
key_zenTabPrevious: 'zen-key-tab-prev-shortcut',
key_toggleUnloadedCycling: 'zen-toggle-unloaded-cycling-shortcut',

key_selectTab1: 'zen-key-select-tab-1',
key_selectTab2: 'zen-key-select-tab-2',
key_selectTab3: 'zen-key-select-tab-3',
Expand Down Expand Up @@ -1169,4 +1173,9 @@ Preferences.addAll([
type: 'bool',
default: true,
},
{
id: 'zen.tabs.unloaded-navigation-mode',
type: 'string',
default: 'always',
},
]);
29 changes: 28 additions & 1 deletion src/browser/components/preferences/zenTabsManagement.inc.xhtml
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,33 @@
</hbox>
</groupbox>

</html:template>
<hbox id="zenTabsUnloadCategory" class="subcategory" hidden="true" data-category="paneZenTabManagement">
<html:h1 data-l10n-id="pane-zen-tabs-unloader-title" />
</hbox>

<hbox id="zenPinnedTabsManagerCategory" class="subcategory" hidden="true" data-category="paneZenTabManagement">
<html:h1 data-l10n-id="pane-zen-tab-navigation-title" />
</hbox>

<groupbox id="zenTabsUnloadedNavigationGroup" data-category="paneZenTabManagement" hidden="true"
class="highlighting-group">
<label>
<html:h2 data-l10n-id="zen-tabs-unloaded-navigation-mode-label" />
</label>
<description class="description-deemphasized"
data-l10n-id="zen-tabs-unloaded-navigation-mode-description" />

<radiogroup id="zenTabsUnloadedNavigationMode" preference="zen.tabs.unloaded-navigation-mode"
oncommand="onZenTabsUnloadedNavigationModeChanged(this.value);">
<hbox align="center">
<radio id="zenTabsUnloadedNavigationModeAlways" value="always" />
<description data-l10n-id="zen-tabs-unloaded-navigation-mode-always" />
</hbox>
<hbox align="center">
<radio id="zenTabsUnloadedNavigationModeNever" value="never" />
<description data-l10n-id="zen-tabs-unloaded-navigation-mode-never" />
</hbox>
</radiogroup>
</groupbox>

</html:template>
48 changes: 43 additions & 5 deletions src/toolkit/content/widgets/tabbox-js.patch
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,15 @@ diff --git a/toolkit/content/widgets/tabbox.js b/toolkit/content/widgets/tabbox.
index 70afbfc87d543971e6f8a0661a44b682920a7bc4..2f767296db8043318fab2aeb39bfc5eee090b258 100644
--- a/toolkit/content/widgets/tabbox.js
+++ b/toolkit/content/widgets/tabbox.js
@@ -213,7 +213,7 @@
@@ -125,6 +125,7 @@

const { ShortcutUtils } = imports;

+ return;
switch (ShortcutUtils.getSystemActionForEvent(event)) {
case ShortcutUtils.CYCLE_TABS:
Glean.browserUiInteraction.keyboard["ctrl-tab"].add(1);
@@ -213,7 +214,7 @@
) {
this._inAsyncOperation = false;
if (oldPanel != this._selectedPanel) {
Expand All @@ -11,7 +19,7 @@ index 70afbfc87d543971e6f8a0661a44b682920a7bc4..2f767296db8043318fab2aeb39bfc5ee
this._selectedPanel?.classList.add("deck-selected");
}
this.setAttribute("selectedIndex", val);
@@ -610,7 +610,7 @@
@@ -610,7 +611,7 @@
if (!tab) {
return;
}
Expand All @@ -20,7 +28,7 @@ index 70afbfc87d543971e6f8a0661a44b682920a7bc4..2f767296db8043318fab2aeb39bfc5ee
if (otherTab != tab && otherTab.selected) {
otherTab._selected = false;
}
@@ -823,7 +823,7 @@
@@ -823,7 +824,7 @@
if (tab == startTab) {
return null;
}
Expand All @@ -29,12 +37,42 @@ index 70afbfc87d543971e6f8a0661a44b682920a7bc4..2f767296db8043318fab2aeb39bfc5ee
return tab;
}
}
@@ -888,7 +888,7 @@
@@ -885,10 +886,18 @@
* @param {boolean} [aWrap]
*/
advanceSelectedTab(aDir, aWrap) {
+
+ const basePref = Services.prefs.getStringPref('zen.tabs.unloaded-navigation-mode', 'never');
+ const invertedState = Services.prefs.getBoolPref('zen.tabs.unloaded-navigation-mode.inverted', false);
+ const includeUnloaded = (basePref === 'always' && !invertedState) || (basePref === 'never' && invertedState);
+ const tabFilter = includeUnloaded
+ ? (tab => tab.visible)
+ : (tab => tab.visible && !tab.hasAttribute('pending'));
+
let { ariaFocusedItem } = this;
let startTab = ariaFocusedItem;
if (!ariaFocusedItem || !this.allTabs.includes(ariaFocusedItem)) {
- startTab = this.selectedItem;
+ startTab = gZenGlanceManager.getFocusedTab(aDir) || this.selectedItem;
}
let newTab = null;


@@ -896,15 +905,15 @@
// which has a random placement in this.allTabs.
if (startTab.hidden) {
if (aDir == 1) {
- newTab = this.allTabs.find(tab => tab.visible);
+ newTab = this.allTabs.find(tabFilter);
} else {
- newTab = this.allTabs.findLast(tab => tab.visible);
+ newTab = this.allTabs.findLast(tabFilter);
}
} else {
newTab = this.findNextTab(startTab, {
direction: aDir,
wrap: aWrap,
- filter: tab => tab.visible,
+ filter: tabFilter,
});
}

19 changes: 18 additions & 1 deletion src/zen/common/ZenCommonUtils.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ window.gZenOperatingSystemCommonUtils = {

/* eslint-disable no-unused-vars */
class nsZenMultiWindowFeature {
constructor() {}
constructor() { }

static get browsers() {
return Services.wm.getEnumerator('navigator:browser');
Expand Down Expand Up @@ -121,6 +121,23 @@ var gZenCommonActions = {
}
},

nextTab() {
gBrowser.tabContainer.advanceSelectedTab(1, false);
},
previousTab() {
gBrowser.tabContainer.advanceSelectedTab(-1, false);
},

toggleUnloadedCycling() {
try {
const currentMode = Services.prefs.getStringPref('zen.tabs.unloaded-navigation-mode', 'always');
const nextMode = currentMode === 'always' ? 'never' : 'always';
Services.prefs.setStringPref('zen.tabs.unloaded-navigation-mode', nextMode);
} catch (e) {
console.error('[gZenCommonActions] Error on unloaded cycling:', e);
}
},

throttle(f, delay) {
let timer = 0;
return function (...args) {
Expand Down
9 changes: 9 additions & 0 deletions src/zen/common/zen-sets.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,15 @@ document.addEventListener(
case 'cmd_zenSplitViewUnsplit':
gZenViewSplitter.toggleShortcut('unsplit');
break;
case 'cmd_zenTabNext':
gZenCommonActions.nextTab();
break;
case 'cmd_zenTabPrev':
gZenCommonActions.previousTab();
break;
case 'cmd_zenToggleUnloadedCycling':
gZenCommonActions.toggleUnloadedCycling();
break;
case 'cmd_zenSplitViewContextMenu':
gZenViewSplitter.contextSplitTabs();
break;
Expand Down
43 changes: 39 additions & 4 deletions src/zen/kbs/ZenKeyboardShortcuts.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -993,6 +993,43 @@ class nsZenKeyboardShortcutsVersioner {
}
}
}
if (version < 10) {
// 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'
)
);
data.push(
new KeyShortcut(
'zen-tab-prev-shortcut',
'TAB',
'VK_TAB',
'windowAndTabManagement',
nsKeyShortcutModifiers.fromObject({ accel: true, shift: true }),
'cmd_zenTabPrev',
'zen-tab-prev-shortcut'
)
);
data.push(
new KeyShortcut(
'zen-toggle-unloaded-cycling-shortcut',
'U',
'',
'windowAndTabManagement',
nsKeyShortcutModifiers.fromObject({ alt: true }),
'cmd_zenToggleUnloadedCycling',
'zen-toggle-unloaded-cycling-shortcut'
)
);
}
return data;
}
}
Expand Down Expand Up @@ -1023,10 +1060,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();
}
},
Expand Down Expand Up @@ -1271,4 +1306,4 @@ document.addEventListener(
}
},
{ once: true }
);
);
3 changes: 2 additions & 1 deletion src/zen/tests/tabs/browser.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,10 @@ support-files = [
"head.js",
]

["browser_tab_unloaded_navigation.js"]
["browser_tabs_empty_checks.js"]
["browser_drag_drop_vertical.js"]
tags = [
"drag-drop",
"vertical-tabs"
]
]
Loading