Compare commits

..

1 Commits

Author SHA1 Message Date
mr. m
e176c1ba41 perf: Improve startup performance, b=no-bug, c=common 2026-01-10 20:21:20 +01:00
18 changed files with 227 additions and 370 deletions

View File

@@ -336,7 +336,7 @@ jobs:
MOZ_BUILD_DATE: ${{needs.buildid.outputs.buildids}}
use-sccache: ${{ inputs.use-sccache }}
mac-pgo-generate:
mac:
name: macOS build
uses: ./.github/workflows/macos-release-build.yml
permissions:
@@ -348,21 +348,6 @@ jobs:
release-branch: ${{ inputs.update_branch }}
MOZ_BUILD_DATE: ${{needs.buildid.outputs.buildids}}
use-sccache: ${{ inputs.use-sccache }}
generate-pgo-data: true
mac:
name: macOS build
uses: ./.github/workflows/macos-release-build.yml
permissions:
contents: write
secrets: inherit
needs: [build-data, buildid, mac-pgo-generate]
with:
build-version: ${{ needs.build-data.outputs.version }}
release-branch: ${{ inputs.update_branch }}
MOZ_BUILD_DATE: ${{needs.buildid.outputs.buildids}}
use-sccache: ${{ inputs.use-sccache }}
generate-pgo-data: false
mac-uni:
name: macOS build (Universal)

View File

