fix: Fixed closing last tab not closing the window and other refactors, b=closes #10455, c=common, configs, kbs, split-view, folders, tests, workspaces

This commit is contained in:
Mr. M
2025-09-21 17:29:40 +02:00
parent 2ed55a22a6
commit d962cf9949
17 changed files with 110 additions and 18 deletions

View File

@@ -100,6 +100,8 @@ if test "$ZEN_RELEASE"; then
ac_add_options --enable-updater
export MOZ_PACKAGE_JSSHELL=1
else
ac_add_options --disable-crashreporter
fi
ac_add_options --enable-unverified-updates

View File

@@ -79,3 +79,6 @@
- name: browser.tabs.groups.hoverPreview.enabled
value: false
- name: browser.tabs.closeWindowWithLastTab
value: false

View File

@@ -33,7 +33,7 @@
value: true
- name: zen.theme.styled-status-panel
value: true
value: '@IS_TWILIGHT@'
# ==== Mark: border radius ====

View File

@@ -66,13 +66,6 @@
}
#urlbar:not([breakout-extend='true']) {
& .urlbar-background {
transition: background-color 0.15s ease;
:root[supress-primary-adjustment] & {
transition: none !important;
}
}
&:hover .urlbar-background {
background-color: light-dark(rgba(0, 0, 0, 0.1), rgba(255, 255, 255, 0.2)) !important;
}

View File

