Compare commits

..

24 Commits

Author SHA1 Message Date
mr. m
a8e245b28a feat: Listen for tabHide and tabShow events for window sync, b=bug #12408, c=no-component 2026-02-19 00:50:11 +01:00
mr. m
a30ddc98bd feat: Correctly calculate certain popup opening coordinates, b=no-bug, c=folders, workspaces 2026-02-19 00:38:21 +01:00
mr. m
6273313ce3 fix: Fixed startup freeze when a group was not found, b=closes #12420, c=no-component 2026-02-18 19:18:12 +01:00
mr. m
dd26ec1171 fix: Fixed tabs becoming empty tabs when switching between windows, b=bug #12421, c=no-component 2026-02-18 12:52:26 +01:00
mr. m
1d2a14f9e4 feat: Correctly calculate size of folder search popup, b=no-bug, c=flatpak, folders, workspaces 2026-02-17 22:40:00 +01:00
mr. m
5be2ffa418 fix: Fixed not being able to unload tabs that are in another workspace, b=closes #9683, c=no-component 2026-02-17 17:20:28 +01:00
mr. m
a30798a275 feat: Rework panel animations and updated Firefox 147.0.4, b=no-bug, c=split-view, folders, common, compact-mode, kbs, workspaces 2026-02-17 13:01:38 +01:00
mr. m
214fd4aff0 feat: Include X-AppImage-Version into the AppImage .desktop file, b=closes #12412, c=workflows 2026-02-17 12:13:41 +01:00
mr. m
ddd7f165bf feat: Lower the timing of panel animations, b=no-bug, c=common 2026-02-16 16:25:01 +01:00
Abdush salam
ae5f9060d4 fix: Remove duplicate fullscreen shortcuts from settings, b=closes #12237. p=#12395, c=kbs 2026-02-16 14:17:06 +01:00
mr. m
362764f497 Merge branch 'dev' of https://github.com/zen-browser/desktop into dev 2026-02-16 14:03:27 +01:00
mr. m
083f388176 chore: Remove x-checker-data for flatpak releases, b=no-bug, c=flatpak 2026-02-16 14:03:23 +01:00
Ivaon
813fc16986 fix: properly collapse folder when unloading all tabs, p=#12399
* fix: properly collapse folder when unloading all tabs

* chore: fix implementation in wrong function
2026-02-16 11:29:57 +01:00
mr. m
86a9c17acd feat: Make sure to always clear dragging-out flag on each new drag event, b=no-bug, c=tabs 2026-02-16 00:11:36 +01:00
mr. m
3d0bdbc71b chore: Fixed linting and formatting, b=no-bug, c=common 2026-02-15 23:54:22 +01:00
mr. m
119bedce30 feat: Don't trim the URL if the omnibox has been opened, b=no-bug, c=common 2026-02-15 22:41:00 +01:00
mr. m
1493c6be21 Merge branch 'dev' of https://github.com/zen-browser/desktop into dev 2026-02-15 22:32:19 +01:00
mr. m
4d4d6970e3 fix: Fixed DnD indicator not showing when there are no pinned tabs, b=no-bug, c=common, tabs 2026-02-15 22:31:59 +01:00
TogiFerretFerret
3914d33968 chore: fix issue where transparent browsers have a forced-white sync, p=#12392
* chore: fix issue where transparent browsers have a forced-white sync background without breaking non-transparent browsers

* chore: fix linting issue
2026-02-15 19:44:38 +01:00
mr. m
c4f98b0cd8 fix: Fixed back/frwd buttons switching tab's state instead of space, b=closes #9157, c=workspaces 2026-02-15 14:12:02 +01:00
mr. m
6e728d0e2f feat: Remove unnecesary browser flush calls, b=bug #12152, c=no-component 2026-02-15 13:59:08 +01:00
mr. m
3bd1101f7b fix: Fixed moving tabs to different spaces in separate windows, b=closes #12235, c=tabs 2026-02-15 13:50:51 +01:00
mr. m
c55126085b chore: Fix merge conflicts, b=no-bug, c=no-component 2026-02-15 13:38:00 +01:00
mr. m
9a6db5fb86 fix: Fixed migration data not working if there where any errors, b=no-bug, c=no-component 2026-02-15 13:36:37 +01:00
30 changed files with 241 additions and 169 deletions

View File