@@ -22,11 +22,6 @@ on:
required: true
type: boolean
default: false
generate-pgo-data:
description: 'Generate PGO data'
required: false
type: boolean
default: false
jobs:
mac-build:
@@ -73,8 +68,8 @@ jobs:
- name: Setup Git
run: |
git config --global user.email "mr-cheffy@users.noreply.github.com"
git config --global user.name "mr-cheffy"
git config --global user.email "mauro-balades@users.noreply.github.com"
git config --global user.name "mauro-balades"
- name: Install system dependencies
run: |
@@ -125,20 +120,6 @@ jobs:
SURFER_COMPAT: ${{ matrix.arch }}
run: npm run import -- --verbose
- name: Download PGO data
if: ${{ inputs.generate-pgo-data == false }}
uses: actions/download-artifact@v4
with:
name: zen-macos-pgo-data-${{ matrix.arch }}
- name: Move PGO data
if: ${{ inputs.generate-pgo-data == false }}
run: |
mkdir -p $(echo ~)/artifact
mv $GITHUB_WORKSPACE/zen-macos-pgo-data-${{ matrix.arch }}/* $(echo ~)/artifact
chmod +x ~/artifact/en-US.log
chmod +x ~/artifact/merged.profdata
- name: Bootstrap
run: |
cd engine
@@ -161,7 +142,6 @@ jobs:
env:
SURFER_COMPAT: ${{ matrix.arch }}
ZEN_RELEASE_BRANCH: ${{ inputs.release-branch }}
ZEN_GENERATE_PGO_DATA: ${{ inputs.generate-pgo-data && '1' || '0' }}
run: |
export SURFER_PLATFORM="darwin"
if [[ -n ${{ inputs.MOZ_BUILD_DATE }} ]];then
@@ -170,7 +150,6 @@ jobs:
bash .github/workflows/src/release-build.sh
- name: Package
if: ${{ !inputs.generate-pgo-data }}
env:
SURFER_COMPAT: ${{ matrix.arch }}
ZEN_GA_DISABLE_PGO: true
@@ -184,7 +163,6 @@ jobs:
rm -rf ~/.zen-keys
- name: Rename artifacts
if: ${{ !inputs.generate-pgo-data }}
run: |
echo "Tarballing DMG"
set -ex
@@ -194,7 +172,6 @@ jobs:
- name: Upload dist dmg
uses: actions/upload-artifact@v4
if: ${{ !inputs.generate-pgo-data }}
with:
retention-days: 1
name: zen-${{ matrix.arch }}-apple-darwin-dist.dmg
@@ -202,7 +179,7 @@ jobs:
- name: Upload host mar
uses: actions/upload-artifact@v4
if: matrix.arch == 'aarch64' && !inputs.generate-pgo-data
if: matrix.arch == 'aarch64'
with:
retention-days: 1
name: zen-macos-host-mar
@@ -210,16 +187,8 @@ jobs:
- name: Upload platform.ini
uses: actions/upload-artifact@v4
if: matrix.arch == 'x86_64' && !inputs.generate-pgo-data
if: matrix.arch == 'x86_64'
with:
retention-days: 1
name: platform.ini
path: ./platform.ini
- name: Upload PGO data
uses: actions/upload-artifact@v4
if: inputs.generate-pgo-data
with:
retention-days: 1
name: zen-macos-pgo-data-${{ matrix.arch }}
path: ./zen-macos-pgo-data

View File

@@ -28,22 +28,3 @@ else
export ZEN_RELEASE=1
npm run build
fi
if test "$ZEN_GENERATE_PGO_DATA" = "1"; then
cd engine
export UPLOAD_PATH=../zen-macos-pgo-data
export MOZ_FETCHES_DIR=/Users/runner/.mozbuild
mkdir -p $UPLOAD_PATH
export JARLOG_FILE="en-US.log"
export LLVM_PROFDATA=$MOZ_FETCHES_DIR/clang/bin/llvm-profdata
set -v
./mach python build/pgo/profileserver.py --binary obj-*-apple-darwin/dist/*.app/Contents/MacOS/zen
mv merged.profdata $UPLOAD_PATH/
mv $JARLOG_FILE $UPLOAD_PATH/
cd ..
fi

View File

@@ -14,6 +14,15 @@ if test "$ZEN_RELEASE"; then
ac_add_options --enable-lto=cross,thin
fi
if test "$ZEN_RELEASE"; then
if test "$ZEN_GA_DISABLE_PGO"; then
export ZEN_DUMMY=1
else
export MOZ_PGO=1
ac_add_options MOZ_PGO=1
fi
fi
if test "$SURFER_COMPAT" = "x86_64"; then
ac_add_options --target=x86_64-apple-darwin
@@ -41,18 +50,9 @@ fi
# Keep using ld64 on PGO/LTO builds because of performance regressions when using lld.
# Mozilla sets "MOZ_LD64_KNOWN_GOOD" to true when they do automated builds with PGO/LTO on macOS.
# See https://searchfox.org/firefox-main/rev/e61d59b5c9a651fd7bf28043f87c0dc669833496/build/moz.configure/lto-pgo.configure#261
export MOZ_LD64_KNOWN_GOOD=1
ac_add_options --enable-linker=ld64
if test "$ZEN_RELEASE"; then
if ! test "$ZEN_GA_DISABLE_PGO"; then
if test "$ZEN_GENERATE_PGO_DATA"; then
mk_add_options "export MOZ_AUTOMATION_PACKAGE_GENERATED_SOURCES=0"
ac_add_options --enable-profile-generate=cross
else
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
fi
fi
fi
# export MOZ_LD64_KNOWN_GOOD=1
# ac_add_options --enable-linker=ld64
#
# if test "$ZEN_RELEASE"; then
# mk_add_options MOZ_MAKE_FLAGS="-j4"
# fi

View File

@@ -47,7 +47,9 @@ if test "$ZEN_CROSS_COMPILING"; then
ac_add_options --enable-profile-generate=cross
elif test "$SURFER_COMPAT" = "x86_64"; then
# Dont use PGO on aarch64 builds and the ZEN_GA_DISABLE_PGO flag is not set
if ! test "$ZEN_GA_DISABLE_PGO"; then
if test "$ZEN_GA_DISABLE_PGO"; then
export ZEN_DUMMY=1
else
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

View File

@@ -69,6 +69,3 @@
- name: browser.tabs.dragDrop.multiselectStacking
value: false
locked: true
- name: browser.tabs.notes.enabled
value: false

View File

@@ -10,6 +10,3 @@
- name: zen.window-sync.prefer-unsynced-windows
value: false
- name: zen.window-sync.open-link-in-new-unsynced-window
value: true

View File

@@ -1,5 +1,5 @@
diff --git a/browser/components/tabbrowser/content/tabbrowser.js b/browser/components/tabbrowser/content/tabbrowser.js
index 0eaca7a58e0026237b71b2ad515efe84d9e8c779..64b6fc581be1791ef9a750e03ab9a91c92325be3 100644
index 0eaca7a58e0026237b71b2ad515efe84d9e8c779..f3966d85049735538b24424f42d4a690eaf7bbec 100644
--- a/browser/components/tabbrowser/content/tabbrowser.js
+++ b/browser/components/tabbrowser/content/tabbrowser.js
@@ -398,6 +398,7 @@
@@ -591,7 +591,7 @@ index 0eaca7a58e0026237b71b2ad515efe84d9e8c779..64b6fc581be1791ef9a750e03ab9a91c
Glean.browserTabclose.timeAnim.cancel(aTab._closeTimeAnimTimerId);
aTab._closeTimeAnimTimerId = null;
- this._endRemoveTab(aTab);
+ if (animate && !gReduceMotion && !(gZenUIManager.testingEnabled && !gZenUIManager.profilingEnabled)) {
+ if (animate && !gReduceMotion && !gZenUIManager.testingEnabled) {
+ gZenVerticalTabsManager.animateTabClose(aTab, (animate && !gReduceMotion)).then(() => {
+ this._endRemoveTab(aTab);
+ });

View File

@@ -1,16 +1,8 @@
diff --git a/browser/modules/URILoadingHelper.sys.mjs b/browser/modules/URILoadingHelper.sys.mjs
index 9175fa820ad6bb75cd125fbfda2bf07d6dba4c90..62a1a62f304ec8c83e859196861025347e79ba46 100644
index 9175fa820ad6bb75cd125fbfda2bf07d6dba4c90..f673cfd15289401ae425256016bf51303063e0b2 100644
--- a/browser/modules/URILoadingHelper.sys.mjs
+++ b/browser/modules/URILoadingHelper.sys.mjs
@@ -225,6 +225,7 @@ function openInWindow(url, params, sourceWindow) {
features,
sa
);
+ win._zenStartupSyncFlag = Services.prefs.getBoolPref('zen.window-sync.open-link-in-new-unsynced-window') ? 'unsynced' : 'synced';
}
function openInCurrentTab(targetBrowser, url, uriObj, params) {
@@ -542,7 +543,7 @@ export const URILoadingHelper = {
@@ -542,7 +542,7 @@ export const URILoadingHelper = {
// page. If a load request bounces off for the currently selected tab,
// we'll open a new tab instead.
let tab = w.gBrowser.getTabForBrowser(targetBrowser);
@@ -19,7 +11,7 @@ index 9175fa820ad6bb75cd125fbfda2bf07d6dba4c90..62a1a62f304ec8c83e85919686102534
where = "tab";
targetBrowser = null;
} else if (
@@ -972,7 +973,7 @@ export const URILoadingHelper = {
@@ -972,7 +972,7 @@ export const URILoadingHelper = {
ignoreQueryString || replaceQueryString,
ignoreFragmentWhenComparing
);
@@ -28,7 +20,7 @@ index 9175fa820ad6bb75cd125fbfda2bf07d6dba4c90..62a1a62f304ec8c83e85919686102534
for (let i = 0; i < browsers.length; i++) {
let browser = browsers[i];
let browserCompare = cleanURL(
@@ -1018,7 +1019,7 @@ export const URILoadingHelper = {
@@ -1018,7 +1018,7 @@ export const URILoadingHelper = {
}
if (!doAdopt) {

View File

@@ -7,10 +7,15 @@
@namespace html 'http://www.w3.org/1999/xhtml';
:root {
--zen-settings-secondary-background: light-dark(
#f2f4f4,
color-mix(in srgb, var(--zen-colors-tertiary) 50%, #0f0f0f 50%)
);
--in-content-box-background: var(--zen-colors-tertiary) !important;
}
.main-content {
background: var(--zen-settings-secondary-background);
padding-top: 60px !important;
}
@@ -38,6 +43,35 @@ html|dialog {
animation: dialogPopin 0.2s ease-out;
}
groupbox {
background: light-dark(white, color-mix(in srgb, var(--zen-primary-color) 2%, #1b1b1b 98%));
padding-inline: unset !important;
padding: 20px 30px !important;
margin-bottom: 0 !important;
position: relative;
/* add shadow just to the sides */
box-shadow: 0 0 2px 0 rgba(0, 0, 0, 0.1);
}
.subcategory + groupbox,
#noFxaAccount,
#hasFxaAccount {
border-top-left-radius: 5px;
border-top-right-radius: 5px;
margin-top: 5px;
}
groupbox:has(+ script),
groupbox:last-of-type,
groupbox#pane-experimental-featureGates,
groupbox:has(+ .subcategory) {
border-bottom-left-radius: 5px !important;
border-bottom-right-radius: 5px !important;
/* add shadow just to bottom */
box-shadow: 0 0 2px 0 rgba(0, 0, 0, 0.1);
}
.sticky-inner-container {
display: none !important;
}

