diff --git a/.github/workflows/macos-profile-build.yml b/.github/workflows/macos-profile-build.yml index 43aa552b2..4d42e76c5 100644 --- a/.github/workflows/macos-profile-build.yml +++ b/.github/workflows/macos-profile-build.yml @@ -23,7 +23,6 @@ jobs: fail-fast: false matrix: arch: [x86_64, aarch64] - runs-on: ${{ matrix.arch == 'x86_64' && 'macos-15-intel' || 'macos-26' }} steps: diff --git a/.github/workflows/src/release-build.sh b/.github/workflows/src/release-build.sh index d3e9720e6..6daa7c7ce 100644 --- a/.github/workflows/src/release-build.sh +++ b/.github/workflows/src/release-build.sh @@ -37,6 +37,8 @@ bash ./scripts/mar_sign.sh -i ulimit -n 4096 +export ZEN_DISABLE_BOOTSTRAP=1 + if command -v Xvfb &> /dev/null; then if ! test "$ZEN_CROSS_COMPILING"; then Xvfb :2 -nolisten tcp -noreset -screen 0 1024x768x24 & diff --git a/.github/workflows/windows-profile-build.yml b/.github/workflows/windows-profile-build.yml index 694672647..3ba3ffa11 100644 --- a/.github/workflows/windows-profile-build.yml +++ b/.github/workflows/windows-profile-build.yml @@ -27,7 +27,6 @@ jobs: fail-fast: false matrix: arch: [x86_64, aarch64] - runs-on: ${{ inputs.release-branch == 'release' && 'windows-latest' || 'windows-latest' }} steps: diff --git a/configs/common/mozconfig b/configs/common/mozconfig index 2adf9d0eb..c4ecea44d 100644 --- a/configs/common/mozconfig +++ b/configs/common/mozconfig @@ -53,7 +53,10 @@ fi if test "$ZEN_RELEASE"; then ac_add_options --enable-clang-plugin - ac_add_options --enable-bootstrap=-sccache + + if ! test "$ZEN_DISABLE_BOOTSTRAP"; then + ac_add_options --enable-bootstrap=-sccache + fi ac_add_options --enable-optimize @@ -69,16 +72,11 @@ if test "$ZEN_RELEASE"; then ac_add_options --disable-geckodriver ac_add_options --disable-rust-tests - if ! test "$ZEN_DISABLE_LTO"; then - # only enable full LTO when ZEN_RELEASE_BRANCH is 'release' - if test "$ZEN_RELEASE_BRANCH" = "release"; then - # TODO: make it "full" once we have the resources to build it - export MOZ_LTO=cross,full - ac_add_options --enable-lto=cross,full - else - export MOZ_LTO=cross,thin - ac_add_options --enable-lto=cross,thin - fi + if test "$ZEN_DISABLE_LTO"; then + ac_add_options --disable-lto + else + export MOZ_LTO=cross,thin + ac_add_options --enable-lto=cross,thin fi mk_add_options MOZILLA_OFFICIAL=1 diff --git a/configs/linux/mozconfig b/configs/linux/mozconfig index c959a8eec..4ea92b3e5 100644 --- a/configs/linux/mozconfig +++ b/configs/linux/mozconfig @@ -9,6 +9,9 @@ if test "$ZEN_RELEASE"; then # Enable Profile Guided Optimization if ! test "$ZEN_GA_DISABLE_PGO"; then + export MOZ_LTO=cross,full + ac_add_options --enable-lto=cross,full + if test "$ZEN_GA_GENERATE_PROFILE"; then mk_add_options "export MOZ_AUTOMATION_PACKAGE_GENERATED_SOURCES=0" ac_add_options --enable-profile-generate=cross diff --git a/configs/windows/mozconfig b/configs/windows/mozconfig index cc93620e7..ae38f3791 100644 --- a/configs/windows/mozconfig +++ b/configs/windows/mozconfig @@ -45,6 +45,9 @@ if test "$ZEN_CROSS_COMPILING"; then ac_add_options --enable-profile-use=cross ac_add_options --with-pgo-profile-path=$(echo ~)/artifact/merged.profdata ac_add_options --with-pgo-jarlog=$(echo ~)/artifact/en-US.log + + export MOZ_LTO=cross,full + ac_add_options --enable-lto=cross,full fi fi fi diff --git a/src/browser/components/preferences/zen-settings.js b/src/browser/components/preferences/zen-settings.js index 90151667c..f6618158b 100644 --- a/src/browser/components/preferences/zen-settings.js +++ b/src/browser/components/preferences/zen-settings.js @@ -741,7 +741,6 @@ var gZenWorkspacesSettings = { Services.prefs.addObserver("zen.glance.enabled", tabsUnloaderPrefListener); // We can use the same listener for both prefs Services.prefs.addObserver("zen.workspaces.separate-essentials", tabsUnloaderPrefListener); - Services.prefs.addObserver("zen.glance.activation-method", tabsUnloaderPrefListener); Services.prefs.addObserver("zen.window-sync.sync-only-pinned-tabs", tabsUnloaderPrefListener); Services.prefs.addObserver( "zen.tabs.ctrl-tab.ignore-essential-tabs", @@ -750,7 +749,6 @@ var gZenWorkspacesSettings = { Services.prefs.addObserver("browser.ctrlTab.sortByRecentlyUsed", toggleZenCycleByAttrWarning); window.addEventListener("unload", () => { Services.prefs.removeObserver("zen.glance.enabled", tabsUnloaderPrefListener); - Services.prefs.removeObserver("zen.glance.activation-method", tabsUnloaderPrefListener); Services.prefs.removeObserver("zen.workspaces.separate-essentials", tabsUnloaderPrefListener); Services.prefs.removeObserver( "zen.window-sync.sync-only-pinned-tabs", diff --git a/src/browser/components/tabbrowser/content/tabbrowser-js.patch b/src/browser/components/tabbrowser/content/tabbrowser-js.patch index ddd1b60db..05bdb13a4 100644 --- a/src/browser/components/tabbrowser/content/tabbrowser-js.patch +++ b/src/browser/components/tabbrowser/content/tabbrowser-js.patch @@ -751,7 +751,7 @@ index 43180487a2fac15b7a65fac94f233eeed9094990..ef6d30eb681caeae48d15280687b3bc3 } /** -@@ -6422,6 +6618,7 @@ +@@ -6422,11 +6618,12 @@ } let excludeTabs = new Set(aExcludeTabs); @@ -759,6 +759,12 @@ index 43180487a2fac15b7a65fac94f233eeed9094990..ef6d30eb681caeae48d15280687b3bc3 // If this tab has a successor, it should be selectable, since // hiding or closing a tab removes that tab as a successor. + if (aTab.successor && !excludeTabs.has(aTab.successor)) { +- return aTab.successor; ++ return gZenWorkspaces.findTabToBlur(aTab.successor); + } + + if ( @@ -6434,13 +6631,13 @@ !excludeTabs.has(aTab.owner) && Services.prefs.getBoolPref("browser.tabs.selectOwnerOnClose") diff --git a/src/zen/boosts/actors/ZenBoostsChild.sys.mjs b/src/zen/boosts/actors/ZenBoostsChild.sys.mjs index 364490698..805de7a89 100644 --- a/src/zen/boosts/actors/ZenBoostsChild.sys.mjs +++ b/src/zen/boosts/actors/ZenBoostsChild.sys.mjs @@ -70,8 +70,10 @@ export class ZenBoostsChild extends JSWindowActorChild { static PREVENTABLE_SET = new Set(ZenBoostsChild.PREVENTABLE_EVENTS); - actorCreated() { - this.#applyBoostForPageIfAvailable(); + handleEvent(event) { + if (event.type === "DOMDocElementInserted") { + this.#applyBoostForPageIfAvailable(); + } } didDestroy() { @@ -330,6 +332,22 @@ export class ZenBoostsChild extends JSWindowActorChild { return this.sendQuery("ZenBoost:GetBoostForDomain", domain); } + /** + * Sets a synced BrowsingContext field only when its value changes. Every + * setter commits a transaction that is broadcast to the whole browsing + * context group, even when the value is unchanged, so this avoids three + * such broadcasts on every page load that has no boost. + * + * @param {BrowsingContext} browsingContext + * @param {string} field - The synced field name. + * @param {number | boolean} value + */ + #setSyncedField(browsingContext, field, value) { + if (browsingContext[field] !== value) { + browsingContext[field] = value; + } + } + /** * Applies the boost settings for the current page if available. * @@ -360,7 +378,11 @@ export class ZenBoostsChild extends JSWindowActorChild { sizeOverride: boostData.sizeOverride, }); - browsingContext.isZenBoostsInverted = boostData.smartInvert; + this.#setSyncedField( + browsingContext, + "isZenBoostsInverted", + !!boostData.smartInvert + ); if (boostData.enableColorBoost) { let primaryColor; if (boostData.autoTheme) { @@ -396,18 +418,21 @@ export class ZenBoostsChild extends JSWindowActorChild { boostData ); } - browsingContext.zenBoostsData = primaryColor; + this.#setSyncedField(browsingContext, "zenBoostsData", primaryColor); // The complementary accent is derived in the backend by rotating the // primary accent's hue by this delta (in degrees). - browsingContext.zenBoostsComplementaryRotation = - boostData.secondaryDotAngleDegDelta ?? 0; + this.#setSyncedField( + browsingContext, + "zenBoostsComplementaryRotation", + boostData.secondaryDotAngleDegDelta ?? 0 + ); return; } } else { - browsingContext.isZenBoostsInverted = false; + this.#setSyncedField(browsingContext, "isZenBoostsInverted", false); } - browsingContext.zenBoostsData = 0; - browsingContext.zenBoostsComplementaryRotation = 0; + this.#setSyncedField(browsingContext, "zenBoostsData", 0); + this.#setSyncedField(browsingContext, "zenBoostsComplementaryRotation", 0); } /** diff --git a/src/zen/common/sys/ZenActorsManager.sys.mjs b/src/zen/common/sys/ZenActorsManager.sys.mjs index 4b3fc1471..c7864f261 100644 --- a/src/zen/common/sys/ZenActorsManager.sys.mjs +++ b/src/zen/common/sys/ZenActorsManager.sys.mjs @@ -42,7 +42,6 @@ let JSWINDOWACTORS = { child: { esModuleURI: "resource:///actors/ZenGlanceChild.sys.mjs", events: { - DOMContentLoaded: {}, mousedown: { capture: true, }, @@ -86,9 +85,7 @@ if (!Services.appinfo.inSafeMode) { child: { esModuleURI: "resource:///actors/ZenBoostsChild.sys.mjs", events: { - // Needed to let the actor be created, please don't remove - // without checking if boosts still work without it, thanks <3 - DOMWindowCreated: {}, + DOMDocElementInserted: {}, }, }, safeForUntrustedWebProcess: true, diff --git a/src/zen/glance/actors/ZenGlanceChild.sys.mjs b/src/zen/glance/actors/ZenGlanceChild.sys.mjs index 1758204d6..f91185fc3 100644 --- a/src/zen/glance/actors/ZenGlanceChild.sys.mjs +++ b/src/zen/glance/actors/ZenGlanceChild.sys.mjs @@ -17,12 +17,18 @@ XPCOMUtils.defineLazyPreferenceGetter( true ); +XPCOMUtils.defineLazyPreferenceGetter( + lazy, + "activationMethod", + "zen.glance.activation-method", + "ctrl" +); + // A small threshold to allow for minor mouse jitter during a normal click. // Anything beyond this is likely an intentional drag (like selecting text). const CLICK_DRAG_THRESHOLD_PX = 4; export class ZenGlanceChild extends JSWindowActorChild { - #activationMethod; #mouseDownX = null; #mouseDownY = null; @@ -37,12 +43,6 @@ export class ZenGlanceChild extends JSWindowActorChild { } } - async #initActivationMethod() { - this.#activationMethod = await this.sendQuery( - "ZenGlance:GetActivationMethod" - ); - } - #ensureOnlyKeyModifiers(event) { return !(event.ctrlKey ^ event.altKey ^ event.shiftKey ^ event.metaKey); } @@ -156,7 +156,7 @@ export class ZenGlanceChild extends JSWindowActorChild { ) { return; } - const activationMethod = this.#activationMethod; + const activationMethod = lazy.activationMethod; if (activationMethod === "ctrl" && !event.ctrlKey) { return; } else if (activationMethod === "alt" && !event.altKey) { @@ -184,8 +184,4 @@ export class ZenGlanceChild extends JSWindowActorChild { this.contentWindow.document.body, }); } - - async on_DOMContentLoaded() { - await this.#initActivationMethod(); - } } diff --git a/src/zen/glance/actors/ZenGlanceParent.sys.mjs b/src/zen/glance/actors/ZenGlanceParent.sys.mjs index 748c18912..74446ab70 100644 --- a/src/zen/glance/actors/ZenGlanceParent.sys.mjs +++ b/src/zen/glance/actors/ZenGlanceParent.sys.mjs @@ -11,12 +11,6 @@ export class ZenGlanceParent extends JSWindowActorParent { async receiveMessage(message) { switch (message.name) { - case "ZenGlance:GetActivationMethod": { - return Services.prefs.getStringPref( - "zen.glance.activation-method", - "ctrl" - ); - } case "ZenGlance:OpenGlance": { this.openGlance(this.browsingContext.topChromeWindow, message.data); break; diff --git a/src/zen/spaces/ZenSpaceManager.mjs b/src/zen/spaces/ZenSpaceManager.mjs index 727d0e754..e7e57a67a 100644 --- a/src/zen/spaces/ZenSpaceManager.mjs +++ b/src/zen/spaces/ZenSpaceManager.mjs @@ -2911,7 +2911,10 @@ class nsZenWorkspaces { } findTabToBlur(tab) { - if ((!this._shouldChangeToTab(tab) || !tab) && this._emptyTab) { + if ( + (!tab || !this._shouldChangeToTab(tab) || !gBrowser.tabs.includes(tab)) && + this._emptyTab + ) { return this._emptyTab; } return tab;