Compare commits

..

20 Commits

Author SHA1 Message Date
mr. m
f0a63fa7c5 no-bug: Fixed overflowable addons clipping button badges (gh-13679) 2026-05-13 12:38:31 +02:00
mr. m
ad52054113 no-bug: Sync upstream Firefox to version 150.0.3 (gh-13670) 2026-05-12 23:20:00 +02:00
Guilherme Luiz Cella
0a7ee3fcf0 no-bug: Refactor _oppositeSide method using OPPOSITE_SIDES (gh-13613)
Signed-off-by: Guilherme Luiz Cella <151692400+guilherme-luiz-cella@users.noreply.github.com>
Co-authored-by: mr. m <91018726+mr-cheffy@users.noreply.github.com>
2026-05-12 11:57:56 +02:00
mr. m
c406e79c5d no-bug: Remove fullscreen prefs (gh-13648) 2026-05-10 23:28:52 +02:00
jakubiakdev
78c37a122e no-bug: Improve flaky URLBar scrolling (gh-13645)
Co-authored-by: mr. m <mr.m@tuta.com>
2026-05-10 23:26:52 +02:00
AbdullahMRiad
8f0edbd91a no-bug: Fix capitalization of 'GitHub' in README (gh-13635) 2026-05-09 23:44:46 +02:00
mr. m
d9c6dcdca4 no-bug: Improve space swipe performance (gh-13631) 2026-05-09 18:20:05 +02:00
mr. m
4983c0a877 no-bug: Lint project (gh-13632) 2026-05-09 17:53:52 +02:00
sporocyst
4e6521a713 gh-13629: fix tab renaming input field too narrow (gh-13630) 2026-05-09 16:50:29 +02:00
mr. m
da9838e478 gh-13620: Fixed unresponsive tabs when opening external links (gh-13628) 2026-05-09 12:17:13 +02:00
mr. m
639bf29de3 gh-13623: Fixed native popovers not working after using dropdowns (gh-13627) 2026-05-09 12:17:00 +02:00
mr. m
cfd1e7a6aa no-bug: Make extensions list hidden for double toolbar (gh-13610) 2026-05-08 13:08:17 +02:00
mr. m
17f61152b9 Revert "no-bug: A few quality-of-life tweaks (build tooling)" (gh-13605) 2026-05-07 21:27:37 +02:00
mr. m
9c88e3a84f no-bug: Sync upstream Firefox to version 150.0.2 (gh-13601) 2026-05-07 18:28:25 +02:00
mr. m
b999a932ac no-bug: Improve swipe feel and avoid big jumps while swiping (gh-13603) 2026-05-07 17:08:50 +02:00
dependabot[bot]
e9a0beae20 no-bug: bump axios from 1.15.0 to 1.16.0 (gh-13590)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-05-06 23:12:02 +02:00
Daniel Richard G.
b93c2054c4 no-bug: A few quality-of-life tweaks (build tooling) (gh-13565) 2026-05-06 21:38:16 +02:00
mr. m
dcf272f620 gh-13516: Show the loading indicator ontop of the webview for toolbar mode (gh-13588) 2026-05-06 16:23:05 +02:00
mr. m
3ffdf6b299 gh-13583: Fixed Previous Space in menu bar not working (gh-13587) 2026-05-06 16:10:02 +02:00
mr. m
b052c1d804 gh-13584: Add click tab to split config (gh-13586) 2026-05-06 16:02:41 +02:00
28 changed files with 318 additions and 197 deletions

View File

@@ -129,7 +129,7 @@ jobs:
token: ${{ secrets.DEPLOY_KEY }}
commit-message: "chore: Sync upstream to `Firefox ${{ steps.build-data.outputs.version }}`"
branch: "chore/upstream-sync"
title: "Sync upstream Firefox to version ${{ steps.build-data.outputs.version }}"
title: "no-bug: Sync upstream Firefox to version ${{ steps.build-data.outputs.version }}"
body: |
This PR syncs the upstream Firefox to version ${{ steps.build-data.outputs.version }}.

View File