View File

@@ -1,13 +0,0 @@
diff --git a/build/moz.configure/toolchain.configure b/build/moz.configure/toolchain.configure
index 0fb4faa598072ccad47c376765a9433b40e27a6d..6ab448cc4202e5a3e871dfd753e95d76453758e5 100644
--- a/build/moz.configure/toolchain.configure
+++ b/build/moz.configure/toolchain.configure
@@ -1995,7 +1995,7 @@ def select_linker_tmpl(host_or_target):
# ensure consistent output.
env["LC_ALL"] = "C"
retcode, stdout, stderr = get_cmd_output(*cmd, env=env)
- if retcode == 1 and "Logging ld64 options" in stderr:
+ if retcode == 1 and "ld: unknown options: --version" in stderr:
kind = "ld64"
elif retcode != 0:

View File

@@ -5,6 +5,7 @@
import checkForZenUpdates, {
createWindowUpdateAnimation,
} from 'chrome://browser/content/ZenUpdates.mjs';
import { kDefaultSidebarWidth } from 'resource:///modules/ZenCustomizableUI.sys.mjs';
class ZenStartup {
#watermarkIgnoreElements = ['zen-toast-container'];
@@ -14,9 +15,11 @@ class ZenStartup {
init() {
this.openWatermark();
this.#initBrowserBackground();
this.#changeSidebarLocation();
this.#zenInitBrowserLayout();
gZenKeyboardShortcutsManager.beforeInit();
gZenWorkspaces.init().then(() => {
this.#initBrowserBackground();
this.#zenInitBrowserLayout();
});
}
#initBrowserBackground() {
@@ -36,7 +39,7 @@ class ZenStartup {
#zenInitBrowserLayout() {
if (this.#hasInitializedLayout) return;
this.#hasInitializedLayout = true;
gZenKeyboardShortcutsManager.beforeInit();
this.#changeSidebarLocation();
try {
const kNavbarItems = ['nav-bar', 'PersonalToolbar'];
const kNewContainerId = 'zen-appcontent-navbar-container';
@@ -54,16 +57,13 @@ class ZenStartup {
document.getElementById('zen-appcontent-wrapper').prepend(deckTemplate);
}
gZenWorkspaces.init();
setTimeout(() => {
gZenUIManager.init();
this.#checkForWelcomePage();
}, 0);
gZenUIManager.init();
this.#checkForWelcomePage();
} catch (e) {
console.error('ZenThemeModifier: Error initializing browser layout', e);
}
if (gBrowserInit.delayedStartupFinished) {
this.delayedStartupFinished();
this.#delayedStartupFinished();
} else {
Services.obs.addObserver(this, 'browser-delayed-startup-finished');
}
@@ -74,14 +74,12 @@ class ZenStartup {
// this window has finished painting and starting up.
if (aTopic == 'browser-delayed-startup-finished' && aSubject == window) {
Services.obs.removeObserver(this, 'browser-delayed-startup-finished');
this.delayedStartupFinished();
this.#delayedStartupFinished();
}
}
delayedStartupFinished() {
gZenWorkspaces.promiseInitialized.then(async () => {
await delayedStartupPromise;
await SessionStore.promiseAllWindowsRestored;
#delayedStartupFinished() {
gZenWorkspaces.promiseInitialized.then(() => {
delete gZenUIManager.promiseInitialized;
this.#initSearchBar();
gZenCompactModeManager.init();
@@ -141,6 +139,20 @@ class ZenStartup {
const browser = document.getElementById('browser');
browser.prepend(gNavToolbox);
// Set a splitter to navigator-toolbox
const splitter = document.createXULElement('splitter');
splitter.setAttribute('id', 'zen-sidebar-splitter');
splitter.setAttribute('orient', 'horizontal');
splitter.setAttribute('resizebefore', 'sibling');
splitter.setAttribute('resizeafter', 'none');
gNavToolbox.insertAdjacentElement('afterend', splitter);
splitter.addEventListener('dblclick', (e) => {
if (e.button !== 0) return;
gNavToolbox.style.width = kDefaultSidebarWidth;
gNavToolbox.setAttribute('width', kDefaultSidebarWidth);
});
const sidebarPanelWrapper = document.getElementById('tabbrowser-tabbox');
for (let id of kElementsToAppend) {
const elem = document.getElementById(id);
@@ -178,7 +190,7 @@ class ZenStartup {
window.gZenStartup = new ZenStartup();
window.addEventListener(
'MozBeforeInitialXULLayout',
'load',
() => {
gZenStartup.init();
},

View File

@@ -10,7 +10,6 @@ window.gZenUIManager = {
_hoverPausedForExpand: false,
_hasLoadedDOM: false,
testingEnabled: Services.prefs.getBoolPref('zen.testing.enabled', false),
profilingEnabled: Services.prefs.getBoolPref('zen.testing.profiling.enabled', false),
_lastClickPosition: null,
@@ -858,9 +857,7 @@ window.gZenVerticalTabsManager = {
!aItem ||
!gZenUIManager._hasLoadedDOM ||
!aItem.isConnected ||
// We do want to do some animations during testing with profiling enabled
// so we can capture and improve them.
(gZenUIManager.testingEnabled && !gZenUIManager.profilingEnabled) ||
gZenUIManager.testingEnabled ||
!gZenStartup.isReady ||
aItem.group?.hasAttribute('split-view-group')
) {

View File

@@ -4,6 +4,8 @@
import { AppConstants } from 'resource://gre/modules/AppConstants.sys.mjs';
export const kDefaultSidebarWidth = AppConstants.platform === 'macosx' ? '230px' : '186px';
export const ZenCustomizableUI = new (class {
constructor() {}
@@ -39,17 +41,8 @@ export const ZenCustomizableUI = new (class {
}
#addSidebarButtons(window) {
const kDefaultSidebarWidth = AppConstants.platform === 'macosx' ? '230px' : '186px';
const toolbox = window.gNavToolbox;
// Set a splitter to navigator-toolbox
const splitter = window.document.createXULElement('splitter');
splitter.setAttribute('id', 'zen-sidebar-splitter');
splitter.setAttribute('orient', 'horizontal');
splitter.setAttribute('resizebefore', 'sibling');
splitter.setAttribute('resizeafter', 'none');
toolbox.insertAdjacentElement('afterend', splitter);
const sidebarBox = window.MozXULElement.parseXULToFragment(`
<toolbar id="zen-sidebar-top-buttons"
fullscreentoolbar="true"
@@ -94,12 +87,6 @@ export const ZenCustomizableUI = new (class {
toolbox.style.width = width;
toolbox.setAttribute('width', width);
splitter.addEventListener('dblclick', (e) => {
if (e.button !== 0) return;
toolbox.style.width = kDefaultSidebarWidth;
toolbox.setAttribute('width', kDefaultSidebarWidth);
});
const newTab = window.document.getElementById('vertical-tabs-newtab-button');
newTab.classList.add('zen-sidebar-action-button');

View File

@@ -9,148 +9,143 @@
*
* FOR ANY WEBSITE THAT WOULD NEED TO USE THE ACCENT COLOR, ETC
*/
{
const { AppConstants } = ChromeUtils.importESModule(
'resource://gre/modules/AppConstants.sys.mjs'
);
const kZenThemePrefsList = [
'zen.theme.accent-color',
'zen.theme.border-radius',
'zen.theme.content-element-separation',
];
const kZenMaxElementSeparation = 12;
const kZenThemePrefsList = [
'zen.theme.accent-color',
'zen.theme.border-radius',
'zen.theme.content-element-separation',
];
const kZenMaxElementSeparation = 12;
/**
* ZenThemeModifier controls the application of theme data to the browser,
* for example, it injects the accent color to the document. This is used
* because we need a way to apply the accent color without having to worry about
* shadow roots not inheriting the accent color.
*
* note: It must be a Firefox builtin page with access to the browser's configuration
* and services.
*/
var ZenThemeModifier = {
_inMainBrowserWindow: false,
/**
* ZenThemeModifier controls the application of theme data to the browser,
* for example, it injects the accent color to the document. This is used
* because we need a way to apply the accent color without having to worry about
* shadow roots not inheriting the accent color.
*
* note: It must be a Firefox builtin page with access to the browser's configuration
* and services.
* Listen for theming updates from the LightweightThemeChild actor, and
* begin listening to changes in preferred color scheme.
*/
window.ZenThemeModifier = {
_inMainBrowserWindow: false,
init() {
this._inMainBrowserWindow = window.location.href == 'chrome://browser/content/browser.xhtml';
this.listenForEvents();
this.updateAllThemeBasics();
},
/**
* Listen for theming updates from the LightweightThemeChild actor, and
* begin listening to changes in preferred color scheme.
*/
init() {
this._inMainBrowserWindow = window.location.href == 'chrome://browser/content/browser.xhtml';
this.listenForEvents();
this.updateAllThemeBasics();
},
listenForEvents() {
var handleEvent = this.handleEvent.bind(this);
// Listen for changes in the accent color and border radius
for (let pref of kZenThemePrefsList) {
Services.prefs.addObserver(pref, handleEvent);
}
listenForEvents() {
var handleEvent = this.handleEvent.bind(this);
// Listen for changes in the accent color and border radius
for (let pref of kZenThemePrefsList) {
Services.prefs.addObserver(pref, handleEvent);
}
// Add fullscreen listener to update the theme when going in and out of fullscreen
const eventsForSeparation = [
'ZenViewSplitter:SplitViewDeactivated',
'ZenViewSplitter:SplitViewActivated',
'fullscreen',
'ZenCompactMode:Toggled',
];
const separationHandler = this.updateElementSeparation.bind(this);
for (let eventName of eventsForSeparation) {
window.addEventListener(eventName, separationHandler);
}
// Add fullscreen listener to update the theme when going in and out of fullscreen
const eventsForSeparation = [
'ZenViewSplitter:SplitViewDeactivated',
'ZenViewSplitter:SplitViewActivated',
'fullscreen',
'ZenCompactMode:Toggled',
];
const separationHandler = this.updateElementSeparation.bind(this);
for (let eventName of eventsForSeparation) {
window.addEventListener(eventName, separationHandler);
}
window.addEventListener(
'unload',
() => {
for (let pref of kZenThemePrefsList) {
Services.prefs.removeObserver(pref, handleEvent);
}
for (let eventName of eventsForSeparation) {
window.removeEventListener(eventName, separationHandler);
}
},
{ once: true }
);
},
handleEvent() {
// note: even might be undefined, but we shoudnt use it!
this.updateAllThemeBasics();
},
/**
* Update all theme basics, like the accent color.
*/
async updateAllThemeBasics() {
this.updateAccentColor();
this.updateBorderRadius();
this.updateElementSeparation();
},
updateBorderRadius() {
const borderRadius = Services.prefs.getIntPref('zen.theme.border-radius', -1);
// -1 is the default value, will use platform-native values
// otherwise, use the custom value
if (borderRadius == -1) {
if (AppConstants.platform == 'macosx') {
const targetRadius = window.matchMedia('(-moz-mac-tahoe-theme)').matches ? 15 : 10;
document.documentElement.style.setProperty('--zen-border-radius', targetRadius + 'px');
} else if (AppConstants.platform == 'linux') {
// Linux uses GTK CSD titlebar radius, default to 8px
document.documentElement.style.setProperty(
'--zen-border-radius',
'env(-moz-gtk-csd-titlebar-radius, 8px)'
);
} else {
// Windows defaults to 8px
document.documentElement.style.setProperty('--zen-border-radius', '8px');
window.addEventListener(
'unload',
() => {
for (let pref of kZenThemePrefsList) {
Services.prefs.removeObserver(pref, handleEvent);
}
for (let eventName of eventsForSeparation) {
window.removeEventListener(eventName, separationHandler);
}
},
{ once: true }
);
},
handleEvent() {
// note: even might be undefined, but we shoudnt use it!
this.updateAllThemeBasics();
},
/**
* Update all theme basics, like the accent color.
*/
async updateAllThemeBasics() {
this.updateAccentColor();
this.updateBorderRadius();
this.updateElementSeparation();
},
updateBorderRadius() {
const borderRadius = Services.prefs.getIntPref('zen.theme.border-radius', -1);
// -1 is the default value, will use platform-native values
// otherwise, use the custom value
if (borderRadius == -1) {
if (AppConstants.platform == 'macosx') {
const targetRadius = window.matchMedia('(-moz-mac-tahoe-theme)').matches ? 15 : 10;
document.documentElement.style.setProperty('--zen-border-radius', targetRadius + 'px');
} else if (AppConstants.platform == 'linux') {
// Linux uses GTK CSD titlebar radius, default to 8px
document.documentElement.style.setProperty(
'--zen-border-radius',
'env(-moz-gtk-csd-titlebar-radius, 8px)'
);
} else {
// Use the overridden value
document.documentElement.style.setProperty('--zen-border-radius', borderRadius + 'px');
// Windows defaults to 8px
document.documentElement.style.setProperty('--zen-border-radius', '8px');
}
},
} else {
// Use the overridden value
document.documentElement.style.setProperty('--zen-border-radius', borderRadius + 'px');
}
},
updateElementSeparation() {
const kMinElementSeparation = 0.1; // in px
let separation = this.elementSeparation;
if (
document.documentElement.hasAttribute('inFullscreen') &&
window.gZenCompactModeManager?.preference &&
!document.getElementById('tabbrowser-tabbox')?.hasAttribute('zen-split-view') &&
Services.prefs.getBoolPref('zen.view.borderless-fullscreen', true)
) {
separation = 0;
}
// In order to still use it on fullscreen, even if it's 0px, add .1px (almost invisible)
separation = Math.max(kMinElementSeparation, separation);
document.documentElement.style.setProperty('--zen-element-separation', separation + 'px');
if (separation == kMinElementSeparation) {
document.documentElement.setAttribute('zen-no-padding', true);
} else {
document.documentElement.removeAttribute('zen-no-padding');
}
},
updateElementSeparation() {
const kMinElementSeparation = 0.1; // in px
let separation = this.elementSeparation;
if (
document.documentElement.hasAttribute('inFullscreen') &&
window.gZenCompactModeManager?.preference &&
!document.getElementById('tabbrowser-tabbox')?.hasAttribute('zen-split-view') &&
Services.prefs.getBoolPref('zen.view.borderless-fullscreen', true)
) {
separation = 0;
}
// In order to still use it on fullscreen, even if it's 0px, add .1px (almost invisible)
separation = Math.max(kMinElementSeparation, separation);
document.documentElement.style.setProperty('--zen-element-separation', separation + 'px');
if (separation == kMinElementSeparation) {
document.documentElement.setAttribute('zen-no-padding', true);
} else {
document.documentElement.removeAttribute('zen-no-padding');
}
},
get elementSeparation() {
return Math.min(
Services.prefs.getIntPref('zen.theme.content-element-separation'),
kZenMaxElementSeparation
);
},
get elementSeparation() {
return Math.min(
Services.prefs.getIntPref('zen.theme.content-element-separation'),
kZenMaxElementSeparation
);
},
/**
* Update the accent color.
*/
updateAccentColor() {
const accentColor = Services.prefs.getStringPref('zen.theme.accent-color');
document.documentElement.style.setProperty('--zen-primary-color', accentColor);
},
};
/**
* Update the accent color.
*/
updateAccentColor() {
const accentColor = Services.prefs.getStringPref('zen.theme.accent-color');
document.documentElement.style.setProperty('--zen-primary-color', accentColor);
},
};
if (typeof Services !== 'undefined') ZenThemeModifier.init();
}
if (typeof Services !== 'undefined') ZenThemeModifier.init();

View File

@@ -467,8 +467,6 @@ window.gZenCompactModeManager = {
});
}
this.sidebar.style.removeProperty('margin-right');
this.sidebar.style.removeProperty('margin-left');
this.sidebar.style.removeProperty('transition');
this.sidebar.style.removeProperty('transform');
this.sidebar.style.removeProperty('point-events');

View File

@@ -15,16 +15,9 @@ ChromeUtils.defineESModuleGetters(lazy, {
SessionSaver: 'resource:///modules/sessionstore/SessionSaver.sys.mjs',
setTimeout: 'resource://gre/modules/Timer.sys.mjs',
gWindowSyncEnabled: 'resource:///modules/zen/ZenWindowSync.sys.mjs',
DeferredTask: 'resource://gre/modules/DeferredTask.sys.mjs',
});
XPCOMUtils.defineLazyPreferenceGetter(lazy, 'gShouldLog', 'zen.session-store.log', true);
XPCOMUtils.defineLazyPreferenceGetter(
lazy,
'gMaxSessionBackups',
'zen.session-store.max-backups',
10
);
// Note that changing this hidden pref will make the previous session file
// unused, causing a new session file to be created on next write.
@@ -37,10 +30,6 @@ const MIGRATION_PREF = 'zen.ui.migration.session-manager-restore';
// 'browser.startup.page' preference value to resume the previous session.
const BROWSER_STARTUP_RESUME_SESSION = 3;
// The amount of time (in milliseconds) to wait for our backup regeneration
// debouncer to kick off a regeneration.
const REGENERATION_DEBOUNCE_RATE_MS = 20 * 60 * 1000; // 20 minutes
/**
* Class representing the sidebar object stored in the session file.
* This object holds all the data related to tabs, groups, folders
@@ -69,18 +58,13 @@ export class nsZenSessionManager {
* @type {nsZenSidebarObject}
*/
#sidebarObject = new nsZenSidebarObject();
/**
* A deferred task to create backups of the session file.
*/
#deferredBackupTask = null;
// Called from SessionComponents.manifest on app-startup
init() {
this.log('Initializing session manager');
let profileDir = Services.dirsvc.get('ProfD', Ci.nsIFile).path;
let backupFile = null;
if (SHOULD_BACKUP_FILE) {
backupFile = PathUtils.join(this.#backupFolderPath, FILE_NAME);
backupFile = PathUtils.join(profileDir, 'zen-sessions-backup', FILE_NAME);
}
let filePath = PathUtils.join(profileDir, FILE_NAME);
this.#file = new JSONFile({
@@ -88,9 +72,6 @@ export class nsZenSessionManager {
compression: SHOULD_COMPRESS_FILE ? 'lz4' : undefined,
backupFile,
});
this.#deferredBackupTask = new lazy.DeferredTask(async () => {
await this.#createBackupsIfNeeded();
}, REGENERATION_DEBOUNCE_RATE_MS);
}
log(...args) {
@@ -99,11 +80,6 @@ export class nsZenSessionManager {
}
}
get #backupFolderPath() {
let profileDir = Services.dirsvc.get('ProfD', Ci.nsIFile).path;
return PathUtils.join(profileDir, 'zen-sessions-backup');
}
/**
* Gets the spaces data from the Places database for migration.
* This is only called once during the first run after updating
@@ -268,66 +244,9 @@ export class nsZenSessionManager {
// quitting the app.
this.#file.data = this.#sidebar;
this.#file.saveSoon();
this.#debounceRegeneration();
this.log(`Saving Zen session data with ${this.#sidebar.tabs?.length || 0} tabs`);
}
/**
* Called when the last known backup should be deleted and a new one
* created. This uses the #deferredBackupTask to debounce clusters of
* events that might cause such a regeneration to occur.
*/
#debounceRegeneration() {
this.#deferredBackupTask.disarm();
this.#deferredBackupTask.arm();
}
/**
* Creates backups of the session file if needed. We only keep
* a limited number of backups to avoid using too much disk space.
* The way we are doing this is by replacing the file for today's
* date if it already exists, otherwise we create a new one.
* We then delete the oldest backups if we exceed the maximum
* number of backups allowed.
*
* We run the next backup creation after a delay or when idling,
* to avoid blocking the main thread during session saves.
*/
async #createBackupsIfNeeded() {
if (!SHOULD_BACKUP_FILE) {
return;
}
try {
const today = new Date();
const backupFolder = this.#backupFolderPath;
await IOUtils.makeDirectory(backupFolder, {
ignoreExisting: true,
createAncestors: true,
});
const todayFileName = `zen-sessions-${today.getFullYear()}-${(today.getMonth() + 1)
.toString()
.padStart(2, '0')}-${today.getDate().toString().padStart(2, '0')}.json${
SHOULD_COMPRESS_FILE ? 'lz4' : ''
}`;
const todayFilePath = PathUtils.join(backupFolder, todayFileName);
const sessionFilePath = this.#file.path;
this.log(`Backing up session file to ${todayFileName}`);
await IOUtils.copy(sessionFilePath, todayFilePath, { noOverwrite: false });
// Now we need to check if we have exceeded the maximum
// number of backups allowed, and delete the oldest ones
// if needed.
let files = await IOUtils.getChildren(backupFolder);
files = files.filter((file) => file.startsWith('zen-sessions-')).sort();
for (let i = 0; i < files.length - lazy.gMaxSessionBackups; i++) {
const fileToDelete = PathUtils.join(backupFolder, files[i].name);
this.log(`Deleting old backup file ${files[i].name}`);
await IOUtils.remove(fileToDelete);
}
} catch (e) {
console.error('ZenSessionManager: Failed to create session file backups', e);
}
}
/**
* Saves the session data for a closed window if it meets the criteria.
* See SessionStoreInternal.maybeSaveClosedWindow for more details.

View File

@@ -777,7 +777,12 @@ class nsZenWorkspaces {
}
get workspaceEnabled() {
return this.shouldHaveWorkspaces && !window.closed;
if (typeof this._workspaceEnabled === 'undefined') {
this._workspaceEnabled =
this.shouldHaveWorkspaces &&
!Services.prefs.getBoolPref('zen.testing.profiling.enabled', false);
}
return this._workspaceEnabled && !window.closed;
}
getActiveWorkspaceFromCache() {