mirror of
https://github.com/zen-browser/desktop.git
synced 2026-09-09 23:05:33 +00:00
gh-14956: Check if the closing tab exists on the tab list before switching (gh-15312)
This commit is contained in:
1
.github/workflows/macos-profile-build.yml
vendored
1
.github/workflows/macos-profile-build.yml
vendored
@@ -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:
|
||||
|
||||
2
.github/workflows/src/release-build.sh
vendored
2
.github/workflows/src/release-build.sh
vendored
@@ -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 &
|
||||
|
||||
1
.github/workflows/windows-profile-build.yml
vendored
1
.github/workflows/windows-profile-build.yml
vendored
@@ -27,7 +27,6 @@ jobs:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
arch: [x86_64, aarch64]
|
||||
|
||||
runs-on: ${{ inputs.release-branch == 'release' && 'windows-latest' || 'windows-latest' }}
|
||||
|
||||
steps:
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user