@@ -34,12 +34,12 @@ 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 `150.0.1`! 🚀
- [`Twilight`](https://zen-browser.app/download?twilight) - Is currently built using Firefox version `RC 150.0.1`!
- [`Release`](https://zen-browser.app/download) - Is currently built using Firefox version `150.0.3`! 🚀
- [`Twilight`](https://zen-browser.app/download?twilight) - Is currently built using Firefox version `RC 150.0.3`!
### Contributing
If you'd like to report a bug, please do so on our [GitHub Issues page](https://github.com/zen-browser/desktop/issues/) and for feature requests, you can use [Github Discussions](https://github.com/zen-browser/desktop/discussions).
If you'd like to report a bug, please do so on our [GitHub Issues page](https://github.com/zen-browser/desktop/issues/) and for feature requests, you can use [GitHub Discussions](https://github.com/zen-browser/desktop/discussions).
Zen is an open-source project, and we welcome contributions from the community! Please take a look at the [contribution guidelines](./docs/contribute.md) before getting started!

View File

@@ -1 +1 @@
e097b3c5ca4139a5b88052379a776782e078356b
69c3d9ff05fd352d761a41ec35f59b06e166e3bc

8
package-lock.json generated
View File

@@ -1005,13 +1005,13 @@
"license": "MIT"
},
"node_modules/axios": {
"version": "1.15.0",
"resolved": "https://registry.npmjs.org/axios/-/axios-1.15.0.tgz",
"integrity": "sha512-wWyJDlAatxk30ZJer+GeCWS209sA42X+N5jU2jy6oHTp7ufw8uzUTVFBX9+wTfAlhiJXGS0Bq7X6efruWjuK9Q==",
"version": "1.16.0",
"resolved": "https://registry.npmjs.org/axios/-/axios-1.16.0.tgz",
"integrity": "sha512-6hp5CwvTPlN2A31g5dxnwAX0orzM7pmCRDLnZSX772mv8WDqICwFjowHuPs04Mc8deIld1+ejhtaMn5vp6b+1w==",
"dev": true,
"license": "MIT",
"dependencies": {
"follow-redirects": "^1.15.11",
"follow-redirects": "^1.16.0",
"form-data": "^4.0.5",
"proxy-from-env": "^2.1.0"
}

View File

@@ -1,16 +0,0 @@
# 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/.
# Fullscreen API preferences
- name: full-screen-api.transition-duration.enter
value: "0 0"
- name: full-screen-api.transition-duration.leave
value: "0 0"
- name: full-screen-api.warning.delay
value: -1
- name: full-screen-api.warning.timeout
value: 0

View File

@@ -5,6 +5,9 @@
- name: zen.splitView.enable-tab-drop
value: true
- name: zen.splitView.enable-tab-click-split
value: true
- name: zen.splitView.min-resize-width
value: 7

View File

@@ -17,6 +17,12 @@
- name: zen.workspaces.swipe-actions
value: true
- name: zen.workspaces.swipe-actions.delta-multiplier
value: 100
- name: zen.workspaces.switch-animation-duration
value: 200
- name: zen.workspaces.wrap-around-navigation
value: true

View File

@@ -1,5 +1,5 @@
diff --git a/browser/components/tabbrowser/content/tab.js b/browser/components/tabbrowser/content/tab.js
index 2e02bad1a7c89b4c3b5aee1e14c13bb953a64eb6..139fa9be7919928e5a57fda6c7fabe4bc5acf982 100644
index 2e02bad1a7c89b4c3b5aee1e14c13bb953a64eb6..fb9ec4deb5871bc0ba57c323a413f07440e9aa42 100644
--- a/browser/components/tabbrowser/content/tab.js
+++ b/browser/components/tabbrowser/content/tab.js
@@ -21,6 +21,7 @@
@@ -151,14 +151,15 @@ index 2e02bad1a7c89b4c3b5aee1e14c13bb953a64eb6..139fa9be7919928e5a57fda6c7fabe4b
on_click(event) {
if (event.button != 0) {
return;
@@ -617,14 +656,30 @@
@@ -617,14 +656,31 @@
trigger: "alt_click",
});
}
+ if (
+ !event.target.classList.contains("tab-close-button") &&
+ !event.target.classList.contains("tab-icon-overlay") &&
+ !event.target.classList.contains("tab-audio-button")
+ !event.target.classList.contains("tab-audio-button") &&
+ Services.prefs.getBoolPref("zen.splitView.enable-tab-click-split", false)
+ ) {
+ if (!this.splitView) {
+ gZenViewSplitter.contextSplitTabs(this);
@@ -183,7 +184,7 @@ index 2e02bad1a7c89b4c3b5aee1e14c13bb953a64eb6..139fa9be7919928e5a57fda6c7fabe4b
gBrowser.multiSelectedTabsCount > 0 &&
!event.target.classList.contains("tab-close-button") &&
!event.target.classList.contains("tab-icon-overlay") &&
@@ -636,8 +691,9 @@
@@ -636,8 +692,9 @@
}
if (
@@ -195,7 +196,7 @@ index 2e02bad1a7c89b4c3b5aee1e14c13bb953a64eb6..139fa9be7919928e5a57fda6c7fabe4b
) {
if (this.activeMediaBlocked) {
if (this.multiselected) {
@@ -655,7 +711,7 @@
@@ -655,7 +712,7 @@
return;
}
@@ -204,7 +205,7 @@ index 2e02bad1a7c89b4c3b5aee1e14c13bb953a64eb6..139fa9be7919928e5a57fda6c7fabe4b
if (this.multiselected) {
gBrowser.removeMultiSelectedTabs(
lazy.TabMetrics.userTriggeredContext(
@@ -675,6 +731,14 @@
@@ -675,6 +732,14 @@
// (see tabbrowser-tabs 'click' handler).
gBrowser.tabContainer._blockDblClick = true;
}
@@ -219,7 +220,7 @@ index 2e02bad1a7c89b4c3b5aee1e14c13bb953a64eb6..139fa9be7919928e5a57fda6c7fabe4b
}
on_dblclick(event) {
@@ -698,6 +762,8 @@
@@ -698,6 +763,8 @@
animate: true,
triggeringEvent: event,
});

View File

@@ -1,5 +1,5 @@
diff --git a/browser/components/urlbar/UrlbarValueFormatter.sys.mjs b/browser/components/urlbar/UrlbarValueFormatter.sys.mjs
index f28d277764158566bc9406ce0e6160d92d346a63..82dd5f8568ec1b12e87676e5c2b243824628b5af 100644
index f28d277764158566bc9406ce0e6160d92d346a63..aee17083999f99670c2de7b47cb917e400da86a6 100644
--- a/browser/components/urlbar/UrlbarValueFormatter.sys.mjs
+++ b/browser/components/urlbar/UrlbarValueFormatter.sys.mjs
@@ -77,7 +77,7 @@ export class UrlbarValueFormatter {
@@ -11,7 +11,30 @@ index f28d277764158566bc9406ce0e6160d92d346a63..82dd5f8568ec1b12e87676e5c2b24382
});
}
@@ -371,7 +371,7 @@ export class UrlbarValueFormatter {
@@ -105,6 +105,22 @@ export class UrlbarValueFormatter {
}
#ensureFormattedHostVisible(urlMetaData) {
+ // Make sure the domain is visible even with long subdomains when the single sidebar is being used
+ if (
+ this.#window.gZenVerticalTabsManager?._hasSetSingleToolbar
+ && Services.prefs.getBoolPref("zen.urlbar.show-domain-only-in-sidebar")
+ ) {
+ const hoverAttr = "zen-has-implicit-hover";
+ const hasHover = this.#window.gNavToolbox.hasAttribute(hoverAttr);
+ this.#window.gNavToolbox.removeAttribute(hoverAttr);
+
+ this.#inputField.scrollLeft = this.#inputField.scrollLeftMax;
+
+ if (hasHover) {
+ this.#window.gNavToolbox.setAttribute(hoverAttr, true);
+ }
+ return;
+ }
// Make sure the host is always visible. Since it is aligned on
// the first strong directional character, we set scrollLeft
// appropriately to ensure the domain stays visible in case of an
@@ -371,7 +387,7 @@ export class UrlbarValueFormatter {
* @returns {boolean}
* True if formatting was applied and false if not.
*/
@@ -20,7 +43,7 @@ index f28d277764158566bc9406ce0e6160d92d346a63..82dd5f8568ec1b12e87676e5c2b24382
let urlMetaData = this.#getUrlMetaData();
if (!urlMetaData) {
return false;
@@ -640,6 +640,7 @@ export class UrlbarValueFormatter {
@@ -640,6 +656,7 @@ export class UrlbarValueFormatter {
this.#window.requestAnimationFrame(() => {
if (instance == this.#resizeInstance) {
this.#ensureFormattedHostVisible();

View File

@@ -1,5 +1,5 @@
diff --git a/browser/themes/shared/urlbar-searchbar.css b/browser/themes/shared/urlbar-searchbar.css
index 0ee35cfe67c9bce37a844d4b7d9715d4fb50f709..5cdb8037e49a68ea4126af349690af8a16b5e59b 100644
index 0ee35cfe67c9bce37a844d4b7d9715d4fb50f709..034cf876c8cef5a2b4c0ca5f209d127dbfc90b20 100644
--- a/browser/themes/shared/urlbar-searchbar.css
+++ b/browser/themes/shared/urlbar-searchbar.css
@@ -10,7 +10,7 @@
@@ -20,7 +20,18 @@ index 0ee35cfe67c9bce37a844d4b7d9715d4fb50f709..5cdb8037e49a68ea4126af349690af8a
}
/* Document Picture-in-Picture API window */
@@ -333,10 +333,14 @@ toolbar[inactive="true"] .urlbar,
@@ -200,6 +200,10 @@ toolbar[inactive="true"] .urlbar,
.urlbar:not([focused])[textoverflow="left"][domaindir="rtl"] > .urlbar-input-container > .urlbar-input-box > & {
mask-image: linear-gradient(to right, transparent var(--urlbar-scheme-size), black calc(var(--urlbar-scheme-size) + 3ch));
}
+
+ #navigator-toolbox[zen-has-implicit-hover="true"] .urlbar:not([focused])[textoverflow="left"] > .urlbar-input-container > .urlbar-input-box > & {
+ mask-image: linear-gradient(to right, transparent, black 3ch, black calc(100% - 3ch), transparent);
+ }
}
#urlbar-scheme {
@@ -333,10 +337,14 @@ toolbar[inactive="true"] .urlbar,
.urlbar[breakout][breakout-extend] {
height: auto;

View File

@@ -385,12 +385,12 @@ diff --git a/widget/cocoa/nsCocoaWindow.mm b/widget/cocoa/nsCocoaWindow.mm
+ preferredEdge:preferredEdge
+ hiddenAnchor:shouldHideAnchor];
+ SyncPopoverBounds([(PopupWindow*)mWindow popover], popupFrame);
+ if (mPopupLevel == PopupLevel::Parent) {
+ [nativeParentWindow addChildWindow:mWindow ordered:NSWindowAbove];
+ }
+
+
+
+
+ // Exit early here since the popover is now shown.
+ mWindow.isBeingShown = NO;
+
+ return;
+ }
// If our popup window is a non-native context menu, tell the OS (and

View File

@@ -0,0 +1,51 @@
diff --git a/widget/cocoa/nsCocoaWindow.h b/widget/cocoa/nsCocoaWindow.h
--- a/widget/cocoa/nsCocoaWindow.h
+++ b/widget/cocoa/nsCocoaWindow.h
@@ -140,10 +140,11 @@
// NSPopover support for native appearance
NSPopover* mPopover;
NSViewController* mPopoverViewController;
BOOL mUsePopover;
+ NSRect mLastPopoverRect;
}
- (id)initWithContentRect:(NSRect)contentRect
styleMask:(NSUInteger)styleMask
backing:(NSBackingStoreType)bufferingType
diff --git a/widget/cocoa/nsCocoaWindow.mm b/widget/cocoa/nsCocoaWindow.mm
--- a/widget/cocoa/nsCocoaWindow.mm
+++ b/widget/cocoa/nsCocoaWindow.mm
@@ -5597,11 +5597,10 @@
return false;
}
nsMenuPopupFrame* popupFrame = GetPopupFrame();
return [mWindow isKindOfClass:[PopupWindow class]] &&
[(PopupWindow*)mWindow usePopover] && popupFrame &&
- popupFrame->ShouldFollowAnchor() &&
!popupFrame->PopupElement().GetBoolAttr(nsGkAtoms::nonnativepopover);
}
TransparencyMode nsCocoaWindow::GetTransparencyMode() {
NS_OBJC_BEGIN_TRY_BLOCK_RETURN;
@@ -8775,10 +8774,19 @@
NS_OBJC_BEGIN_TRY_IGNORE_BLOCK;
if (!mPopover) {
return;
}
+ if (!positioningRect.size.width && !positioningRect.size.height &&
+ mLastPopoverRect.size.width && mLastPopoverRect.size.height) {
+ // Sometimes, specially when downloading addons from unofficial sources,
+ // the popover is shown in a very fast motion and the positioningRect is
+ // empty.
+ positioningRect = mLastPopoverRect;
+ }
+ mLastPopoverRect = positioningRect;
+
// Close existing popover if it's already shown
if (mPopover.shown) {
[mPopover close];
}

View File

@@ -4,7 +4,10 @@
[
{
"type": "phabricator",
"id": "D284084",
"ids": [
"D284084",
"D299584"
],
"name": "Native MacOS popovers",
"replaces": {
// Specifically trying to target FeatureCallout.sys.mjs's change.
@@ -22,7 +25,9 @@
" #include \"nsISupportsPrimitives.h\"\n": "",
" Atom(\"nonnative\", \"nonnative\"),\n": "",
"Atom(\"noscript\", \"noscript\"),": "Atom(\"noscript\", \"noscript\"),\n Atom(\"noshade\", \"noshade\"),"
"Atom(\"noscript\", \"noscript\"),": "Atom(\"noscript\", \"noscript\"),\n Atom(\"noshade\", \"noshade\"),",
"GetBoolAttr(nsGkAtoms::nonnative)": "GetBoolAttr(nsGkAtoms::nonnativepopover)"
}
},
{

View File

@@ -1,5 +1,5 @@
diff --git a/widget/SwipeTracker.cpp b/widget/SwipeTracker.cpp
index 887d06d3bd9cdaa934880e0ae7a11ec8b737fb61..e2bf27c0130701f1d50990b60a5ef76e93c5a6bf 100644
index 887d06d3bd9cdaa934880e0ae7a11ec8b737fb61..979f93ddab0d661ac1a1d73e7a0ba27fa2c8f9b7 100644
--- a/widget/SwipeTracker.cpp
+++ b/widget/SwipeTracker.cpp
@@ -3,6 +3,7 @@
@@ -10,7 +10,25 @@ index 887d06d3bd9cdaa934880e0ae7a11ec8b737fb61..e2bf27c0130701f1d50990b60a5ef76e
#include "InputData.h"
#include "mozilla/FlushType.h"
@@ -90,7 +91,7 @@ bool SwipeTracker::ComputeSwipeSuccess() const {
@@ -67,6 +68,9 @@ double SwipeTracker::SwipeSuccessTargetValue() const {
}
double SwipeTracker::ClampToAllowedRange(double aGestureAmount) const {
+ if (StaticPrefs::zen_swipe_is_fast_swipe()) {
+ return aGestureAmount;
+ }
// gestureAmount needs to stay between -1 and 0 when swiping right and
// between 0 and 1 when swiping left.
double min =
@@ -84,13 +88,14 @@ bool SwipeTracker::ComputeSwipeSuccess() const {
// If the fingers were moving away from the target direction when they were
// lifted from the touchpad, abort the swipe.
if (mCurrentVelocity * targetValue <
- -StaticPrefs::widget_swipe_velocity_twitch_tolerance()) {
+ -StaticPrefs::widget_swipe_velocity_twitch_tolerance()
+ && !StaticPrefs::zen_swipe_is_fast_swipe()) {
return false;
}
return (mGestureAmount * targetValue +
mCurrentVelocity * targetValue *
@@ -19,3 +37,13 @@ index 887d06d3bd9cdaa934880e0ae7a11ec8b737fb61..e2bf27c0130701f1d50990b60a5ef76e
kSwipeSuccessThreshold;
}
@@ -141,7 +146,8 @@ nsEventStatus SwipeTracker::ProcessEvent(
// display the UI as if we were at the success threshold as that would
// give a false indication that navigation would happen.
if (!computedSwipeSuccess && (eventAmount >= kSwipeSuccessThreshold ||
- eventAmount <= -kSwipeSuccessThreshold)) {
+ eventAmount <= -kSwipeSuccessThreshold)
+ && !StaticPrefs::zen_swipe_is_fast_swipe()) {
eventAmount = 0.999 * kSwipeSuccessThreshold;
if (mGestureAmount < 0.f) {
eventAmount = -eventAmount;

View File

@@ -92,7 +92,7 @@ export class nsZenMenuBar {
key="zen-workspace-forward"/>
<menuitem
data-l10n-id="zen-panel-ui-workspaces-change-back"
command="cmd_zenWorkspaceBack"
command="cmd_zenWorkspaceBackward"
key="zen-workspace-backward"/>
</menupopup>
</menu>`);

View File

@@ -698,11 +698,6 @@ window.gZenUIManager = {
this.urlbarShowDomainOnly
) {
let url = BrowserUIUtils.removeSingleTrailingSlashFromURL(aURL);
requestIdleCallback(() => {
// Scroll the urlbar all the way to the right so that
// the domain is always visible when the url is too long.
gURLBar.inputField.scrollLeft = gURLBar.inputField.scrollWidth;
});
let stripped = url.startsWith("https://") ? url.split("/")[2] : url;
if (stripped.startsWith("www.")) {
stripped = stripped.substring(4);

View File

@@ -45,6 +45,7 @@ body,
overflow: clip;
isolation: isolate;
contain: content;
&::after,
&::before {
@@ -53,6 +54,7 @@ body,
inset: 0;
z-index: 0;
pointer-events: none;
will-change: background-color;
}
&::after {
@@ -106,8 +108,6 @@ body,
}
#zen-browser-background {
contain: paint;
/* This is conceptually a background, but putting this on a pseudo-element
* avoids it from suppressing the chrome-content separator border, etc.
*

View File

@@ -120,6 +120,7 @@
#urlbar .urlbar-input {
border-radius: 0 !important;
color: color-mix(in srgb, var(--input-color, FieldText) 70%, transparent);
}
#urlbar .urlbar-input-box {

View File

@@ -4,48 +4,55 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
#zen-overflow-extensions-list:not(:empty) {
--uei-icon-size: 14px;
display: grid;
gap: 8px;
padding: 8px 2px;
padding-bottom: 0;
border-radius: calc(var(--border-radius-medium) - 4px);
grid-template-columns: repeat(auto-fit, minmax(32px, 1fr));
#zen-overflow-extensions-list {
display: none;
& .unified-extensions-item {
flex: 1;
margin: 0;
}
:root[zen-single-toolbar="true"] &:not(:empty) {
--uei-icon-size: 14px;
display: grid;
gap: 8px;
padding: 8px 2px;
padding-bottom: 0;
border-radius: calc(var(--border-radius-medium) - 4px);
grid-template-columns: repeat(auto-fit, minmax(32px, 1fr));
& .toolbarbutton-badge-stack {
margin: 0;
width: 100%;
height: 100%;
padding: 8px 0;
justify-content: center;
align-items: center;
}
& .unified-extensions-item {
flex: 1;
margin: 0;
}
& .unified-extensions-item-action-button {
appearance: none;
background-color: var(--zen-toolbar-element-bg);
height: 30px;
margin: 0;
justify-content: center;
align-items: center;
border-radius: var(--border-radius-medium);
overflow: clip;
padding: 0;
& .toolbarbutton-badge-stack {
margin: 0;
width: 100%;
height: 100%;
justify-content: center;
align-items: center;
}
&:hover {
background-color: var(--zen-toolbar-element-bg-hover);
& .unified-extensions-item-action-button {
appearance: none;
background-color: var(--zen-toolbar-element-bg);
height: 26px;
margin: 0;
justify-content: center;
align-items: center;
border-radius: calc(var(--border-radius-medium) - 2px);
overflow: visible;
padding: 0;
&:hover {
background-color: var(--zen-toolbar-element-bg-hover);
}
& .toolbarbutton-badge {
transform: translate(4px, 2px);
}
}
.unified-extensions-item-contents,
.unified-extensions-item-menu-button,
unified-extensions-item-messagebar-wrapper {
display: none;
}
}
.unified-extensions-item-contents,
.unified-extensions-item-menu-button,
unified-extensions-item-messagebar-wrapper {
display: none;
}
}

View File

@@ -739,17 +739,13 @@
--zen-loading-progress-bar-color: color-mix(in srgb, var(--zen-primary-color), light-dark(rgba(0, 0, 0, 0.5), rgba(255, 255, 255, 0.5)) 70%);
position: fixed;
top: calc(-2px - env(hairline));
top: calc(var(--zen-element-separation) / -2);
/* Minimum -2px, but if its larger, elemenet separation / -2 will be used as top offset, to avoid overlapping with the notification stack */
:root:is([zen-no-padding="true"], [inDOMFullscreen="true"]) & {
:root:is([zen-no-padding="true"], [inDOMFullscreen="true"], :not([zen-single-toolbar="true"])) & {
top: 4px;
}
:root[zen-single-toolbar="true"] & {
top: calc(var(--zen-element-separation) / -2);
}
left: 50%;
transform: translate(-50%, -50%) scale(0);
background: var(--zen-loading-progress-bar-color);

View File

@@ -313,16 +313,18 @@ class nsZenGlanceManager extends nsZenDOMOperatedFeature {
// content process since it does not take into account scroll. This way, we can
// be sure that the coordinates are correct.
const tabPanelsRect = gBrowser.tabpanels.getBoundingClientRect();
const zoomLevel =
this.#currentParentTab?.linkedBrowser.browsingContext.fullZoom || 1;
const rect = new DOMRect(
data.clientX + tabPanelsRect.left,
data.clientY + tabPanelsRect.top,
data.width,
data.height
data.clientX / zoomLevel + tabPanelsRect.left,
data.clientY / zoomLevel + tabPanelsRect.top,
data.width / zoomLevel,
data.height / zoomLevel
);
return await this.#imageBitmapToObjectURL(
await window.browsingContext.currentWindowGlobal.drawSnapshot(
rect,
1,
zoomLevel,
"transparent",
undefined
)

View File

@@ -66,11 +66,13 @@ export class ZenGlanceChild extends JSWindowActorChild {
) {
rect = originalTargetRect;
}
// Change the rect to make sure we take into account zoom.
const zoom = this.browsingContext.fullZoom;
this.sendAsyncMessage("ZenGlance:RecordLinkClickData", {
clientX: rect.left,
clientY: rect.top,
width: rect.width,
height: rect.height,
clientX: rect.left * zoom,
clientY: rect.top * zoom,
width: rect.width * zoom,
height: rect.height * zoom,
});
}

View File

@@ -137,8 +137,6 @@ class nsZenWorkspaces {
document.documentElement.setAttribute("zen-private-window", "true");
}
this.popupOpenHandler = this._popupOpenHandler.bind(this);
window.addEventListener("resize", this.onWindowResize.bind(this));
this.addPopupListeners();
@@ -599,16 +597,6 @@ class nsZenWorkspaces {
);
}
_popupOpenHandler() {
// If a popup is opened, we should stop the swipe gesture
if (this._swipeManager?.isGestureActive) {
document.documentElement.removeAttribute("swipe-gesture");
gZenUIManager.tabsWrapper.style.removeProperty("scrollbar-width");
this.updateTabsContainers();
this._cancelSwipeAnimation();
}
}
get activeWorkspace() {
return this.#activeWorkspace;
}
@@ -828,14 +816,12 @@ class nsZenWorkspaces {
let removedEmptyTab = false;
let initialTabWasEmpty = false;
if (
this._initialTab &&
!(this._initialTab._shouldRemove && this._initialTab._veryPossiblyEmpty)
) {
initialTabWasEmpty = !!this._initialTab._veryPossiblyEmpty;
gBrowser.selectedTab = this._initialTab;
this.moveTabToWorkspace(this._initialTab, this.activeWorkspace);
gBrowser.moveTabTo(this._initialTab, {
if (this._shouldOverrideTabs) {
let initialTab = this._initialTab || gBrowser.selectedTab;
initialTabWasEmpty = !!initialTab._veryPossiblyEmpty;
gBrowser.selectedTab = initialTab;
this.moveTabToWorkspace(initialTab, this.activeWorkspace);
gBrowser.moveTabTo(initialTab, {
forceUngrouped: true,
tabIndex: 0,
});
@@ -1907,7 +1893,9 @@ class nsZenWorkspaces {
} = {}
) {
gZenUIManager.tabsWrapper.style.scrollbarWidth = "none";
const kGlobalAnimationDuration = 0.2;
const kGlobalAnimationDuration =
Services.prefs.getIntPref("zen.workspaces.switch-animation-duration") /
1000;
this._animatingChange = true;
const animations = [];
const workspaces = this.getWorkspaces();
@@ -1995,26 +1983,41 @@ class nsZenWorkspaces {
);
const offset = -(newWorkspaceIndex - elementWorkspaceIndex) * 100;
const newTransform = `translateX(${offset}%)`;
// Only animate the workspace that is coming in, to avoid having multiple workspaces
// animating off-screen at the same time which can cause performance issues. With an off
// set of 1 or -1, so we animate the current workspace and the next one.
const goingLeft = newWorkspaceIndex < previousWorkspaceIndex;
const willBeVisible =
(goingLeft &&
elementWorkspaceIndex >= newWorkspaceIndex &&
elementWorkspaceIndex <= previousWorkspaceIndex) ||
(!goingLeft &&
elementWorkspaceIndex <= newWorkspaceIndex &&
elementWorkspaceIndex >= previousWorkspaceIndex);
if (shouldAnimate) {
const existingPaddingTop = element.style.paddingTop;
animations.push(
gZenUIManager.motion.animate(
element,
{
transform: existingTransform
? [existingTransform, newTransform]
: newTransform,
paddingTop: existingTransform
? [existingPaddingTop, existingPaddingTop]
: existingPaddingTop,
},
{
type: "spring",
bounce: 0,
duration: kGlobalAnimationDuration,
}
)
);
if (!willBeVisible) {
element.style.transform = newTransform;
} else {
const existingPaddingTop = element.style.paddingTop;
animations.push(
gZenUIManager.motion.animate(
element,
{
transform: existingTransform
? [existingTransform, newTransform]
: newTransform,
paddingTop: existingTransform
? [existingPaddingTop, existingPaddingTop]
: existingPaddingTop,
},
{
type: "spring",
bounce: 0,
duration: kGlobalAnimationDuration,
}
)
);
}
}
element.active = offset === 0;
if (offset === 0) {

View File

@@ -20,24 +20,22 @@ export class ZenSpacesSwipe {
};
constructor() {
const elements = [
gNavToolbox,
// Event handlers do not work on elements inside shadow DOM
// so we need to attach them directly.
document
.getElementById("tabbrowser-arrowscrollbox")
?.shadowRoot?.querySelector("scrollbox"),
];
for (const element of elements) {
if (!element) {
continue;
}
this._attachWorkspaceSwipeGestures(element);
}
this.#attachWorkspaceSwipeGestures(gNavToolbox);
this._popupOpenHandler = this._popupOpenHandler.bind(this);
}
_attachWorkspaceSwipeGestures(element) {
get #stripWidth() {
return (
window.windowUtils.getBoundsWithoutFlushing(
document.getElementById("navigator-toolbox")
).width +
window.windowUtils.getBoundsWithoutFlushing(
document.getElementById("zen-sidebar-splitter")
).width
);
}
#attachWorkspaceSwipeGestures(element) {
element.addEventListener(
"MozSwipeGestureMayStart",
this._handleSwipeMayStart.bind(this),
@@ -107,7 +105,7 @@ export class ZenSpacesSwipe {
gZenFolders.cancelPopupTimer();
document.documentElement.setAttribute("swipe-gesture", "true");
document.addEventListener("popupshown", ws.popupOpenHandler, {
document.addEventListener("popupshown", this._popupOpenHandler, {
once: true,
});
@@ -128,17 +126,16 @@ export class ZenSpacesSwipe {
return;
}
const stripWidth = this.#stripWidth;
event.preventDefault();
event.stopPropagation();
const stripWidth =
window.windowUtils.getBoundsWithoutFlushing(
document.getElementById("navigator-toolbox")
).width +
window.windowUtils.getBoundsWithoutFlushing(
document.getElementById("zen-sidebar-splitter")
).width;
const delta = event.delta * stripWidth;
const delta =
event.delta *
Services.prefs.getIntPref(
"zen.workspaces.swipe-actions.delta-multiplier"
);
let translateX = this._swipeState.lastDelta + delta;
// Add a force multiplier as we are translating the strip depending on how close to the edge we are
let forceMultiplier = Math.min(
@@ -152,7 +149,8 @@ export class ZenSpacesSwipe {
translateX = this._swipeState.lastDelta;
}
if (Math.abs(delta) > 0.8) {
if (Math.abs(delta) > 0.9) {
delete ws._hasAnimatedBackgrounds;
this._swipeState.direction = delta > 0 ? "left" : "right";
}
@@ -176,6 +174,10 @@ export class ZenSpacesSwipe {
const rawDirection = moveForward ? 1 : -1;
const direction = ws.naturalScroll ? -1 : 1;
await ws.changeWorkspaceShortcut(rawDirection * direction, true);
}
onSwipeGestureAnimationEnd() {
const ws = gZenWorkspaces;
// Reset swipe state
this._swipeState = {
@@ -183,10 +185,6 @@ export class ZenSpacesSwipe {
lastDelta: 0,
direction: null,
};
}
onSwipeGestureAnimationEnd() {
const ws = gZenWorkspaces;
Services.prefs.setBoolPref("zen.swipe.is-fast-swipe", false);
document.documentElement.removeAttribute("swipe-gesture");
@@ -198,11 +196,15 @@ export class ZenSpacesSwipe {
);
delete ws._hasAnimatedBackgrounds;
ws.updateTabsContainers();
document.removeEventListener("popupshown", ws.popupOpenHandler, {
document.removeEventListener("popupshown", this._popupOpenHandler, {
once: true,
});
}
_popupOpenHandler() {
this.onSwipeGestureAnimationEnd();
}
get isGestureActive() {
return this._swipeState?.isGestureActive;
}

View File

@@ -11,7 +11,6 @@
align-items: center;
display: flex;
font-size: x-small;
margin: 0 3px;
padding: 0;
position: relative;
@@ -321,6 +320,7 @@ zen-workspace {
height: 100%;
overflow: hidden;
color: var(--toolbox-textcolor);
will-change: transform;
@media not (prefers-reduced-motion: reduce) {
transition: padding-top 0.1s;
@@ -346,8 +346,12 @@ zen-workspace {
overflow-y: auto;
}
:root[swipe-gesture] &::part(scrollbox) {
scrollbar-width: none;
:root[swipe-gesture] &{
pointer-events: none;
&::part(scrollbox) {
scrollbar-width: none;
}
}
&[overflowing] {

View File

@@ -969,19 +969,14 @@ class nsZenViewSplitter extends nsZenDOMOperatedFeature {
};
_oppositeSide(side) {
if (side === "top") {
return "bottom";
}
if (side === "bottom") {
return "top";
}
if (side === "left") {
return "right";
}
if (side === "right") {
return "left";
}
return undefined;
const OPPOSITE_SIDES = {
top: "bottom",
bottom: "top",
left: "right",
right: "left",
};
return OPPOSITE_SIDES[side];
}
calculateHoverSide(x, y, elementRect) {

View File

@@ -335,7 +335,7 @@
#tabbrowser-tabs:not([movingtab])
&:active:not(:has(.tab-content > image:active)) {
scale: var(--zen-active-tab-scale);
rotate: 0.02deg; /* Subtle rotation to trigger GPU acceleration and prevent blurriness */
rotate: 0.01deg; /* Subtle rotation to trigger GPU acceleration and prevent blurriness */
}
:root:not([zen-renaming-tab="true"])
@@ -1131,6 +1131,7 @@
transition:
max-height 0.3s ease-out,
grid-template-columns 0.3s ease-out;
will-change: transform;
opacity: 1;
--min-essentials-width-wrap: calc(var(--tab-min-height) + 4px);
grid-template-columns: repeat(auto-fit, minmax(max(23.7%, var(--min-essentials-width-wrap)), 1fr));
@@ -1325,6 +1326,7 @@
padding: 0;
outline: none !important;
border-radius: 0;
width: 100%;
}
/* ==========================================================================

View File

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