@@ -368,7 +368,7 @@ jobs:
strategy:
matrix:
arch: [x86_64, aarch64]
needs: [linux]
needs: [linux, build-data]
steps:
- name: Checkout repository
uses: actions/checkout@v4
@@ -406,6 +406,8 @@ jobs:
sed -i -e 's/StartupWMClass=zen/StartupWMClass=zen-twilight/g' build/AppDir/zen.desktop
fi
sed -i -e 's/\$VERSION/${{ needs.build-data.outputs.version }}/g' build/AppDir/zen.desktop
APPDIR=build/AppDir
tar -xvf *.tar.* && rm -rf *.tar.*
mv zen/* $APPDIR/

View File

@@ -34,8 +34,8 @@ Zen is a firefox-based browser with the aim of pushing your productivity to a ne
### Firefox Versions
- [`Release`](https://zen-browser.app/download) - Is currently built using Firefox version `147.0.3`! 🚀
- [`Twilight`](https://zen-browser.app/download?twilight) - Is currently built using Firefox version `RC 147.0.3`!
- [`Release`](https://zen-browser.app/download) - Is currently built using Firefox version `147.0.4`! 🚀
- [`Twilight`](https://zen-browser.app/download?twilight) - Is currently built using Firefox version `RC 147.0.4`!
### Contributing

View File

@@ -12,6 +12,7 @@ Terminal=false
X-MultipleArgs=false
Keywords=Internet;WWW;Browser;Web;Explorer;
Actions=new-window;new-private-window;profilemanager;
X-AppImage-Version=$VERSION
[Desktop Action new-window]
Name=Open a New Window

View File

@@ -25,6 +25,7 @@ finish-args:
- --filesystem=xdg-run/speech-dispatcher:ro
- --device=all
- --talk-name=org.freedesktop.FileManager1
- --talk-name=org.freedesktop.Notifications
- --system-talk-name=org.freedesktop.NetworkManager
- --talk-name=org.a11y.Bus
- --talk-name=org.gtk.vfs.*
@@ -62,12 +63,6 @@ modules:
strip-components: 0
only-arches:
- x86_64
x-checker-data:
type: json
url: https://api.github.com/repos/zen-browser/desktop/releases/latest
version-query: .tag_name
url-query: .assets[] | select(.name=="zen.linux-x86_64.tar.xz") | .browser_download_url
is-main-source: true
- type: archive
url: https://github.com/zen-browser/desktop/releases/download/{version}/zen.linux-aarch64.tar.xz
@@ -75,12 +70,6 @@ modules:
strip-components: 0
only-arches:
- aarch64
x-checker-data:
type: json
url: https://api.github.com/repos/zen-browser/desktop/releases/latest
version-query: .tag_name
url-query: .assets[] | select(.name=="zen.linux-aarch64.tar.xz") | .browser_download_url
is-main-source: true
- type: archive
url: https://github.com/zen-browser/flatpak/releases/download/{version}/archive.tar

View File

@@ -16,7 +16,4 @@ zen-split-link =
zen-split-view-modifier-header = Split View
zen-split-view-modifier-activate-reallocation =
.label = Activate reallocation
zen-split-view-modifier-enabled-toast = Split view rearrange is ON.
zen-split-view-modifier-enabled-toast-description = Drag and drop the view to rearrange. Press Esc to exit.
zen-split-view-modifier-disabled-toast = Split view rearrange is OFF.
.label = Activate reallocation

View File

@@ -6,7 +6,7 @@
value: true
- name: zen.folders.search.hover-delay
value: 700 # ms
value: 500 # ms
- name: zen.folders.max-subfolders
value: 5

View File

@@ -2,7 +2,7 @@
# 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/.
<panel id="zen-folder-tabs-popup" type="arrow" orient="vertical">
<panel id="zen-folder-tabs-popup" type="arrow" orient="vertical" side="left">
<hbox class="tabs-list-header" flex="1">
<image class="zen-folder-tabs-list-search-icon" src="chrome://global/skin/icons/search-glass.svg"/>
<html:input id="zen-folder-tabs-list-search"

View File

@@ -818,6 +818,13 @@ const zenMissingKeyboardShortcutL10n = {
key_accessibility: "zen-devtools-toggle-accessibility-shortcut",
};
var zenIgnoreKeyboardShortcutIDs = [
"key_enterFullScreen_old",
"key_enterFullScreen_compat",
"key_exitFullScreen_old",
"key_exitFullScreen_compat",
];
var zenIgnoreKeyboardShortcutL10n = [
"zen-full-zoom-reduce-shortcut-alt-b",
"zen-full-zoom-reduce-shortcut-alt-a",
@@ -888,7 +895,11 @@ var gZenCKSSettings = {
const labelValue = zenMissingKeyboardShortcutL10n[keyID] ?? l10nID;
if (zenIgnoreKeyboardShortcutL10n.includes(labelValue) || shortcut.shouldBeEmpty) {
if (
zenIgnoreKeyboardShortcutIDs.includes(keyID) ||
zenIgnoreKeyboardShortcutL10n.includes(labelValue) ||
shortcut.shouldBeEmpty
) {
continue;
}

View File

@@ -1,5 +1,5 @@
diff --git a/browser/components/tabbrowser/TabUnloader.sys.mjs b/browser/components/tabbrowser/TabUnloader.sys.mjs
index aefccef39f0b81176a5710a794e8a5e2650d6507..e073c65790df6d55e827a4f4596199f4f1a99a57 100644
index aefccef39f0b81176a5710a794e8a5e2650d6507..53c838b3bc322cadee4ef9b411d02fc0af8c35e5 100644
--- a/browser/components/tabbrowser/TabUnloader.sys.mjs
+++ b/browser/components/tabbrowser/TabUnloader.sys.mjs
@@ -52,7 +52,7 @@ let CRITERIA_WEIGHT = 1;
@@ -11,3 +11,12 @@ index aefccef39f0b81176a5710a794e8a5e2650d6507..e073c65790df6d55e827a4f4596199f4
return weight;
}
@@ -106,7 +106,7 @@ let DefaultTabUnloaderMethods = {
*iterateTabs() {
for (let win of Services.wm.getEnumerator("navigator:browser")) {
- for (let tab of win.gBrowser.tabs) {
+ for (let tab of win.gZenWorkspaces.allStoredTabs) {
yield { tab, gBrowser: win.gBrowser };
}
}

View File

@@ -1,5 +1,5 @@
diff --git a/browser/components/tabbrowser/content/tabbrowser.js b/browser/components/tabbrowser/content/tabbrowser.js
index 0eaca7a58e0026237b71b2ad515efe84d9e8c779..db1c57c8eb4b3d614b5e5aa820871d66b00ec9a4 100644
index 0eaca7a58e0026237b71b2ad515efe84d9e8c779..41cbe295b29abd014cc0425972be45b54fc684d9 100644
--- a/browser/components/tabbrowser/content/tabbrowser.js
+++ b/browser/components/tabbrowser/content/tabbrowser.js
@@ -398,6 +398,7 @@
@@ -438,7 +438,7 @@ index 0eaca7a58e0026237b71b2ad515efe84d9e8c779..db1c57c8eb4b3d614b5e5aa820871d66
this._fireTabOpen(tab, {});
- } else if (tabData.groupId) {
+ }
+ if (tabData.groupId) {
+ if (tabData.groupId && tabGroupWorkingData.get(tabData.groupId)) {
let { groupId } = tabData;
const tabGroup = tabGroupWorkingData.get(groupId);
// if a tab refers to a tab group we don't know, skip any group
@@ -470,10 +470,10 @@ index 0eaca7a58e0026237b71b2ad515efe84d9e8c779..db1c57c8eb4b3d614b5e5aa820871d66
+ gZenWorkspaces._initialTab._shouldRemove = true;
+ }
+ }
+ }
}
+ else {
+ gZenWorkspaces._tabToRemoveForEmpty = this.selectedTab;
}
+ }
+ this._hasAlreadyInitializedZenSessionStore = true;
if (tabs.length > 1 || !tabs[0].selected) {
@@ -959,16 +959,21 @@ index 0eaca7a58e0026237b71b2ad515efe84d9e8c779..db1c57c8eb4b3d614b5e5aa820871d66
// Clear tabs cache after moving nodes because the order of tabs may have
// changed.
this.tabContainer._invalidateCachedTabs();
@@ -6869,6 +7096,18 @@
@@ -6868,7 +7095,22 @@
* @returns {object}
* The new tab in the current window, null if the tab couldn't be adopted.
*/
adoptTab(aTab, { elementIndex, tabIndex, selectTab = false } = {}) {
- adoptTab(aTab, { elementIndex, tabIndex, selectTab = false } = {}) {
+ adoptTab(aTab, { elementIndex, tabIndex, selectTab = false, spaceId = null } = {}) {
+ if (window.gZenWorkspaces.currentWindowIsSyncing && aTab.ownerGlobal.gZenWorkspaces?.currentWindowIsSyncing) {
+ const tabId = aTab.id;
+ const thisTab = window.gZenWindowSync.getItemFromWindow(window, tabId);
+ if (thisTab) {
+ // Just move the tab to the index
+ this.moveTabTo(thisTab, { elementIndex, tabIndex });
+ if (spaceId) {
+ thisTab.setAttribute("zen-workspace-id", spaceId);
+ }
+ if (selectTab) {
+ this.selectedTab = thisTab;
+ }
@@ -978,7 +983,7 @@ index 0eaca7a58e0026237b71b2ad515efe84d9e8c779..db1c57c8eb4b3d614b5e5aa820871d66
// Swap the dropped tab with a new one we create and then close
// it in the other window (making it seem to have moved between
// windows). We also ensure that the tab we create to swap into has
@@ -6910,6 +7149,8 @@
@@ -6910,6 +7152,8 @@
params.userContextId = aTab.getAttribute("usercontextid");
}
let newTab = this.addWebTab("about:blank", params);
@@ -987,7 +992,7 @@ index 0eaca7a58e0026237b71b2ad515efe84d9e8c779..db1c57c8eb4b3d614b5e5aa820871d66
let newBrowser = this.getBrowserForTab(newTab);
aTab.container.tabDragAndDrop.finishAnimateTabMove();
@@ -7718,7 +7959,7 @@
@@ -7718,7 +7962,7 @@
// preventDefault(). It will still raise the window if appropriate.
break;
}
@@ -996,7 +1001,7 @@ index 0eaca7a58e0026237b71b2ad515efe84d9e8c779..db1c57c8eb4b3d614b5e5aa820871d66
window.focus();
aEvent.preventDefault();
break;
@@ -7735,7 +7976,6 @@
@@ -7735,7 +7979,6 @@
}
case "TabGroupCollapse":
aEvent.target.tabs.forEach(tab => {
@@ -1004,7 +1009,7 @@ index 0eaca7a58e0026237b71b2ad515efe84d9e8c779..db1c57c8eb4b3d614b5e5aa820871d66
});
break;
case "TabGroupCreateByUser":
@@ -7895,7 +8135,9 @@
@@ -7895,7 +8138,9 @@
let filter = this._tabFilters.get(tab);
if (filter) {
@@ -1014,7 +1019,7 @@ index 0eaca7a58e0026237b71b2ad515efe84d9e8c779..db1c57c8eb4b3d614b5e5aa820871d66
let listener = this._tabListeners.get(tab);
if (listener) {
@@ -8698,6 +8940,7 @@
@@ -8698,6 +8943,7 @@
aWebProgress.isTopLevel
) {
this.mTab.setAttribute("busy", "true");
@@ -1022,7 +1027,7 @@ index 0eaca7a58e0026237b71b2ad515efe84d9e8c779..db1c57c8eb4b3d614b5e5aa820871d66
gBrowser._tabAttrModified(this.mTab, ["busy"]);
this.mTab._notselectedsinceload = !this.mTab.selected;
}
@@ -8778,6 +9021,7 @@
@@ -8778,6 +9024,7 @@
// known defaults. Note we use the original URL since about:newtab
// redirects to a prerendered page.
const shouldRemoveFavicon =
@@ -1030,7 +1035,7 @@ index 0eaca7a58e0026237b71b2ad515efe84d9e8c779..db1c57c8eb4b3d614b5e5aa820871d66
!this.mBrowser.mIconURL &&
!ignoreBlank &&
!(originalLocation.spec in FAVICON_DEFAULTS);
@@ -9803,7 +10047,7 @@ var TabContextMenu = {
@@ -9803,7 +10050,7 @@ var TabContextMenu = {
);
contextUnpinSelectedTabs.hidden =
!this.contextTab.pinned || !this.multiselected;

View File

@@ -1,5 +1,5 @@
diff --git a/toolkit/content/widgets/arrowscrollbox.js b/toolkit/content/widgets/arrowscrollbox.js
index b80d1049bb6ae305f2ac9c4c35fe975fd508031c..0d900883d903ed48ac57863c0468ab39a6f3d98f 100644
index b80d1049bb6ae305f2ac9c4c35fe975fd508031c..9bc80194d4e35f663b5c15baae55fa48eed4ffe9 100644
--- a/toolkit/content/widgets/arrowscrollbox.js
+++ b/toolkit/content/widgets/arrowscrollbox.js
@@ -98,6 +98,7 @@
@@ -15,7 +15,7 @@ index b80d1049bb6ae305f2ac9c4c35fe975fd508031c..0d900883d903ed48ac57863c0468ab39
on_wheel(event) {
// Don't consume the event if we can't scroll.
- if (!this.overflowing) {
+ if (!this.overflowing || this.id === 'tabbrowser-arrowscrollbox' || ((event.deltaY == 0 || gZenWorkspaces._swipeState?.isGestureActive) && this.classList.contains('workspace-arrowscrollbox'))) {
+ if (!this.overflowing || this.id === 'tabbrowser-arrowscrollbox' || ((event.deltaY == 0 || window.gZenWorkspaces?._swipeState?.isGestureActive) && this.classList.contains('workspace-arrowscrollbox'))) {
return;
}

View File

@@ -1,5 +1,5 @@
diff --git a/toolkit/themes/shared/popup.css b/toolkit/themes/shared/popup.css
index c2618b86d7e8bb71f9f7f71ef9916c8140ca1ead..9e2006015e22f1ac043c46066c4c9a85fe053a21 100644
index c2618b86d7e8bb71f9f7f71ef9916c8140ca1ead..96a602f9cbfb77ee0a52151ce8ccf7ba17cf5c43 100644
--- a/toolkit/themes/shared/popup.css
+++ b/toolkit/themes/shared/popup.css
@@ -22,8 +22,8 @@ panel {
@@ -13,3 +13,24 @@ index c2618b86d7e8bb71f9f7f71ef9916c8140ca1ead..9e2006015e22f1ac043c46066c4c9a85
-moz-window-input-region-margin: var(--panel-shadow-margin);
margin: calc(-1 * var(--panel-shadow-margin));
@@ -143,11 +143,7 @@ panel[type="arrow"] {
-moz-window-transform,
-moz-window-opacity;
@media not (prefers-reduced-motion) {
- -moz-window-transform: translateY(-70px);
-
- &:where([side="bottom"]) {
- -moz-window-transform: translateY(70px);
- }
+ -moz-window-transform: scale(0);
}
/* Only do the fade-in animation on pre-Big Sur to avoid missing shadows on
* Big Sur+, see bug 1672091. */
@@ -161,7 +157,6 @@ panel[type="arrow"] {
}
&[animate="cancel"] {
- -moz-window-transform: none;
transform: none;
}

View File

@@ -222,7 +222,7 @@ window.gZenUIManager = {
"--zen-urlbar-top",
`${window.innerHeight / 2 - Math.max(kUrlbarHeight, gURLBar.getBoundingClientRect().height) / 2}px`
);
gURLBar.style.setProperty("--zen-urlbar-width", `${Math.min(window.innerWidth / 2, 700)}px`);
gURLBar.style.setProperty("--zen-urlbar-width", `${Math.min(window.innerWidth / 2, 750)}px`);
gZenVerticalTabsManager.actualWindowButtons.removeAttribute("zen-has-hover");
gZenVerticalTabsManager.recalculateURLBarHeight();
if (!this._preventToolbarRebuild) {
@@ -570,11 +570,10 @@ window.gZenUIManager = {
},
urlbarTrim(aURL) {
if (
gZenVerticalTabsManager._hasSetSingleToolbar &&
this.urlbarShowDomainOnly &&
!gURLBar.hasAttribute("breakout-extend")
) {
if (gURLBar.hasAttribute("breakout-extend")) {
return aURL;
}
if (gZenVerticalTabsManager._hasSetSingleToolbar && this.urlbarShowDomainOnly) {
let url = BrowserUIUtils.removeSingleTrailingSlashFromURL(aURL);
return url.startsWith("https://") ? url.split("/")[2] : url;
}

View File

@@ -4,18 +4,6 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
@keyframes zen-jello-animation-macos {
0% {
-moz-window-opacity: 0;
-moz-window-transform: scale(0.8);
}
100% {
-moz-window-opacity: 1;
-moz-window-transform: scale(1);
}
}
@keyframes zen-theme-picker-dot-animation {
from {
transform: scale(0.8) translate(-50%, -50%);

View File

@@ -17,7 +17,7 @@
}
.urlbar {
--urlbarView-separator-color: light-dark(hsl(0, 0%, 89%), hsl(0, 0%, 20%));
--urlbarView-separator-color: light-dark(hsl(0, 0%, 92%), hsl(0, 0%, 20%));
--urlbarView-hover-background: var(--toolbarbutton-hover-background);
--urlbarView-highlight-background: var(--toolbarbutton-hover-background);
border-radius: calc(var(--toolbarbutton-border-radius) - 2px);

View File

@@ -9,18 +9,29 @@ panel[type="arrow"] {
/* Animate from the bottom */
-zen-window-transform-origin: 0 100%;
}
&[side="left"] {
/* Animate from the left and center */
-zen-window-transform-origin: 0 50%;
}
&[side="right"] {
/* Animate from the right */
-zen-window-transform-origin: 100% 50%;
}
:root[zen-right-side="true"] & {
/* Animate from the right */
-zen-window-transform-origin: 100% 0;
&[side="bottom"] {
/* Animate from the bottom right */
-zen-window-transform-origin: 100% 100%;
}
}
-moz-window-opacity: 0;
&[animate="open"] {
animation: zen-jello-animation-macos 0.2s ease-in-out forwards !important;
&[side="left"] {
/* Animate from the right */
-zen-window-transform-origin: 100% 50%;
}
&[side="right"] {
/* Animate from the right */
-zen-window-transform-origin: 100% 50%;
}
}
}
}

View File

@@ -12,12 +12,12 @@ document.addEventListener(
case "cmd_zenCompactModeToggle":
gZenCompactModeManager.toggle();
break;
case "cmd_zenCompactModeShowSidebar":
gZenCompactModeManager.toggleSidebar();
break;
case "cmd_toggleCompactModeIgnoreHover":
gZenCompactModeManager.toggle(true);
break;
case "cmd_zenCompactModeShowSidebar":
gZenCompactModeManager.toggleSidebar();
break;
case "cmd_zenWorkspaceForward":
gZenWorkspaces.changeWorkspaceShortcut();
break;

View File

@@ -630,6 +630,7 @@ window.gZenCompactModeManager = {
_setElementExpandAttribute(element, value, attr = "zen-has-hover") {
const kVerifiedAttributes = ["zen-has-hover", "has-popup-menu", "zen-compact-mode-active"];
const isToolbar = element.id === "zen-appcontent-navbar-wrapper";
this.log("Setting", attr, "to", value, "on element", element?.id);
if (value) {
if (attr === "zen-has-hover" && element !== gZenVerticalTabsManager.actualWindowButtons) {
element.setAttribute("zen-has-implicit-hover", "true");
@@ -666,6 +667,7 @@ window.gZenCompactModeManager = {
addMouseActions() {
gURLBar.addEventListener("mouseenter", (event) => {
this.log("Mouse entered URL bar:", event.target);
if (event.target.closest("#urlbar[zen-floating-urlbar]")) {
window.requestAnimationFrame(() => {
this._setElementExpandAttribute(gZenVerticalTabsManager.actualWindowButtons, false);

View File

@@ -105,6 +105,7 @@
startTabDrag(event, tab, ...args) {
this.ZenDragAndDropService.onDragStart(1);
this.#isOutOfWindow = false;
gZenCompactModeManager._isTabBeingDragged = true;
super.startTabDrag(event, tab, ...args);
const dt = event.dataTransfer;
@@ -861,6 +862,7 @@
const draggedTab = dt.mozGetDataAt(TAB_DROP_TYPE, 0);
let ownerGlobal = draggedTab?.ownerGlobal;
draggedTab.style.visibility = "";
let thisFromGlobal = ownerGlobal?.gBrowser.tabContainer.tabDragAndDrop;
let currentEssenialContainer = ownerGlobal.gZenWorkspaces.getCurrentEssentialsContainer();
if (currentEssenialContainer?.essentialsPromo) {
currentEssenialContainer.essentialsPromo.remove();
@@ -870,19 +872,21 @@
ownerGlobal.gZenFolders.highlightGroupOnDragOver(null);
this.ZenDragAndDropService.onDragEnd();
super.handle_dragend(event);
this.#removeDragOverBackground();
thisFromGlobal.clearDragOverVisuals();
ownerGlobal.gZenPinnedTabManager.removeTabContainersDragoverClass();
this.#maybeClearVerticalPinnedGridDragOver();
this.originalDragImageArgs = [];
window.removeEventListener("dragenter", this.handle_windowDragEnter, { capture: true });
thisFromGlobal.originalDragImageArgs = [];
window.removeEventListener("dragenter", thisFromGlobal.handle_windowDragEnter, {
capture: true,
});
this.#isOutOfWindow = false;
if (this._browserDragImageWrapper) {
this._browserDragImageWrapper.remove();
delete this._browserDragImageWrapper;
if (thisFromGlobal._browserDragImageWrapper) {
thisFromGlobal._browserDragImageWrapper.remove();
delete thisFromGlobal._browserDragImageWrapper;
}
if (this._tempDragImageParent) {
this._tempDragImageParent.remove();
delete this._tempDragImageParent;
if (thisFromGlobal._tempDragImageParent) {
thisFromGlobal._tempDragImageParent.remove();
delete thisFromGlobal._tempDragImageParent;
}
delete ownerGlobal.gZenCompactModeManager._isTabBeingDragged;
if (dt.dropEffect !== "move") {
@@ -941,14 +945,19 @@
);
if (event.target.classList.contains("zen-workspace-empty-space") || hoveringPeriphery) {
let lastTab = gBrowser.tabs.at(-1);
dropElement =
(hoveringPeriphery && Services.prefs.getBoolPref("zen.view.show-newtab-button-top")
? this._tabbrowserTabs.ariaFocusableItems.at(
gBrowser._numVisiblePinTabsWithoutCollapsed
)
: this._tabbrowserTabs.ariaFocusableItems.at(-1)) || lastTab;
let pinnedTabsCount = gBrowser._numVisiblePinTabsWithoutCollapsed;
// Only if there are no normal tabs to drop after
showIndicatorUnderNewTabButton = lastTab.hasAttribute("zen-empty-tab");
let useLastPinnd =
(hoveringPeriphery ||
(showIndicatorUnderNewTabButton &&
!(pinnedTabsCount - gBrowser._numZenEssentials))) &&
Services.prefs.getBoolPref("zen.view.show-newtab-button-top");
dropElement =
(useLastPinnd
? this._tabbrowserTabs.ariaFocusableItems.at(pinnedTabsCount)
: this._tabbrowserTabs.ariaFocusableItems.at(-1)) || lastTab;
}
}
dropElement = elementToMove(dropElement);

View File

@@ -256,6 +256,7 @@ export class nsZenFolder extends MozTabbrowserTabGroup {
folderToUnload: this,
});
this.activeTabs = [];
this.collapsed = true;
}
on_click(event) {

View File

@@ -179,7 +179,7 @@ class nsZenFolders extends nsZenDOMOperatedFeature {
if (this.#popup.matches(":hover")) {
return;
}
this.#popup.hidePopup();
this.#popup.hidePopup(true);
}, 200);
});
}
@@ -357,7 +357,7 @@ class nsZenFolders extends nsZenDOMOperatedFeature {
this.#mouseTimer = null;
}
if (this.#popup) {
this.#popup.hidePopup();
this.#popup.hidePopup(true);
}
}
@@ -729,11 +729,13 @@ class nsZenFolders extends nsZenDOMOperatedFeature {
get #searchPopupOptions() {
const isRightSide = gZenVerticalTabsManager._prefsRightSide;
const position = isRightSide ? "topleft topright" : "topright topleft";
const position = isRightSide ? "start_before" : "start_before";
let size = Math.min(this.#popup.querySelector("#zen-folder-tabs-list").children.length, 6);
size *= 48;
return {
position,
x: 10,
y: -25,
x: -10,
y: size / -2,
};
}
@@ -958,7 +960,7 @@ class nsZenFolders extends nsZenDOMOperatedFeature {
if (this.#popup.matches(":hover")) {
return;
}
this.#popup.hidePopup();
this.#popup.hidePopup(true);
}, 200);
});
}

View File

@@ -677,7 +677,7 @@ class nsZenKeyboardShortcutsLoader {
"",
ZEN_COMPACT_MODE_SHORTCUTS_GROUP,
nsKeyShortcutModifiers.fromObject({ accel: true }),
"cmd_zenCompactModeToggle",
"cmd_toggleCompactModeIgnoreHover",
"zen-compact-mode-shortcut-toggle"
)
);
@@ -812,7 +812,7 @@ class nsZenKeyboardShortcutsLoader {
}
class nsZenKeyboardShortcutsVersioner {
static LATEST_KBS_VERSION = 14;
static LATEST_KBS_VERSION = 16;
constructor() {}
@@ -1146,6 +1146,17 @@ class nsZenKeyboardShortcutsVersioner {
}
}
if (version < 16) {
// Migrate from version 14 to 16.
// We move the action for "toggle compact mode" to "cmd_toggleCompactModeIgnoreHover"
for (let shortcut of data) {
if (shortcut.getID() == "zen-compact-mode-toggle") {
shortcut._setAction("cmd_toggleCompactModeIgnoreHover");
break;
}
}
}
return data;
}
}

View File

@@ -30,10 +30,6 @@ XPCOMUtils.defineLazyPreferenceGetter(
3
);
const SHOULD_LOG_TAB_ENTRIES = Services.prefs.getBoolPref(
"zen.session-store.log-tab-entries",
false
);
const SHOULD_BACKUP_FILE = Services.prefs.getBoolPref("zen.session-store.backup-file", true);
const FILE_NAME = "zen-sessions.jsonlz4";
@@ -127,37 +123,47 @@ export class nsZenSessionManager {
const db = await PlacesUtils.promiseDBConnection();
let data = {};
let rows = await db.execute("SELECT * FROM zen_workspaces ORDER BY created_at ASC");
data.spaces = rows.map((row) => ({
uuid: row.getResultByName("uuid"),
name: row.getResultByName("name"),
icon: row.getResultByName("icon"),
containerTabId: row.getResultByName("container_id") ?? 0,
position: row.getResultByName("position"),
theme: row.getResultByName("theme_type")
? {
type: row.getResultByName("theme_type"),
gradientColors: JSON.parse(row.getResultByName("theme_colors")),
opacity: row.getResultByName("theme_opacity"),
rotation: row.getResultByName("theme_rotation"),
texture: row.getResultByName("theme_texture"),
}
: null,
}));
rows = await db.execute("SELECT * FROM zen_pins ORDER BY position ASC");
data.pins = rows.map((row) => ({
uuid: row.getResultByName("uuid"),
title: row.getResultByName("title"),
url: row.getResultByName("url"),
containerTabId: row.getResultByName("container_id"),
workspaceUuid: row.getResultByName("workspace_uuid"),
position: row.getResultByName("position"),
isEssential: Boolean(row.getResultByName("is_essential")),
isGroup: Boolean(row.getResultByName("is_group")),
parentUuid: row.getResultByName("folder_parent_uuid"),
editedTitle: Boolean(row.getResultByName("edited_title")),
folderIcon: row.getResultByName("folder_icon"),
isFolderCollapsed: Boolean(row.getResultByName("is_folder_collapsed")),
}));
try {
data.spaces = rows.map((row) => ({
uuid: row.getResultByName("uuid"),
name: row.getResultByName("name"),
icon: row.getResultByName("icon"),
containerTabId: row.getResultByName("container_id") ?? 0,
position: row.getResultByName("position"),
theme: row.getResultByName("theme_type")
? {
type: row.getResultByName("theme_type"),
gradientColors: JSON.parse(row.getResultByName("theme_colors")),
opacity: row.getResultByName("theme_opacity"),
rotation: row.getResultByName("theme_rotation"),
texture: row.getResultByName("theme_texture"),
}
: null,
}));
} catch (e) {
/* ignore errors reading spaces data, as it is not critical and we want to migrate even if we fail to read it */
console.error("Failed to read spaces data from database during migration", e);
}
try {
rows = await db.execute("SELECT * FROM zen_pins ORDER BY position ASC");
data.pins = rows.map((row) => ({
uuid: row.getResultByName("uuid"),
title: row.getResultByName("title"),
url: row.getResultByName("url"),
containerTabId: row.getResultByName("container_id"),
workspaceUuid: row.getResultByName("workspace_uuid"),
position: row.getResultByName("position"),
isEssential: Boolean(row.getResultByName("is_essential")),
isGroup: Boolean(row.getResultByName("is_group")),
parentUuid: row.getResultByName("folder_parent_uuid"),
editedTitle: Boolean(row.getResultByName("edited_title")),
folderIcon: row.getResultByName("folder_icon"),
isFolderCollapsed: Boolean(row.getResultByName("is_folder_collapsed")),
}));
} catch (e) {
/* ignore errors reading pins data, as it is not critical and we want to migrate even if we fail to read it */
console.error("Failed to read pins data from database during migration", e);
}
try {
data.recoveryData = await IOUtils.readJSON(
PathUtils.join(
@@ -187,8 +193,9 @@ export class nsZenSessionManager {
}
}
this._migrationData = data;
} catch {
} catch (e) {
/* ignore errors during migration */
console.error(e);
}
}
@@ -225,7 +232,7 @@ export class nsZenSessionManager {
this._shouldRunMigration = true;
await this.#getDataFromDBForMigration();
}
if (SHOULD_LOG_TAB_ENTRIES) {
if (Services.prefs.getBoolPref("zen.session-store.log-tab-entries", false)) {
for (const tab of this.#sidebar.tabs || []) {
this.log("Tab entry in session file:", tab);
}

View File

@@ -47,6 +47,9 @@ const EVENTS = [
"TabGroupRemoved",
"TabGroupMoved",
"TabHide",
"TabShow",
"ZenTabRemovedFromSplit",
"ZenSplitViewTabsSplit",
@@ -245,8 +248,6 @@ class nsZenWindowSync {
for (let tab of gZenWorkspaces.allStoredTabs) {
if (!tab.id) {
tab.id = this.#newTabSyncId;
// Don't call with await here to avoid blocking the loop.
this.#maybeFlushTabState(tab);
}
if (tab.pinned && !tab._zenPinnedInitialState) {
await this.setPinnedTabState(tab);
@@ -474,9 +475,6 @@ class nsZenWindowSync {
this.#maybeSyncAttributeChange(aOriginalItem, aTargetItem, "zen-workspace-id");
this.#syncItemPosition(aOriginalItem, aTargetItem, aWindow);
}
if (gBrowser.isTab(aTargetItem)) {
this.#maybeFlushTabState(aTargetItem);
}
}
/**
@@ -720,7 +718,7 @@ class nsZenWindowSync {
return;
}
lazy.TabStateCache.update(aOurTab.linkedBrowser.permanentKey, {
history: tabStateEntries,
history: Cu.cloneInto(tabStateEntries, {}),
});
};
// Running `swapBrowsersAndCloseOther` doesn't expect us to use the tab after
@@ -803,6 +801,7 @@ class nsZenWindowSync {
{
fullScale: true,
fullViewport: true,
backgroundColor: "transparent",
}
);
@@ -820,17 +819,18 @@ class nsZenWindowSync {
let promise = this.#createPseudoImageForBrowser(otherBrowser, mySrc);
await Promise.all([promiseToWait, promise]);
aOurTab.ownerGlobal.requestAnimationFrame(() => {
callback();
lazy.setTimeout(() => {
otherBrowser.setAttribute("zen-pseudo-hidden", "true");
ourBrowser.removeAttribute("zen-pseudo-hidden");
this.#maybeRemovePseudoImageForBrowser(ourBrowser);
ourBrowser.focus();
resolve();
});
callback();
} else {
ourBrowser.removeAttribute("zen-pseudo-hidden");
this.#maybeRemovePseudoImageForBrowser(ourBrowser);
return;
}
ourBrowser.removeAttribute("zen-pseudo-hidden");
this.#maybeRemovePseudoImageForBrowser(ourBrowser);
resolve();
});
}
@@ -1151,7 +1151,6 @@ class nsZenWindowSync {
if (duringPinning && tab?.splitView) {
this.on_ZenSplitViewTabsSplit({ target: tab.group });
}
this.#maybeFlushTabState(tab);
}
on_ZenTabIconChanged(aEvent) {
@@ -1171,6 +1170,34 @@ class nsZenWindowSync {
return this.#delegateGenericSyncEvent(aEvent, SYNC_FLAG_LABEL);
}
on_TabHide(aEvent) {
const tab = aEvent.target;
const window = tab.ownerGlobal;
if (lazy.gSyncOnlyPinnedTabs && !tab.pinned) {
return;
}
this.#runOnAllWindows(window, (win) => {
const targetTab = this.getItemFromWindow(win, tab.id);
if (targetTab) {
targetTab.ownerGlobal.gBrowser.hideTab(targetTab);
}
});
}
on_TabShow(aEvent) {
const tab = aEvent.target;
const window = tab.ownerGlobal;
if (lazy.gSyncOnlyPinnedTabs && !tab.pinned) {
return;
}
this.#runOnAllWindows(window, (win) => {
const targetTab = this.getItemFromWindow(win, tab.id);
if (targetTab) {
targetTab.ownerGlobal.gBrowser.showTab(targetTab);
}
});
}
on_TabMove(aEvent) {
this.#delegateGenericSyncEvent(aEvent, SYNC_FLAG_MOVE);
return Promise.resolve();

View File

@@ -641,21 +641,6 @@ class nsZenViewSplitter extends nsZenDOMOperatedFeature {
}
}
get rearangeActionTarget() {
return document.getElementById("urlbar-container");
}
afterRearangeAction() {
document.getElementById("zenSplitViewModifier").hidePopup();
gZenUIManager.showToast("zen-split-view-modifier-enabled-toast", {
descriptionId: "zen-split-view-modifier-enabled-toast-description",
});
}
afterRearangeRemove() {
gZenUIManager.showToast("zen-split-view-modifier-disabled-toast");
}
toggleWrapperDisplay(value) {
const wrapper = this.overlay?.parentNode;
if (!wrapper) {
@@ -695,9 +680,6 @@ class nsZenViewSplitter extends nsZenDOMOperatedFeature {
this.tabBrowserPanel.addEventListener("click", this.disableTabRearrangeView);
window.addEventListener("keydown", this.disableTabRearrangeView);
if (!tabDrag) {
this.afterRearangeAction();
}
}
disableTabRearrangeView = (event = null) => {
@@ -733,10 +715,6 @@ class nsZenViewSplitter extends nsZenDOMOperatedFeature {
});
this.rearrangeViewEnabled = false;
this.rearrangeViewView = null;
if (!event?.type === "dragend") {
// Don't show toast if exiting from drag
this.afterRearangeRemove();
}
};
onBrowserDragStart = (event) => {

View File

@@ -595,6 +595,7 @@ class nsZenPinnedTabManager extends nsZenDOMOperatedFeature {
tab = gBrowser.adoptTab(tab, {
elementIndex: newIndex,
selectTab: tab == draggedTab,
spaceId: workspaceId,
});
if (tab) {
++newIndex;

View File

@@ -1130,7 +1130,7 @@
position: absolute;
:root[zen-single-toolbar="true"] &:not(:empty) {
padding-top: 6px;
padding-top: 4px;
}
&[hidden="true"] {

View File

@@ -182,9 +182,10 @@ export class nsZenThemePicker extends nsZenMultiWindowFeature {
"zen-workspace-creation-edit-theme-button"
);
PanelMultiView.openPopup(this.panel, this.toolbox, {
position: "topright topleft",
position: "start_before",
triggerEvent: event,
y: fromForm ? -160 : 0,
x: -10,
});
}

View File

@@ -159,7 +159,7 @@ class nsZenWorkspaces {
}
}
async #afterLoadInit() {
#afterLoadInit() {
const onResize = (...args) => {
requestAnimationFrame(() => {
this.onPinnedTabsResize(...args);
@@ -523,7 +523,7 @@ class nsZenWorkspaces {
_handleAppCommand(event) {
// note: Dont use this._hoveringSidebar as it's not as reliable as checking for :hover
if (!this.workspaceEnabled || !this._hoveringSidebar) {
if (!this.workspaceEnabled || !gNavToolbox.matches(":hover")) {
return;
}
@@ -918,7 +918,7 @@ class nsZenWorkspaces {
this.#initializeEmptyTab();
return (async () => {
await this.#waitForPromises();
await this.#afterLoadInit();
this.#afterLoadInit();
await this.workspaceBookmarks();
await this.changeWorkspace(activeWorkspace, { onInit: true });
this.#fixTabPositions();

View File

@@ -5,8 +5,8 @@
"binaryName": "zen",
"version": {
"product": "firefox",
"version": "147.0.3",
"candidate": "147.0.3",
"version": "147.0.4",
"candidate": "147.0.4",
"candidateBuild": 1
},
"buildOptions": {
@@ -20,7 +20,7 @@
"brandShortName": "Zen",
"brandFullName": "Zen Browser",
"release": {
"displayVersion": "1.18.7b",
"displayVersion": "1.18.9b",
"github": {
"repo": "zen-browser/desktop"
},