feat: close all unpinned tabs in active workspace, p=#10739

* feat: close all unpinned tabs using keyboard shortcut

* feat: use toast instead of prompt

* feat: add toolbarbutton to close all unpinned tabs in a workspace

* feat: Fix bootstraping and other small nitpicks, b=no-bug, c=common, tabs, workspaces

* feat: improve the site popup ui, p=#10765

* style: improve site popup top buttons

* feat: add filled icons for permissions

* style: align and resize items in the site popup

* feat: site popup ui improvements and more permission icons

* chore: Better organize preferences files, b=no-bug, c=compact-mode, folders, glance, kbs, media, mods, split-view, welcome, workspaces

* feat: improve the site popup ui (part 2), p=#10768

* feat: Add a bounce to the glance element float and format, b=no-bug, c=common, glance

* chore: Update workflows to use macos 26 SDK, b=no-bug, c=workflows

* New Crowdin updates, p=#10769

* New translations zen-preferences.ftl (French)

* New translations zen-preferences.ftl (Lithuanian)

* New translations zen-workspaces.ftl (Lithuanian)

* New translations zen-general.ftl (Lithuanian)

* list shortcut in settings page, refactor code based on PR review

* feat: show restore tabs shortcut in toast message

* feat: Add toggle compact mode to the default placements, b=no-bug, c=common, glance

* chore: Only run autopep8 if python files changed, b=no-bug, c=workflows

* chore: Revert to the new folder animation, p=#10783, c=folders

* feat: Use close icon for pinned reset if the preference says so, p=#10786, c=no-component

* feat: Improve glance animation, p=#10790, c=glance

* update l10n string

* feat: Finished UI, b=no-bug, c=workspaces, common, tabs

* chore: Fix lint, b=no-bug, c=workspaces

---------

Co-authored-by: mr. m <mr.m@tuta.com>
Co-authored-by: reizumi <reizumichan@protonmail.com>
Co-authored-by: mr. m <91018726+mr-cheffy@users.noreply.github.com>
This commit is contained in:
Santhosh C
2025-10-28 20:18:36 +05:30
committed by GitHub
parent 8bce5c11ba
commit c21f927f01
14 changed files with 150 additions and 16 deletions

View File

@@ -337,3 +337,4 @@ zen-devtools-toggle-performance-shortcut = Toggle Performance
zen-devtools-toggle-storage-shortcut = Toggle Storage
zen-devtools-toggle-dom-shortcut = Toggle DOM
zen-devtools-toggle-accessibility-shortcut = Toggle Accessibility
zen-close-all-unpinned-tabs-shortcut = Close All Unpinned Tabs

View File

@@ -73,3 +73,10 @@ zen-workspace-creation-label = Spaces are used to organize your tabs and session
zen-workspaces-delete-workspace-title = Delete Space?
zen-workspaces-delete-workspace-body = Are you sure you want to delete { $name }? This action cannot be undone.
# Note that the html tag MUST not be changed or removed, as it is used to better
# display the shortcut in the toast notification.
zen-workspaces-close-all-unpinned-tabs-toast = Tabs Closed! Use <span>{ $shortcut }</span> to undo.
zen-workspaces-close-all-unpinned-tabs-title =
.label = Clear
.tooltiptext = Close all unpinned tabs

View File

@@ -60,4 +60,5 @@
<command id="cmd_zenOpenFolderCreation" />
<command id="cmd_zenTogglePinTab" />
<command id="cmd_zenCloseUnpinnedTabs" />
</commandset>

View File