@@ -1084,7 +1084,7 @@ class nsZenKeyboardShortcutsVersioner {
data.push(
new KeyShortcut(
'zen-new-empty-split-view',
'+',
AppConstants.platform == 'linux' ? '*' : '+',
'',
ZEN_SPLIT_VIEW_SHORTCUTS_GROUP,
nsKeyShortcutModifiers.fromObject({ accel: true, shift: true }),

View File

@@ -1951,6 +1951,8 @@ class nsZenViewSplitter extends nsZenDOMOperatedFeature {
const newSelectedTab = gBrowser.selectedTab;
const cleanup = () => {
this.removeTabFromGroup(emptyTab, groupIndex, { changeTab: false });
const command = document.getElementById('cmd_zenNewEmptySplit');
command.removeAttribute('disabled');
};
if (onElementPicked) {
if (

View File

@@ -36,7 +36,7 @@ add_task(async function test_Issue_() {
ok(!tab1.hasAttribute('folder-active'), 'Tab 1 should not be in the active folder');
ok(!tab2.hasAttribute('folder-active'), 'Tab 2 should not be in the active folder');
resolve();
}, 100)
}, 500)
);
await removeFolder(folder);
});

View File

@@ -1,6 +1,6 @@
[
"zen.mods.updated-value-observer",
"zen.mods.last-update",
"zen.view.compact.should-enable-at-startup",
"zen.view.compact.enable-at-startup",
"browser.newtabpage.activity-stream.trendingSearch.defaultSearchEngine"
]

View File

@@ -10,6 +10,10 @@ ChromeUtils.defineESModuleGetters(this, {
add_task(async function test_Ub_Actions_Search() {
for (const action of globalActions) {
if (!action.isAvailable(window)) {
ok(true, `Skipping action: ${action.command}`);
continue;
}
const label = action.label;
await UrlbarTestUtils.promiseAutocompleteResultPopup({
window,

View File

@@ -15,6 +15,7 @@ support-files = [
["browser_issue_8699.js"]
["browser_issue_9900.js"]
["browser_issue_10455.js"]
["browser_private_mode.js"]
["browser_private_mode_startup.js"]

View File

@@ -0,0 +1,45 @@
/* Any copyright is dedicated to the Public Domain.
https://creativecommons.org/publicdomain/zero/1.0/ */
'use strict';
add_task(async function test_Issue_10455() {
await SpecialPowers.pushPrefEnv({
set: [['browser.tabs.closeWindowWithLastTab', true]],
});
let newWindow = await BrowserTestUtils.openNewBrowserWindow();
await newWindow.gZenWorkspaces.promiseInitialized;
ok(
newWindow.document.documentElement.hasAttribute('zen-workspace-id'),
'New window should have a zen-workspace-id attribute'
);
const unloadEvent = BrowserTestUtils.waitForEvent(newWindow, 'unload');
newWindow.BrowserCommands.closeTabOrWindow();
await unloadEvent;
ok(newWindow.closed, 'Window should be closing');
await SpecialPowers.popPrefEnv();
});
add_task(async function test_Issue_10455_Dont_Close() {
await SpecialPowers.pushPrefEnv({
set: [['browser.tabs.closeWindowWithLastTab', false]],
});
let newWindow = await BrowserTestUtils.openNewBrowserWindow();
await newWindow.gZenWorkspaces.promiseInitialized;
ok(
newWindow.document.documentElement.hasAttribute('zen-workspace-id'),
'New window should have a zen-workspace-id attribute'
);
newWindow.BrowserCommands.closeTabOrWindow();
ok(newWindow.gBrowser.tabs.length === 1, 'Window should still have one tab');
ok(newWindow.gBrowser.selectedTab.hasAttribute('zen-empty-tab'), 'Tab should be a zen empty tab');
ok(!newWindow.closing, 'Window should be closing');
await BrowserTestUtils.closeWindow(newWindow);
await SpecialPowers.popPrefEnv();
});

View File

@@ -18,4 +18,5 @@ add_task(async function test_Private_Mode() {
);
await BrowserTestUtils.closeWindow(privateWindow);
await SpecialPowers.popPrefEnv();
});

View File

@@ -367,6 +367,7 @@ export class ZenUrlbarProviderGlobalActions extends UrlbarProvider {
const payload = result.payload;
const command = payload.zenCommand;
const ownerGlobal = details.element.ownerGlobal;
ownerGlobal.gBrowser.selectedBrowser.focus();
if (typeof command === 'function') {
command(ownerGlobal);
return;
@@ -390,7 +391,6 @@ export class ZenUrlbarProviderGlobalActions extends UrlbarProvider {
}
const commandToRun = ownerGlobal.document.getElementById(command);
if (commandToRun) {
ownerGlobal.gBrowser.selectedBrowser.focus();
commandToRun.doCommand();
}
}

View File

@@ -69,14 +69,21 @@ const globalActionsTemplate = [
},
},
{
label: 'Next Workspace',
label: 'Next Space',
command: 'cmd_zenWorkspaceForward',
icon: 'chrome://browser/skin/zen-icons/forward.svg',
isAvailable: (window) => {
return window.gZenWorkspaces._workspaceCache.workspaces.length > 1;
},
},
{
label: 'Previous Workspace',
label: 'Previous Space',
command: 'cmd_zenWorkspaceBackward',
icon: 'chrome://browser/skin/zen-icons/back.svg',
isAvailable: (window) => {
// This also covers the case of being in private mode
return window.gZenWorkspaces._workspaceCache.workspaces.length > 1;
},
},
{
label: 'Close Tab',

View File

@@ -15,7 +15,7 @@
<html:div class="pinned-tabs-container-separator"></html:div>
</vbox>
<vbox class="zen-workspace-tabs-section zen-workspace-normal-tabs-section">
<!-- Let it me as an ID to mantain compatibility with firefox's tabbrowser -->
<!-- Let it as an ID to mantain compatibility with firefox's tabbrowser -->
<hbox id="tabbrowser-arrowscrollbox-periphery">
<toolbartabstop/>
<toolbarbutton id="tabs-newtab-button"

View File

@@ -1130,7 +1130,7 @@ var gZenWorkspaces = new (class extends nsZenMultiWindowFeature {
}
}
handleTabBeforeClose(tab, closeWindowWithLastTab = false) {
handleTabBeforeClose(tab, closeWindowWithLastTab) {
if (!this.workspaceEnabled || this.__contextIsDelete || this._removedByStartupPage) {
return null;
}
@@ -1144,7 +1144,8 @@ var gZenWorkspaces = new (class extends nsZenMultiWindowFeature {
let tabsPinned = tabs.filter(
(t) => !this.shouldOpenNewTabIfLastUnpinnedTabIsClosed || !t.pinned
);
const shouldCloseWindow = this.shouldCloseWindow() && closeWindowWithLastTab;
const shouldCloseWindow =
closeWindowWithLastTab != null ? closeWindowWithLastTab : this.shouldCloseWindow();
if (tabs.length === 1 && tabs[0] === tab) {
if (shouldCloseWindow) {
// We've already called beforeunload on all the relevant tabs if we get here,

View File

@@ -105,6 +105,7 @@ use serde::{Deserialize, Serialize};
use std::env;
use std::fs;
use std::path::PathBuf;
use std::collections::HashMap;
const STATIC_PREFS: &str = "../engine/modules/libpref/init/zen-static-prefs.inc";
const FIREFOX_PREFS: &str = "../engine/browser/app/profile/firefox.js";
@@ -308,6 +309,37 @@ fn prepare_zen_prefs() {
}
}
fn is_twilight_build() -> bool {
// Check if '"twilight"' is on .surfer/dynamicConfig.brand.json
let mut dynamic_config_path = env::current_dir().expect("Failed to get current directory");
dynamic_config_path.push(".surfer");
dynamic_config_path.push("dynamicConfig.brand.json");
if let Ok(content) = fs::read_to_string(&dynamic_config_path) {
return !content.contains("\"release\"");
}
false
}
fn get_env_values() -> HashMap<String, bool> {
let mut env_values = HashMap::new();
env_values.insert("IS_TWILIGHT".into(), is_twilight_build());
env_values
}
fn expand_pref_values(prefs: &mut [Preference]) {
let env_values = get_env_values();
for pref in prefs {
let mut new_value = pref.value.clone();
for (key, value) in &env_values {
let placeholder = format!("@{}@", key);
if new_value.contains(&placeholder) {
new_value = new_value.replace(&placeholder, if *value { "true" } else { "false" });
}
pref.value = new_value.clone();
}
}
}
fn main() {
let args: Vec<String> = env::args().collect();
let root_path = if args.len() > 1 {
@@ -318,6 +350,7 @@ fn main() {
env::set_current_dir(&root_path).expect("Failed to change directory");
prepare_zen_prefs();
let preferences = load_preferences();
let mut preferences = load_preferences();
expand_pref_values(&mut preferences);
write_preferences(&preferences);
}