/"
+ type = "benchmark"
+ unit = "score"
+ support_class = "jetstream3.py"
+ repository = "https://github.com/webkit/jetstream"
++# Keep this in sync with the version used in PGO instrumentation by updating
++# `taskcluster/kinds/fetch/benchmarks.yml`.
+ repository_revision = "a3f5c45465f5271bed385321a0587bd4202682d6"
+ test_script = "jetstream3.js"
+
+ ["jetstream3"]
+ suite_name = "JetStream3.0"
+
diff --git a/src/external-patches/firefox/ff150_2_pgo_patch_for_bug-2011620.patch b/src/external-patches/firefox/ff150_2_pgo_patch_for_bug-2011620.patch
new file mode 100644
index 000000000..da9579a02
--- /dev/null
+++ b/src/external-patches/firefox/ff150_2_pgo_patch_for_bug-2011620.patch
@@ -0,0 +1,409 @@
+diff --git a/build/pgo/index.html b/build/pgo/index.html
+--- a/build/pgo/index.html
++++ b/build/pgo/index.html
+@@ -10,10 +10,11 @@
+ "blueprint/forms.html",
+ "blueprint/grid.html",
+ "blueprint/sample.html",
+ "js-input/3d-thingy.html",
+ "js-input/crypto-otp.html",
++ "js-input/normalizer_bench.html",
+ "js-input/sunspider/3d-cube.html",
+ "js-input/sunspider/3d-morph.html",
+ "js-input/sunspider/3d-raytrace.html",
+ "js-input/sunspider/access-binary-trees.html",
+ "js-input/sunspider/access-fannkuch.html",
+diff --git a/build/pgo/js-input/normalizer_bench.html b/build/pgo/js-input/normalizer_bench.html
+new file mode 100644
+--- /dev/null
++++ b/build/pgo/js-input/normalizer_bench.html
+@@ -0,0 +1,358 @@
++
++
++
++
++Normalizer bench
++
++Normalizer Bench
++
++ - S
++ - Short: NFD fits in 32 UTF-16 code units. French and German are adjusted to take a substring that contains a non-ASCII character. (Long input contains the same information in each language instead of having a fixed UTF-16 length.)
++ - L
++ - Latin1.
++ - U
++ - Forced UTF-16 form for Latin1 languages. (One non-Latin1 character added to the string.)
++ - W
++ - Forced write: In the UTF-16 case, a singleton is prepended to force the normalizer to start writing from the start. In the Latin1 case, a character with a compatibility decomposition is prepended, since there are no singletons in Latin1. This means the effect is seen only in the K forms.
++ - C
++ - Forced copy: In the UTF-16 case, a singleton is appended to force the normalizer to make a copy even when normalizing from NFC to a C form or from NFD to a D form. In the Latin1 case, a character with a compatibility decomposition is appended, since there are no singletons in Latin1. This means the effect is seen only in the K form corresponding to the input C or D form.
++
++
++Bench not started.
++
++
++| Input | NFC | NFKC | NFD | NFKD |
++| Bench not run. |
++
++
++
++
+diff --git a/testing/mozharness/scripts/android_emulator_pgo.py b/testing/mozharness/scripts/android_emulator_pgo.py
+--- a/testing/mozharness/scripts/android_emulator_pgo.py
++++ b/testing/mozharness/scripts/android_emulator_pgo.py
+@@ -28,10 +28,11 @@
+ "blueprint/forms.html",
+ "blueprint/grid.html",
+ "blueprint/elements.html",
+ "js-input/3d-thingy.html",
+ "js-input/crypto-otp.html",
++ "js-input/normalizer_bench.html",
+ "js-input/sunspider/3d-cube.html",
+ "js-input/sunspider/3d-morph.html",
+ "js-input/sunspider/3d-raytrace.html",
+ "js-input/sunspider/access-binary-trees.html",
+ "js-input/sunspider/access-fannkuch.html",
+diff --git a/toolkit/content/license.html b/toolkit/content/license.html
+--- a/toolkit/content/license.html
++++ b/toolkit/content/license.html
+@@ -5786,10 +5786,11 @@
+ third_party/rust/yoke-derive
+ third_party/rust/zerofrom
+ third_party/rust/zerofrom-derive
+ third_party/rust/zerovec
+ third_party/rust/zerovec-derive
++ build/pgo/js-input/normalizer_bench.html
+
+
+
+
+ UNICODE LICENSE V3
+
diff --git a/src/external-patches/firefox/ff150_3_pgo_patch_for_bug-2014422.patch b/src/external-patches/firefox/ff150_3_pgo_patch_for_bug-2014422.patch
new file mode 100644
index 000000000..99add604c
--- /dev/null
+++ b/src/external-patches/firefox/ff150_3_pgo_patch_for_bug-2014422.patch
@@ -0,0 +1,868 @@
+diff --git a/build/pgo/index.html b/build/pgo/index.html
+--- a/build/pgo/index.html
++++ b/build/pgo/index.html
+@@ -49,10 +49,11 @@
+ "blueprint/forms.html",
+ "blueprint/grid.html",
+ "blueprint/sample.html",
+ "js-input/3d-thingy.html",
+ "js-input/crypto-otp.html",
++ "js-input/collator_bench.html",
+ "js-input/normalizer_bench.html",
+ "js-input/sunspider/3d-cube.html",
+ "js-input/sunspider/3d-morph.html",
+ "js-input/sunspider/3d-raytrace.html",
+ "js-input/sunspider/access-binary-trees.html",
+diff --git a/build/pgo/js-input/collator_bench.html b/build/pgo/js-input/collator_bench.html
+new file mode 100644
+--- /dev/null
++++ b/build/pgo/js-input/collator_bench.html
+@@ -0,0 +1,817 @@
++
++
++
++
++Collator bench
++
++Collator Bench
++
++Bench not started.
++
++
++| Workload | Time |
++| Bench not run. |
++
++
++
++
++
+diff --git a/testing/mozharness/scripts/android_emulator_pgo.py b/testing/mozharness/scripts/android_emulator_pgo.py
+--- a/testing/mozharness/scripts/android_emulator_pgo.py
++++ b/testing/mozharness/scripts/android_emulator_pgo.py
+@@ -29,10 +29,11 @@
+ "blueprint/forms.html",
+ "blueprint/grid.html",
+ "blueprint/elements.html",
+ "js-input/3d-thingy.html",
+ "js-input/crypto-otp.html",
++ "js-input/collator_bench.html",
+ "js-input/normalizer_bench.html",
+ "js-input/sunspider/3d-cube.html",
+ "js-input/sunspider/3d-morph.html",
+ "js-input/sunspider/3d-raytrace.html",
+ "js-input/sunspider/access-binary-trees.html",
+diff --git a/toolkit/content/license.html b/toolkit/content/license.html
+--- a/toolkit/content/license.html
++++ b/toolkit/content/license.html
+@@ -5788,10 +5788,11 @@
+ third_party/rust/zerofrom
+ third_party/rust/zerofrom-derive
+ third_party/rust/zerovec
+ third_party/rust/zerovec-derive
+ build/pgo/js-input/normalizer_bench.html
++ build/pgo/js-input/collator_bench.html
+
+ |
+
+
+ UNICODE LICENSE V3
+
diff --git a/src/external-patches/manifest.json b/src/external-patches/manifest.json
index 91c2934ab..ff81da911 100644
--- a/src/external-patches/manifest.json
+++ b/src/external-patches/manifest.json
@@ -40,5 +40,20 @@
"type": "phabricator",
"id": "D291714",
"name": "gh-12979 Clip dirty_rect to device_size"
+ },
+ {
+ "type": "phabricator",
+ "id": "D256645",
+ "name": "FF150 1 PGO patch for bug-1962418"
+ },
+ {
+ "type": "phabricator",
+ "id": "D279829",
+ "name": "FF150 2 PGO patch for bug-2011620"
+ },
+ {
+ "type": "phabricator",
+ "id": "D281762",
+ "name": "FF150 3 PGO patch for bug-2014422"
}
]
diff --git a/src/zen/common/sys/ZenActorsManager.sys.mjs b/src/zen/common/sys/ZenActorsManager.sys.mjs
index 6595d55ee..3f1404557 100644
--- a/src/zen/common/sys/ZenActorsManager.sys.mjs
+++ b/src/zen/common/sys/ZenActorsManager.sys.mjs
@@ -54,7 +54,7 @@ let JSWINDOWACTORS = {
},
},
allFrames: true,
- matches: ["*://*/*"],
+ remoteTypes: ["web", "file"],
enablePreference: "zen.glance.enabled",
},
};
From 4add28d3c026d1f2d30dfe8bed1d22f660491f44 Mon Sep 17 00:00:00 2001
From: CosmoCreeper <179134799+CosmoCreeper@users.noreply.github.com>
Date: Thu, 9 Apr 2026 16:46:47 -0400
Subject: [PATCH 65/72] no-bug: Remove non-existent hooks property (gh-13160)
Co-authored-by: mr. m <91018726+mr-cheffy@users.noreply.github.com>
---
package.json | 4 ----
1 file changed, 4 deletions(-)
diff --git a/package.json b/package.json
index a9d156ad1..f5dff7d7a 100644
--- a/package.json
+++ b/package.json
@@ -23,7 +23,6 @@
"sync:l10n": "python3 scripts/update_ff.py --just-l10n",
"lint": "cd engine && ./mach lint zen",
"lint:fix": "npm run lint -- --fix",
- "prepare": "husky",
"reset-ff": "surfer reset",
"surfer": "surfer",
"test": "python3 scripts/run_tests.py",
@@ -38,9 +37,6 @@
"type": "git",
"url": "git+https://github.com/zen-browser/desktop.git"
},
- "hooks": {
- "pre-commit": "npm run prepare"
- },
"keywords": [],
"author": "",
"license": "MPL-2.0",
From dfc47ee5d746e9f0e77544ccc65edcf5ff5382df Mon Sep 17 00:00:00 2001
From: DQSS
Date: Thu, 9 Apr 2026 22:51:24 +0200
Subject: [PATCH 66/72] gh-12241: fix skip startup bookmark invalidation when
no workspace bookmarks exist (gh-13168)
---
src/zen/spaces/ZenSpaceManager.mjs | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/src/zen/spaces/ZenSpaceManager.mjs b/src/zen/spaces/ZenSpaceManager.mjs
index d1f6a609d..53dcf5bed 100644
--- a/src/zen/spaces/ZenSpaceManager.mjs
+++ b/src/zen/spaces/ZenSpaceManager.mjs
@@ -2469,8 +2469,14 @@ class nsZenWorkspaces {
}
}
- // Reset bookmarks
- this.#invalidateBookmarkContainers();
+ // Avoid forcing a startup toolbar rebuild when there are no
+ // workspace-specific bookmark assignments to apply.
+ const hasWorkspaceBookmarks = !!Object.keys(
+ this._workspaceBookmarksCache?.bookmarks || {}
+ ).length;
+ if (!onInit || hasWorkspaceBookmarks) {
+ this.#invalidateBookmarkContainers();
+ }
// Update workspace indicator
await this.updateWorkspaceIndicator(workspace, this.workspaceIndicator);
From 000098adb1a8af279c274e3f00cbc71a7ecc4b04 Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Thu, 9 Apr 2026 23:40:53 +0200
Subject: [PATCH 67/72] no-bug: bump axios from 1.13.6 to 1.15.0 in the
npm_and_yarn group across 1 directory (gh-13187)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Bumps the npm_and_yarn group with 1 update in the / directory:
[axios](https://github.com/axios/axios).
Updates `axios` from 1.13.6 to 1.15.0
Release notes
Sourced from axios's
releases.
v1.15.0
This release delivers two critical security patches, adds runtime
support for Deno and Bun, and includes significant CI hardening,
documentation improvements, and routine dependency updates.
⚠️ Important Changes
- Deprecation:
url.parse() usage has
been replaced to address Node.js deprecation warnings. If you are on a
recent version of Node.js, this resolves console warnings you may have
been seeing. (#10625)
🔒 Security Fixes
- Proxy Handling: Fixed a
no_proxy
hostname normalisation bypass that could lead to Server-Side Request
Forgery (SSRF). (#10661)
- Header Injection: Fixed an unrestricted cloud
metadata exfiltration vulnerability via a header injection chain.
(#10660)
🚀 New Features
- Runtime Support: Added compatibility checks and
documentation for Deno and Bun environments. (#10652,
#10653)
🔧 Maintenance & Chores
- CI Security: Hardened workflow permissions to least
privilege, added the
zizmor security scanner, pinned action
versions, and gated npm publishing with OIDC and environment protection.
(#10618,
#10619,
#10627,
#10637,
#10666)
- Dependencies: Bumped
serialize-javascript, handlebars,
picomatch, vite, and
denoland/setup-deno to latest versions. Added a 7-day
Dependabot cooldown period. (#10574,
#10572,
#10568,
#10663,
#10664,
#10665,
#10669,
#10670,
#10616)
- Documentation: Unified docs, improved
beforeRedirect credential leakage example, clarified
withCredentials/withXSRFToken behaviour,
HTTP/2 support notes, async/await timeout error handling, header case
preservation, and various typo fixes. (#10649,
#10624,
#7452,
#7471,
#10654,
#10644,
#10589)
- Housekeeping: Removed stale files, regenerated
lockfile, and updated sponsor scripts and blocks. (#10584,
#10650,
#10582,
#10640,
#10659,
#10668)
- Tests: Added regression coverage for urlencoded
Content-Type casing. (#10573)
🌟 New Contributors
We are thrilled to welcome our new contributors. Thank you for
helping improve Axios:
v1.14.0
This release focuses on compatibility fixes, adapter stability
improvements, and test/tooling modernisation.
⚠️ Important Changes
- Breaking Changes: None identified in this
release.
- Action Required: If you rely on env-based proxy
behaviour or CJS resolution edge-cases, validate your integration after
upgrade (notably
proxy-from-env v2 alignment and
main entry compatibility fix).
🚀 New Features
- Runtime Features: No new end-user features were
introduced in this release.
- Test Coverage Expansion: Added broader smoke/module
test coverage for CJS and ESM package usage. (#7510)
🐛 Bug Fixes
- Headers: Trim trailing CRLF in normalised header
values. (#7456)
- HTTP/2: Close detached HTTP/2 sessions on timeout
to avoid lingering sessions. (#7457)
- Fetch Adapter: Cancel
ReadableStream
created during request-stream capability probing to prevent async
resource leaks. (#7515)
- Proxy Handling: Fixed env proxy behavior with
proxy-from-env v2 usage. (#7499)
... (truncated)
Changelog
Sourced from axios's
changelog.
Changelog
1.13.3
(2026-01-20)
Bug Fixes
- http2: Use port 443 for HTTPS connections by
default. (#7256)
(d7e6065)
- interceptor: handle the error in the same
interceptor (#6269)
(5945e40)
- main field in package.json should correspond to cjs artifacts (#5756)
(7373fbf)
- package.json: add 'bun' package.json 'exports'
condition. Load the Node.js build in Bun instead of the browser build
(#5754)
(b89217e)
- silentJSONParsing=false should throw on invalid JSON (#7253)
(#7257)
(7d19335)
- turn AxiosError into a native error (#5394)
(#5558)
(1c6a86d)
- types: add handlers to AxiosInterceptorManager
interface (#5551)
(8d1271b)
- types: restore AxiosError.cause type from unknown
to Error (#7327)
(d8233d9)
- unclear error message is thrown when specifying an empty proxy
authorization (#6314)
(6ef867e)
Features
Reverts
- Revert "fix: silentJSONParsing=false should throw on invalid
JSON (#7253)
(#7…"
(#7298)
(a4230f5),
closes #7253 #7 #7298
- deps: bump peter-evans/create-pull-request from 7
to 8 in the github-actions group (#7334)
(2d6ad5e)
Contributors to this release
... (truncated)
Commits
772a4e5
chore(release): prepare release 1.15.0 (#10671)
4b07137
chore(deps-dev): bump vite from 8.0.0 to 8.0.5 in /tests/smoke/esm (#10663)
51e57b3
chore(deps-dev): bump vite from 8.0.2 to 8.0.5 (#10664)
fba1a77
chore(deps-dev): bump vite from 8.0.2 to 8.0.5 in /tests/module/esm (#10665)
0bf6e28
chore(deps): bump denoland/setup-deno in the github-actions group (#10669)
8107157
chore(deps-dev): bump the development_dependencies group with 4 updates
(#10670)
e66530e
ci: require npm-publish environment for releases (#10666)
49f23cb
chore(sponsor): update sponsor block (#10668)
3631854
fix: unrestricted cloud metadata exfiltration via header injection chain
(#10...
fb3befb
fix: no_proxy hostname normalization bypass leads to ssrf (#10661)
- Additional commits viewable in compare
view
Install script changes
This version modifies prepare script that runs during
installation. Review the package contents before updating.
[](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)
Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.
[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)
---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore major version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's major version (unless you unignore this specific
dependency's major version or upgrade to it yourself)
- `@dependabot ignore minor version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's minor version (unless you unignore this specific
dependency's minor version or upgrade to it yourself)
- `@dependabot ignore ` will close this group update PR
and stop Dependabot creating any more for the specific dependency
(unless you unignore this specific dependency or upgrade to it yourself)
- `@dependabot unignore ` will remove all of the ignore
conditions of the specified dependency
- `@dependabot unignore ` will
remove the ignore condition of the specified dependency and ignore
conditions
You can disable automated security fix PRs for this repo from the
[Security Alerts
page](https://github.com/zen-browser/desktop/network/alerts).
Signed-off-by: dependabot[bot]
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
---
package-lock.json | 19 +++++++++++--------
1 file changed, 11 insertions(+), 8 deletions(-)
diff --git a/package-lock.json b/package-lock.json
index 65a139677..c773998a9 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1005,15 +1005,15 @@
"license": "MIT"
},
"node_modules/axios": {
- "version": "1.13.6",
- "resolved": "https://registry.npmjs.org/axios/-/axios-1.13.6.tgz",
- "integrity": "sha512-ChTCHMouEe2kn713WHbQGcuYrr6fXTBiu460OTwWrWob16g1bXn4vtz07Ope7ewMozJAnEquLk5lWQWtBig9DQ==",
+ "version": "1.15.0",
+ "resolved": "https://registry.npmjs.org/axios/-/axios-1.15.0.tgz",
+ "integrity": "sha512-wWyJDlAatxk30ZJer+GeCWS209sA42X+N5jU2jy6oHTp7ufw8uzUTVFBX9+wTfAlhiJXGS0Bq7X6efruWjuK9Q==",
"dev": true,
"license": "MIT",
"dependencies": {
"follow-redirects": "^1.15.11",
"form-data": "^4.0.5",
- "proxy-from-env": "^1.1.0"
+ "proxy-from-env": "^2.1.0"
}
},
"node_modules/b4a": {
@@ -3254,11 +3254,14 @@
}
},
"node_modules/proxy-from-env": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
- "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==",
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-2.1.0.tgz",
+ "integrity": "sha512-cJ+oHTW1VAEa8cJslgmUZrc+sjRKgAKl3Zyse6+PV38hZe/V6Z14TbCuXcan9F9ghlz4QrFr2c92TNF82UkYHA==",
"dev": true,
- "license": "MIT"
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ }
},
"node_modules/pump": {
"version": "3.0.2",
From 691fc0cadb68bcaf5a21a035e3a930a59f96bd48 Mon Sep 17 00:00:00 2001
From: fen4flo <75260616+FlorianButz@users.noreply.github.com>
Date: Fri, 10 Apr 2026 03:16:26 +0200
Subject: [PATCH 68/72] fix: Add changes to the zapping feature, c=boosts,
b=no-bug (#13101)
I've added a fix for the zapping which will now only set the display to
none of a zapped element after the dissolve animation is fully complete.
I also plan on looking forward to fixing the color invalidation issue,
which is not done yet.
---
src/zen/boosts/ZenZapDissolve.sys.mjs | 11 ++++++++++-
src/zen/boosts/ZenZapOverlayChild.sys.mjs | 16 ++++++++++++----
2 files changed, 22 insertions(+), 5 deletions(-)
diff --git a/src/zen/boosts/ZenZapDissolve.sys.mjs b/src/zen/boosts/ZenZapDissolve.sys.mjs
index 0bebcc352..25a2dd26d 100644
--- a/src/zen/boosts/ZenZapDissolve.sys.mjs
+++ b/src/zen/boosts/ZenZapDissolve.sys.mjs
@@ -154,6 +154,8 @@ void main() {
#hasTriggered = false;
#rafId = null;
+ #onComplete = null;
+
/**
* @param {Document} document Webpage document
*/
@@ -482,12 +484,14 @@ void main() {
*
* @param {Element} element The element to dissolve
*/
- dissolve(element) {
+ dissolve(element, onComplete) {
if (!this.#initialized || this.#hasTriggered || !element) {
return;
}
this.#hasTriggered = true;
+ this.#onComplete = onComplete;
+
const rect = element.getBoundingClientRect();
if (rect.width === 0 || rect.height === 0) {
console.warn("[ZapDissolve]: element has zero size. Skipping dissolve");
@@ -581,6 +585,11 @@ void main() {
this.window.cancelAnimationFrame(this.#rafId);
this.#rafId = null;
}
+
+ if(this.#onComplete){
+ this.#onComplete();
+ this.#onComplete = null;
+ }
}
/**
diff --git a/src/zen/boosts/ZenZapOverlayChild.sys.mjs b/src/zen/boosts/ZenZapOverlayChild.sys.mjs
index 279266700..dc9ea7bec 100644
--- a/src/zen/boosts/ZenZapOverlayChild.sys.mjs
+++ b/src/zen/boosts/ZenZapOverlayChild.sys.mjs
@@ -192,13 +192,21 @@ export class ZapOverlay {
counter++;
this.#getNextDissolveEffect().then(dissolve => {
- dissolve.dissolve(element);
+ dissolve.dissolve(element, () => {
+ this.zenBoostsChild.addZapSelector(cssPath);
+ this.onZapUpdate();
+
+ this.window.requestAnimationFrame(() => {
+ element.style.visibility = 'initial';
+ });
+ });
+ element.style.visibility = 'hidden';
});
});
+ } else {
+ this.zenBoostsChild.addZapSelector(cssPath);
+ this.onZapUpdate();
}
-
- this.zenBoostsChild.addZapSelector(cssPath);
- this.onZapUpdate();
}
/**
From 11cf410f873c22e9680f21c8a7437b565d6ef427 Mon Sep 17 00:00:00 2001
From: JDX50S <71799746+smoke-wolf@users.noreply.github.com>
Date: Fri, 10 Apr 2026 07:25:16 -0300
Subject: [PATCH 69/72] no-bug: fix SIGNMAR path in Sign MAR step to point at
binary not directory (gh-13193)
---
.github/workflows/build.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index 07203a4a6..92ca489cd 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -512,7 +512,7 @@ jobs:
- name: Sign MAR files
env:
- SIGNMAR: ${{ github.workspace }}/signmar-linux-x86_64
+ SIGNMAR: ${{ github.workspace }}/signmar-linux-x86_64/signmar
ZEN_MAR_SIGNING_PASSWORD: ${{ secrets.ZEN_MAR_SIGNING_PASSWORD }}
ZEN_SIGNING_CERT_PEM_BASE64: ${{ secrets.ZEN_SIGNING_CERT_PEM_BASE64 }}
ZEN_SIGNING_PRIVATE_KEY_PEM_BASE64: ${{ secrets.ZEN_SIGNING_PRIVATE_KEY_PEM_BASE64 }}
From 1edcf465a5e69d36feec70f06af9fc3719bd77e5 Mon Sep 17 00:00:00 2001
From: "Mr. M"
Date: Fri, 10 Apr 2026 16:05:37 +0200
Subject: [PATCH 70/72] no-bug: Fix color algorithms
---
src/zen/boosts/ZenZapDissolve.sys.mjs | 3 +-
src/zen/boosts/ZenZapOverlayChild.sys.mjs | 4 +--
src/zen/boosts/nsZenBoostsBackend.cpp | 35 ++++++++++++-------
src/zen/boosts/zen-advanced-color-options.css | 1 -
src/zen/spaces/ZenGradientGenerator.mjs | 8 ++++-
5 files changed, 33 insertions(+), 18 deletions(-)
diff --git a/src/zen/boosts/ZenZapDissolve.sys.mjs b/src/zen/boosts/ZenZapDissolve.sys.mjs
index 25a2dd26d..860aff172 100644
--- a/src/zen/boosts/ZenZapDissolve.sys.mjs
+++ b/src/zen/boosts/ZenZapDissolve.sys.mjs
@@ -483,6 +483,7 @@ void main() {
* Displays a dissolve effect for the element
*
* @param {Element} element The element to dissolve
+ * @param {Function} onComplete Callback for when the animation is complete
*/
dissolve(element, onComplete) {
if (!this.#initialized || this.#hasTriggered || !element) {
@@ -586,7 +587,7 @@ void main() {
this.#rafId = null;
}
- if(this.#onComplete){
+ if (this.#onComplete) {
this.#onComplete();
this.#onComplete = null;
}
diff --git a/src/zen/boosts/ZenZapOverlayChild.sys.mjs b/src/zen/boosts/ZenZapOverlayChild.sys.mjs
index dc9ea7bec..5635c0c4d 100644
--- a/src/zen/boosts/ZenZapOverlayChild.sys.mjs
+++ b/src/zen/boosts/ZenZapOverlayChild.sys.mjs
@@ -197,10 +197,10 @@ export class ZapOverlay {
this.onZapUpdate();
this.window.requestAnimationFrame(() => {
- element.style.visibility = 'initial';
+ element.style.visibility = "initial";
});
});
- element.style.visibility = 'hidden';
+ element.style.visibility = "hidden";
});
});
} else {
diff --git a/src/zen/boosts/nsZenBoostsBackend.cpp b/src/zen/boosts/nsZenBoostsBackend.cpp
index e0f952e47..109eb6b51 100644
--- a/src/zen/boosts/nsZenBoostsBackend.cpp
+++ b/src/zen/boosts/nsZenBoostsBackend.cpp
@@ -19,6 +19,12 @@
#define COLOR_CHANNEL_MIDPOINT 128
+#if defined(__clang__) || defined(__GNUC__)
+# define ZEN_HOT_FUNCTION __attribute__((hot))
+#else
+# define ZEN_HOT_FUNCTION
+#endif
+
// It's a bit of a hacky solution, but instead of using alpha as what it is
// (opacity), we use it to store contrast information for now.
// We do this primarily to avoid having to deal with WebIDL structs and
@@ -133,8 +139,9 @@ static inline float fastCbrt(float x) {
* @return A struct containing the precomputed Oklab values and contrast factor
* for the accent color.
*/
+ZEN_HOT_FUNCTION
inline static auto zenPrecomputeAccent(nscolor aAccentColor) {
- const float inv255 = 1.0f / 255.0f;
+ constexpr float inv255 = 1.0f / 255.0f;
const float r = NS_GET_R(aAccentColor) * inv255;
const float g = NS_GET_G(aAccentColor) * inv255;
@@ -170,9 +177,8 @@ inline static auto zenPrecomputeAccent(nscolor aAccentColor) {
* contrast value).
* @return The filtered color with transformations applied.
*/
-[[nodiscard]]
-static inline nscolor zenFilterColorChannel(nscolor aOriginalColor,
- const nsZenAccentOklab& aAccent) {
+[[nodiscard]] ZEN_HOT_FUNCTION static inline nscolor zenFilterColorChannel(
+ nscolor aOriginalColor, const nsZenAccentOklab& aAccent) {
const uint8_t oL = NS_GET_A(aOriginalColor);
if (oL == 0) {
return aOriginalColor;
@@ -180,7 +186,6 @@ static inline nscolor zenFilterColorChannel(nscolor aOriginalColor,
const float inv255 = 1.0f / 255.0f;
const float blendFactor = oL * inv255;
- const float preserveFactor = 1.0f - aAccent.contrastFactor;
// sRGB -> linear
const float lr = srgbToLinear(NS_GET_R(aOriginalColor) * inv255);
@@ -206,10 +211,11 @@ static inline nscolor zenFilterColorChannel(nscolor aOriginalColor,
const float fA = origA + (aAccent.accA - origA) * blendFactor;
const float fB = origB + (aAccent.accB - origB) * blendFactor;
- // Luminance: preserve spread at low contrast, flatten at high
- const float deltaL = origL - aAccent.accL;
- const float baseL = origL + (aAccent.accL - origL) * blendFactor;
- const float fL = std::clamp(baseL + deltaL * preserveFactor, 0.0f, 1.0f);
+ // Luminance: at low contrast stay near the original, the higher the contrast,
+ // the more we shift toward the accent luminance, but we never go fully to
+ // the accent luminance to preserve some of the original color's character.
+ const float fL = origL + (aAccent.accL - origL) *
+ (blendFactor * aAccent.contrastFactor * 0.5f);
// Oklab -> LMS
const float fl_ = fL + 0.3963377774f * fA + 0.2158037573f * fB;
@@ -245,6 +251,7 @@ static inline nscolor zenFilterColorChannel(nscolor aOriginalColor,
* @param aColor The color to invert.
* @return The inverted color with luminance preservation.
*/
+ZEN_HOT_FUNCTION
inline static nscolor zenInvertColorChannel(nscolor aColor) {
const auto r = NS_GET_R(aColor);
const auto g = NS_GET_G(aColor);
@@ -274,6 +281,7 @@ inline static nscolor zenInvertColorChannel(nscolor aColor) {
/**
* @brief Retrieves the current boost data from the browsing context.
*/
+ZEN_HOT_FUNCTION
inline static void GetZenBoostsDataFromBrowsingContext(
ZenBoostData* aData, bool* aIsInverted,
nsPresContext* aPresContext = nullptr) {
@@ -323,8 +331,9 @@ auto nsZenBoostsBackend::onPresShellEntered(mozilla::dom::Document* aDocument)
mCurrentBrowsingContext = browsingContext;
}
-auto nsZenBoostsBackend::FilterColorFromPresContext(nscolor aColor,
- nsPresContext* aPresContext)
+[[nodiscard]] ZEN_HOT_FUNCTION auto
+nsZenBoostsBackend::FilterColorFromPresContext(nscolor aColor,
+ nsPresContext* aPresContext)
-> nscolor {
if (!XRE_IsContentProcess()) {
// Zen boosts are only supported in content, so if we somehow end up here
@@ -353,8 +362,8 @@ auto nsZenBoostsBackend::FilterColorFromPresContext(nscolor aColor,
return aColor;
}
-auto nsZenBoostsBackend::ResolveStyleColor(mozilla::StyleAbsoluteColor aColor)
- -> mozilla::StyleAbsoluteColor {
+[[nodiscard]] ZEN_HOT_FUNCTION auto nsZenBoostsBackend::ResolveStyleColor(
+ mozilla::StyleAbsoluteColor aColor) -> mozilla::StyleAbsoluteColor {
if (aColor.alpha == 0) {
// Skip processing fully transparent colors since they won't be visible and
// we want to avoid unnecessary computations. This also prevents issues with
diff --git a/src/zen/boosts/zen-advanced-color-options.css b/src/zen/boosts/zen-advanced-color-options.css
index 052f76b30..8c3285c11 100644
--- a/src/zen/boosts/zen-advanced-color-options.css
+++ b/src/zen/boosts/zen-advanced-color-options.css
@@ -41,4 +41,3 @@
#zen-boost-advanced-color-options-panel input::-moz-range-thumb:active {
background-color: #cbcad0;
}
-
diff --git a/src/zen/spaces/ZenGradientGenerator.mjs b/src/zen/spaces/ZenGradientGenerator.mjs
index 7e73f9939..b4a704fda 100644
--- a/src/zen/spaces/ZenGradientGenerator.mjs
+++ b/src/zen/spaces/ZenGradientGenerator.mjs
@@ -1762,7 +1762,13 @@ export class nsZenThemePicker extends nsZenMultiWindowFeature {
});
// Notify observers that gradient updated
- Services.obs.notifyObservers(null, "zen-space-gradient-update");
+ // note: We just notify if we are not skipping the update,
+ // because otherwise, it can get pretty laggy if we notify on every change
+ // when the user is dragging a dot.
+ // TODO(cheff): We should probably find a better way to handle this
+ if (!skipUpdate) {
+ Services.obs.notifyObservers(null, "zen-space-gradient-update");
+ }
}
fixTheme(theme) {
From 97451e23c82eee85e614a1eaa274799e3cdababd Mon Sep 17 00:00:00 2001
From: "mr. m" <91018726+mr-cheffy@users.noreply.github.com>
Date: Fri, 10 Apr 2026 17:17:52 +0200
Subject: [PATCH 71/72] no-bug: Individually download each artifact on release
(gh-13199)
---
.github/workflows/build.yml | 33 ++++++++++++++++++++++++++++-----
package-lock.json | 11 +++++++----
scripts/mar_sign.sh | 2 ++
3 files changed, 37 insertions(+), 9 deletions(-)
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index 92ca489cd..e9218085c 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -490,8 +490,35 @@ jobs:
submodules: recursive
token: ${{ secrets.DEPLOY_KEY }}
- - name: Download artifact
+ - name: Download artifact (source)
uses: actions/download-artifact@v4
+ with:
+ name: zen.source.tar.zst
+
+ - name: Download artifact (MAR files)
+ uses: actions/download-artifact@v4
+ with:
+ pattern: "*.mar"
+
+ - name: Download artifact (Linux tars)
+ uses: actions/download-artifact@v4
+ with:
+ pattern: "zen.linux-*.tar.xz"
+
+ - name: Download artifact (Linux AppImage)
+ uses: actions/download-artifact@v4
+ with:
+ pattern: "zen-*.AppImage*"
+
+ - name: Download artifact (macOS universal DMG)
+ uses: actions/download-artifact@v4
+ with:
+ name: zen.macos-universal.dmg
+
+ - name: Download artifact (Windows installers)
+ uses: actions/download-artifact@v4
+ with:
+ pattern: "zen.installer*.exe"
- name: Checkout updates repository
uses: actions/checkout@v4
@@ -565,8 +592,6 @@ jobs:
./zen-x86_64.AppImage.zsync/*
./zen-aarch64.AppImage/*
./zen-aarch64.AppImage.zsync/*
- ./zen.win-x86_64.zip/*
- ./zen.win-arm64.zip/*
./linux.mar/*
./linux-aarch64.mar/*
./windows.mar/*
@@ -604,8 +629,6 @@ jobs:
./zen-x86_64.AppImage.zsync/*
./zen-aarch64.AppImage/*
./zen-aarch64.AppImage.zsync/*
- ./.github/workflows/object/windows-x64-signed-x86_64/zen.win-x86_64.zip
- ./.github/workflows/object/windows-x64-signed-arm64/zen.win-arm64.zip
./linux.mar/*
./linux-aarch64.mar/*
./.github/workflows/object/windows-x64-signed-x86_64/windows.mar
diff --git a/package-lock.json b/package-lock.json
index c773998a9..fa57400cb 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -4177,16 +4177,19 @@
"peer": true
},
"node_modules/yaml": {
- "version": "2.7.0",
- "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.7.0.tgz",
- "integrity": "sha512-+hSoy/QHluxmC9kCIJyL/uyFmLmc+e5CFR5Wa+bpIhIj85LVb9ZH2nVnqrHoSvKogwODv0ClqZkmiSSaIH5LTA==",
+ "version": "2.8.3",
+ "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.3.tgz",
+ "integrity": "sha512-AvbaCLOO2Otw/lW5bmh9d/WEdcDFdQp2Z2ZUH3pX9U2ihyUY0nvLv7J6TrWowklRGPYbB/IuIMfYgxaCPg5Bpg==",
"dev": true,
"license": "ISC",
"bin": {
"yaml": "bin.mjs"
},
"engines": {
- "node": ">= 14"
+ "node": ">= 14.6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/eemeli"
}
},
"node_modules/zip": {
diff --git a/scripts/mar_sign.sh b/scripts/mar_sign.sh
index 2dfbfbc6c..8b12a5d68 100644
--- a/scripts/mar_sign.sh
+++ b/scripts/mar_sign.sh
@@ -111,6 +111,8 @@ sign_mars() {
exit 1
fi
+ chmod +x "$SIGNMAR"
+
create_nss_config_dir
folders=(
From fd8308fcb12631f1c498d7cb9e0351263acd799b Mon Sep 17 00:00:00 2001
From: "mr. m" <91018726+mr-cheffy@users.noreply.github.com>
Date: Sat, 11 Apr 2026 12:03:04 +0200
Subject: [PATCH 72/72] Revert "no-bug: Individually download each artifact on
release" (gh-13211)
Reverts zen-browser/desktop#13199
---------
Signed-off-by: mr. m <91018726+mr-cheffy@users.noreply.github.com>
---
.github/workflows/build.yml | 29 +----------------------------
package-lock.json | 11 ++++-------
2 files changed, 5 insertions(+), 35 deletions(-)
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index e9218085c..00e8d76f1 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -490,35 +490,8 @@ jobs:
submodules: recursive
token: ${{ secrets.DEPLOY_KEY }}
- - name: Download artifact (source)
+ - name: Download artifact
uses: actions/download-artifact@v4
- with:
- name: zen.source.tar.zst
-
- - name: Download artifact (MAR files)
- uses: actions/download-artifact@v4
- with:
- pattern: "*.mar"
-
- - name: Download artifact (Linux tars)
- uses: actions/download-artifact@v4
- with:
- pattern: "zen.linux-*.tar.xz"
-
- - name: Download artifact (Linux AppImage)
- uses: actions/download-artifact@v4
- with:
- pattern: "zen-*.AppImage*"
-
- - name: Download artifact (macOS universal DMG)
- uses: actions/download-artifact@v4
- with:
- name: zen.macos-universal.dmg
-
- - name: Download artifact (Windows installers)
- uses: actions/download-artifact@v4
- with:
- pattern: "zen.installer*.exe"
- name: Checkout updates repository
uses: actions/checkout@v4
diff --git a/package-lock.json b/package-lock.json
index fa57400cb..c773998a9 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -4177,19 +4177,16 @@
"peer": true
},
"node_modules/yaml": {
- "version": "2.8.3",
- "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.3.tgz",
- "integrity": "sha512-AvbaCLOO2Otw/lW5bmh9d/WEdcDFdQp2Z2ZUH3pX9U2ihyUY0nvLv7J6TrWowklRGPYbB/IuIMfYgxaCPg5Bpg==",
+ "version": "2.7.0",
+ "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.7.0.tgz",
+ "integrity": "sha512-+hSoy/QHluxmC9kCIJyL/uyFmLmc+e5CFR5Wa+bpIhIj85LVb9ZH2nVnqrHoSvKogwODv0ClqZkmiSSaIH5LTA==",
"dev": true,
"license": "ISC",
"bin": {
"yaml": "bin.mjs"
},
"engines": {
- "node": ">= 14.6"
- },
- "funding": {
- "url": "https://github.com/sponsors/eemeli"
+ "node": ">= 14"
}
},
"node_modules/zip": {
|