@@ -6,7 +6,8 @@
.subviewbutton,
#zen-welcome-start-button,
.zen-toast button {
.zen-toast button,
.pinned-tabs-container-separator toolbarbutton {
-moz-context-properties: fill, fill-opacity !important;
fill: currentColor !important;
}
@@ -392,6 +393,10 @@
list-style-image: url('arrow-down.svg') !important;
}
.zen-workspace-close-unpinned-tabs-button {
list-style-image: url('dart-down.svg') !important;
}
.zen-workspace-actions-reorder-icon,
.zen-tab-rearrange-button {
list-style-image: url('drag-indicator.svg') !important;

View File

@@ -29,6 +29,7 @@
* skin/classic/browser/zen-icons/container-tab.svg (../shared/zen-icons/lin/container-tab.svg)
* skin/classic/browser/zen-icons/cookies-fill.svg (../shared/zen-icons/lin/cookies-fill.svg)
* skin/classic/browser/zen-icons/customize.svg (../shared/zen-icons/lin/customize.svg)
* skin/classic/browser/zen-icons/dart-down.svg (../shared/zen-icons/lin/dart-down.svg)
* skin/classic/browser/zen-icons/desktop-notification-blocked.svg (../shared/zen-icons/lin/desktop-notification-blocked.svg)
* skin/classic/browser/zen-icons/desktop-notification-fill.svg (../shared/zen-icons/lin/desktop-notification-fill.svg)
* skin/classic/browser/zen-icons/desktop-notification.svg (../shared/zen-icons/lin/desktop-notification.svg)
@@ -181,6 +182,7 @@
* skin/classic/browser/zen-icons/container-tab.svg (../shared/zen-icons/lin/container-tab.svg)
* skin/classic/browser/zen-icons/cookies-fill.svg (../shared/zen-icons/lin/cookies-fill.svg)
* skin/classic/browser/zen-icons/customize.svg (../shared/zen-icons/lin/customize.svg)
* skin/classic/browser/zen-icons/dart-down.svg (../shared/zen-icons/lin/dart-down.svg)
* skin/classic/browser/zen-icons/desktop-notification-blocked.svg (../shared/zen-icons/lin/desktop-notification-blocked.svg)
* skin/classic/browser/zen-icons/desktop-notification-fill.svg (../shared/zen-icons/lin/desktop-notification-fill.svg)
* skin/classic/browser/zen-icons/desktop-notification.svg (../shared/zen-icons/lin/desktop-notification.svg)
@@ -333,6 +335,7 @@
* skin/classic/browser/zen-icons/container-tab.svg (../shared/zen-icons/lin/container-tab.svg)
* skin/classic/browser/zen-icons/cookies-fill.svg (../shared/zen-icons/lin/cookies-fill.svg)
* skin/classic/browser/zen-icons/customize.svg (../shared/zen-icons/lin/customize.svg)
* skin/classic/browser/zen-icons/dart-down.svg (../shared/zen-icons/lin/dart-down.svg)
* skin/classic/browser/zen-icons/desktop-notification-blocked.svg (../shared/zen-icons/lin/desktop-notification-blocked.svg)
* skin/classic/browser/zen-icons/desktop-notification-fill.svg (../shared/zen-icons/lin/desktop-notification-fill.svg)
* skin/classic/browser/zen-icons/desktop-notification.svg (../shared/zen-icons/lin/desktop-notification.svg)

View File

@@ -0,0 +1,5 @@
#filter dumbComments emptyLines substitution
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
<svg xmlns="http://www.w3.org/2000/svg" height="12" width="12" viewBox="0 0 12 12"><g stroke-linecap="round" stroke-width="1.5" fill="none" stroke="context-fill" stroke-opacity="context-fill-opacity" stroke-linejoin="round" class="nc-icon-wrapper"><line x1="6" y1="1" x2="6" y2="10.75" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" data-color="color-2"/><polyline points="2.75 7.75 6 11 9.25 7.75" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5"/></g></svg>

View File

@@ -147,7 +147,7 @@
visibility 0.15s;
}
#navigator-toolbox:hover &,
#navigator-toolbox[zen-has-hover='true'] &,
&[open],
#urlbar[has-popup-open='true'] &,
#identity-box[pageproxystate='invalid'] & {

View File

@@ -381,6 +381,16 @@ menuseparator {
& label {
margin: 0 4px;
& span {
background: light-dark(rgba(255, 255, 255, 0.4), rgba(255, 255, 255, 0.1));
border-radius: 4px;
padding: 5px 7px;
font-size: 12px;
font-weight: 600;
margin: 0 2px;
word-spacing: 2px;
}
}
& button {

View File

@@ -122,6 +122,9 @@ document.addEventListener(
}
break;
}
case 'cmd_zenCloseUnpinnedTabs':
gZenWorkspaces.closeAllUnpinnedTabs();
break;
case 'cmd_zenUnloadWorkspace': {
gZenWorkspaces.unloadWorkspace();
break;

View File

@@ -49,6 +49,7 @@ const defaultKeyboardGroups = {
'zen-key-enter-full-screen',
'zen-key-exit-full-screen',
'zen-quit-app-shortcut',
'zen-close-all-unpinned-tabs-shortcut',
'zen-close-tab-shortcut',
'zen-close-shortcut',
'id:key_selectTab1',
@@ -799,7 +800,7 @@ class nsZenKeyboardShortcutsLoader {
}
class nsZenKeyboardShortcutsVersioner {
static LATEST_KBS_VERSION = 12;
static LATEST_KBS_VERSION = 13;
constructor() {}
@@ -1081,6 +1082,20 @@ class nsZenKeyboardShortcutsVersioner {
data = data.filter((shortcut) => shortcut.getID() != 'zen-compact-mode-show-toolbar');
}
if (version < 13) {
data.push(
new KeyShortcut(
'zen-close-all-unpinned-tabs',
'K',
'',
ZEN_WORKSPACE_SHORTCUTS_GROUP,
nsKeyShortcutModifiers.fromObject({ accel: true, shift: true }),
'cmd_zenCloseUnpinnedTabs',
'zen-close-all-unpinned-tabs-shortcut'
)
);
}
return data;
}
}

View File

@@ -130,31 +130,76 @@
Pinned Tabs Separator
========================================================================== */
.pinned-tabs-container-separator {
background: light-dark(rgba(0, 0, 0, 0.1), rgba(255, 255, 255, 0.1));
margin: 8px auto;
height: 24px;
border: none;
height: 1px;
max-height: 1px;
width: 98%;
transition:
margin 0.1s ease-in-out,
background 0.1s ease-in-out,
max-height 0.1s ease-in-out;
height 0.08s ease-in-out,
opacity 0.08s ease-in-out;
overflow: hidden;
position: relative;
opacity: 1;
align-items: center;
& toolbarseparator {
height: 1px;
background: light-dark(rgba(0, 0, 0, 0.1), rgba(255, 255, 255, 0.1));
padding: 0;
margin: auto 4px;
&::before {
border-inline-start: none;
}
}
#tabbrowser-tabs[movingtab] & {
transition:
margin 0.1s ease-in-out,
background 0.1s ease-in-out,
max-height 0.1s ease-in-out,
height 0.08s ease-in-out,
opacity 0.08s ease-in-out,
transform 0.1s ease-in-out;
}
.zen-workspace-pinned-tabs-section[hide-separator] & {
max-height: 0;
margin: 0 auto;
height: 0px;
opacity: 0;
}
& toolbarbutton {
appearance: none;
opacity: 0;
visibility: collapse;
transition:
opacity 0.15s,
visibility 0.15s;
font-size: 10px;
font-weight: 500;
gap: 2px;
#navigator-toolbox[zen-has-hover='true'] & {
visibility: visible;
opacity: 0.5;
}
&:hover {
opacity: 1 !important;
}
:root:not([zen-sidebar-expanded='true']) & {
display: none;
}
& .toolbarbutton-text {
display: flex;
}
& .toolbarbutton-icon {
width: 10px;
transition: transform 0.15s ease-in-out;
}
&:active:hover .toolbarbutton-icon {
transform: translateY(2px);
}
}
}

View File

@@ -12,7 +12,13 @@
</vbox>
<arrowscrollbox orient="vertical" class="workspace-arrowscrollbox">
<vbox class="zen-workspace-tabs-section zen-workspace-pinned-tabs-section" hide-separator="true">
<html:div class="pinned-tabs-container-separator"></html:div>
<hbox class="pinned-tabs-container-separator">
<toolbarseparator flex="1" />
<toolbarbutton command="cmd_zenCloseUnpinnedTabs"
tooltip="dynamic-shortcut-tooltip"
data-l10n-id="zen-workspaces-close-all-unpinned-tabs-title"
class="zen-workspace-close-unpinned-tabs-button" />
</hbox>
</vbox>
<vbox class="zen-workspace-tabs-section zen-workspace-normal-tabs-section">
<!-- Let it as an ID to mantain compatibility with firefox's tabbrowser -->

View File

@@ -1483,6 +1483,19 @@ var gZenWorkspaces = new (class extends nsZenMultiWindowFeature {
});
}
unpinnedTabsInWorkspace(workspaceID) {
return Array.from(this.allStoredTabs).filter(
(tab) => tab.getAttribute('zen-workspace-id') === workspaceID && tab.visible && !tab.pinned
);
}
#deleteAllUnpinnedTabsInWorkspace(tabs) {
gBrowser.removeTabs(tabs, {
animate: false,
closeWindowWithLastTab: false,
});
}
async unloadWorkspace() {
const workspaceId = this.#contextMenuData?.workspaceId || this.activeWorkspace;
@@ -2654,6 +2667,25 @@ var gZenWorkspaces = new (class extends nsZenMultiWindowFeature {
this.tabContainer._invalidateCachedTabs();
}
async closeAllUnpinnedTabs() {
const workspaceId = this.#contextMenuData?.workspaceId || this.activeWorkspace;
const unpinnedTabs = await this.unpinnedTabsInWorkspace(workspaceId);
if (!unpinnedTabs.length) return;
this.#deleteAllUnpinnedTabsInWorkspace(unpinnedTabs);
const restoreClosedTabsShortcut = gZenKeyboardShortcutsManager.getShortcutDisplayFromCommand(
'History:RestoreLastClosedTabOrWindowOrSession'
);
gZenUIManager.showToast('zen-workspaces-close-all-unpinned-tabs-toast', {
l10nArgs: {
shortcut: restoreClosedTabsShortcut,
},
});
}
async contextDeleteWorkspace() {
const workspaceId = this.#contextMenuData?.workspaceId || this.activeWorkspace;
const [title, body] = await document.l10n.formatValues([

View File

@@ -22,6 +22,7 @@ export default [
'gZenStartup',
'gZenWorkspaces',
'gZenKeyboardShortcutsManager',
'ZenWorkspacesEngine',
'ZenWorkspacesStorage',
'ZenWorkspaceBookmarksStorage',