diff --git a/.github/workflows/linux-release-build.yml b/.github/workflows/linux-release-build.yml index b92181af2..5e5a32bff 100644 --- a/.github/workflows/linux-release-build.yml +++ b/.github/workflows/linux-release-build.yml @@ -34,7 +34,6 @@ jobs: env: SCCACHE_GHA_ENABLED: ${{ inputs.use-sccache && 'true' || 'false' }} CARGO_TERM_COLOR: always - RUSTC_WRAPPER: ${{ inputs.use-sccache && 'sccache' || '' }} CARGO_INCREMENTAL: 0 name: Build Linux - ${{ matrix.arch }} @@ -120,6 +119,38 @@ jobs: ./mach --no-interactive bootstrap --application-choice browser cd .. + - name: Build (PGO stage 1 - generate) + if: ${{ matrix.arch == 'x86_64' }} + env: + SURFER_COMPAT: ${{ matrix.arch }} + ZEN_RELEASE_BRANCH: ${{ inputs.release-branch }} + ZEN_GA_GENERATE_PROFILE: 1 + ZEN_SAFEBROWSING_API_KEY: ${{ secrets.ZEN_SAFEBROWSING_API_KEY }} + ZEN_MOZILLA_API_KEY: ${{ secrets.ZEN_MOZILLA_API_KEY }} + ZEN_GOOGLE_LOCATION_SERVICE_API_KEY: ${{ secrets.ZEN_GOOGLE_LOCATION_SERVICE_API_KEY }} + continue-on-error: true + run: | + export SURFER_PLATFORM="linux" + if [[ -n ${{ inputs.MOZ_BUILD_DATE }} ]];then + export MOZ_BUILD_DATE=${{ inputs.MOZ_BUILD_DATE }} + fi + bash .github/workflows/src/release-build.sh + + - name: Generate PGO profile data + if: ${{ matrix.arch == 'x86_64' }} + run: | + set -x + export DISPLAY=:2 + export LLVM_PROFDATA="$HOME/.mozbuild/clang/bin/llvm-profdata" + export JARLOG_FILE=en-US.log + mkdir -p "$HOME/artifact" + cd engine + ./mach python ../scripts/download_pgo_extended_corpus.py + ./mach package + ./mach python build/pgo/profileserver.py --extended-corpus ./pgo-extended-corpus + mv merged.profdata "$HOME/artifact/merged.profdata" + mv en-US.log "$HOME/artifact/en-US.log" + - name: Build env: SURFER_COMPAT: ${{ matrix.arch }} diff --git a/.github/workflows/macos-release-build.yml b/.github/workflows/macos-release-build.yml index a14aac90c..4be480468 100644 --- a/.github/workflows/macos-release-build.yml +++ b/.github/workflows/macos-release-build.yml @@ -35,7 +35,6 @@ jobs: env: SCCACHE_GHA_ENABLED: ${{ inputs.use-sccache && 'true' || 'false' }} CARGO_TERM_COLOR: always - RUSTC_WRAPPER: ${{ inputs.use-sccache && 'sccache' || '' }} CARGO_INCREMENTAL: 0 steps: - name: Checkout repository @@ -134,6 +133,36 @@ jobs: - name: Build language packs run: sh scripts/download-language-packs.sh + - name: Build Zen (PGO stage 1 - generate) + env: + SURFER_COMPAT: ${{ matrix.arch }} + ZEN_RELEASE_BRANCH: ${{ inputs.release-branch }} + ZEN_GA_GENERATE_PROFILE: 1 + ZEN_SAFEBROWSING_API_KEY: ${{ secrets.ZEN_SAFEBROWSING_API_KEY }} + ZEN_MOZILLA_API_KEY: ${{ secrets.ZEN_MOZILLA_API_KEY }} + ZEN_GOOGLE_LOCATION_SERVICE_API_KEY: ${{ secrets.ZEN_GOOGLE_LOCATION_SERVICE_API_KEY }} + run: | + export SURFER_PLATFORM="darwin" + if [[ -n ${{ inputs.MOZ_BUILD_DATE }} ]];then + export MOZ_BUILD_DATE=${{ inputs.MOZ_BUILD_DATE }} + fi + bash .github/workflows/src/release-build.sh + + - name: Generate PGO profile data + env: + SURFER_COMPAT: ${{ matrix.arch }} + run: | + set -x + export LLVM_PROFDATA="$HOME/.mozbuild/clang/bin/llvm-profdata" + export JARLOG_FILE=en-US.log + mkdir -p "$HOME/artifact" + cd engine + ./mach python ../scripts/download_pgo_extended_corpus.py + ./mach package + ./mach python build/pgo/profileserver.py --extended-corpus ./pgo-extended-corpus + mv merged.profdata "$HOME/artifact/merged.profdata" + mv en-US.log "$HOME/artifact/en-US.log" + - name: Build Zen env: SURFER_COMPAT: ${{ matrix.arch }} diff --git a/.github/workflows/macos-universal-release-build.yml b/.github/workflows/macos-universal-release-build.yml index dbc2130f0..b4fea39a0 100644 --- a/.github/workflows/macos-universal-release-build.yml +++ b/.github/workflows/macos-universal-release-build.yml @@ -93,6 +93,7 @@ jobs: env: SURFER_MOZCONFIG_ONLY: true ZEN_RELEASE: 1 + ZEN_GA_DISABLE_PGO: true run: | npm run build cd engine @@ -232,6 +233,7 @@ jobs: - name: Package for mar env: JUST_MAR: true + ZEN_GA_DISABLE_PGO: true run: | # we don't need it anymore set -ex diff --git a/.github/workflows/twilight-release-schedule.yml b/.github/workflows/twilight-release-schedule.yml index de9e3ff1e..5b50f55c3 100644 --- a/.github/workflows/twilight-release-schedule.yml +++ b/.github/workflows/twilight-release-schedule.yml @@ -20,7 +20,7 @@ jobs: with: create_release: ${{ github.event_name != 'workflow_dispatch' && true || inputs.create_release }} update_branch: twilight - use-sccache: false + use-sccache: true update_version: false post-build: diff --git a/.github/workflows/windows-profile-build.yml b/.github/workflows/windows-profile-build.yml index 740c5fd3f..0984f2d37 100644 --- a/.github/workflows/windows-profile-build.yml +++ b/.github/workflows/windows-profile-build.yml @@ -93,7 +93,8 @@ jobs: echo "cd $workspace_dir" '' >> mozilla-build-run.sh echo 'export PATH=/c/mozilla-build/msys2/usr/bin:$PATH' '' >> mozilla-build-run.sh echo './mach --no-interactive bootstrap --application-choice browser' '' >> mozilla-build-run.sh - echo 'LLVM_PROFDATA=/c/Users/runneradmin/.mozbuild/clang/bin/llvm-profdata.exe JARLOG_FILE=en-US.log ./mach python build/pgo/profileserver.py --binary /c/artifact/zen/zen.exe' '' >> mozilla-build-run.sh + echo './mach python ../scripts/download_pgo_extended_corpus.py' '' >> mozilla-build-run.sh + echo 'LLVM_PROFDATA=/c/Users/runneradmin/.mozbuild/clang/bin/llvm-profdata.exe JARLOG_FILE=en-US.log ./mach python build/pgo/profileserver.py --binary /c/artifact/zen/zen.exe --extended-corpus ./pgo-extended-corpus --' '' >> mozilla-build-run.sh C:\mozilla-build\start-shell.bat $workspace_dir_current\mozilla-build-run.sh - name: Move profile data diff --git a/.github/workflows/windows-release-build.yml b/.github/workflows/windows-release-build.yml index dc054aef3..d2570dbfd 100644 --- a/.github/workflows/windows-release-build.yml +++ b/.github/workflows/windows-release-build.yml @@ -39,7 +39,6 @@ jobs: env: SCCACHE_GHA_ENABLED: ${{ inputs.use-sccache && 'true' || 'false' }} CARGO_TERM_COLOR: always - RUSTC_WRAPPER: ${{ inputs.use-sccache && 'sccache' || '' }} CARGO_INCREMENTAL: 0 strategy: fail-fast: false diff --git a/configs/common/mozconfig b/configs/common/mozconfig index ddb795b86..22b8e95c5 100644 --- a/configs/common/mozconfig +++ b/configs/common/mozconfig @@ -26,13 +26,15 @@ export MOZ_INCLUDE_SOURCE_INFO=1 ac_add_options --enable-application=browser -# Anything except 'SCCACHE_GHA_ENABLED == false' -if ! test "$SCCACHE_GHA_ENABLED" = "false"; then +if test "$SCCACHE_GHA_ENABLED" = "true"; then if test -x "$(command -v sccache)"; then ac_add_options --with-ccache=sccache elif test -f "$HOME/.mozbuild/sccache/sccache"; then ac_add_options --with-ccache="$HOME"/.mozbuild/sccache/sccache fi + + mk_add_options 'export RUSTC_WRAPPER=sccache' + mk_add_options 'export CCACHE_CPP2=yes' fi # add API keys if it exists on a file @@ -50,8 +52,7 @@ fi if test "$ZEN_RELEASE"; then - # TODO: Make this successful in builds - # ac_add_options --enable-clang-plugin + ac_add_options --enable-clang-plugin ac_add_options --enable-bootstrap=-sccache ac_add_options --enable-optimize diff --git a/configs/linux/mozconfig b/configs/linux/mozconfig index b15dcd399..9816e7580 100644 --- a/configs/linux/mozconfig +++ b/configs/linux/mozconfig @@ -18,8 +18,14 @@ if test "$ZEN_RELEASE"; then # Enable Profile Guided Optimization if ! test "$ZEN_GA_DISABLE_PGO"; then - export MOZ_PGO=1 - ac_add_options MOZ_PGO=1 + if test "$ZEN_GA_GENERATE_PROFILE"; 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 elif test "$SURFER_COMPAT" = "aarch64"; then ac_add_options --target=aarch64-linux-gnu diff --git a/configs/macos/mozconfig b/configs/macos/mozconfig index 317f6b4e8..3dd601a49 100644 --- a/configs/macos/mozconfig +++ b/configs/macos/mozconfig @@ -15,11 +15,15 @@ if test "$ZEN_RELEASE"; then 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 + if ! test "$ZEN_GA_DISABLE_PGO"; then + if test "$ZEN_GA_GENERATE_PROFILE"; 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 @@ -30,7 +34,6 @@ if test "$SURFER_COMPAT" = "x86_64"; then ac_add_options --enable-wasm-avx fi else - ac_add_options --enable-clang-plugin ac_add_options --target=aarch64-apple-darwin if test "$ZEN_RELEASE"; then diff --git a/configs/windows/mozconfig b/configs/windows/mozconfig index 9290c08bc..065ed1291 100644 --- a/configs/windows/mozconfig +++ b/configs/windows/mozconfig @@ -22,10 +22,6 @@ if test "$ZEN_CROSS_COMPILING"; then fi fi -# We wrongly detect ccache on windows, which leads to build failures. -# This line should be removed once the detection is fixed. -ac_add_options --without-ccache - if test "$SURFER_COMPAT" = "x86_64"; then ac_add_options --target=x86_64-pc-windows-msvc ac_add_options --enable-eme=widevine,wmfcdm diff --git a/prefs/zen/split-view.yaml b/prefs/zen/split-view.yaml index aa02b6def..a950cb328 100644 --- a/prefs/zen/split-view.yaml +++ b/prefs/zen/split-view.yaml @@ -18,4 +18,4 @@ value: 350 - name: zen.splitView.drag-over-split-threshold - value: 25 + value: 40 diff --git a/scripts/download_pgo_extended_corpus.py b/scripts/download_pgo_extended_corpus.py new file mode 100644 index 000000000..f8a06190a --- /dev/null +++ b/scripts/download_pgo_extended_corpus.py @@ -0,0 +1,59 @@ +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +import yaml +import os +import requests +import tarfile +import hashlib + +EXTENDED_CORPUS_KEY="pgo-extended-corpus" +TASKCLUSTER_PATH=os.path.join("taskcluster", "kinds", "fetch", "benchmarks.yml") + +def download_corpus(corpus_url, expected_sha256, output_path): + response = requests.get(corpus_url, stream=True) + response.raise_for_status() + + os.makedirs(output_path, exist_ok=True) + archive_path = os.path.join(output_path, "corpus.tar.gz") + + with open(archive_path, "wb") as f: + for chunk in response.iter_content(chunk_size=8192): + f.write(chunk) + + # Verify the SHA256 checksum + sha256 = hashlib.sha256() + with open(archive_path, "rb") as f: + for chunk in iter(lambda: f.read(8192), b""): + sha256.update(chunk) + if sha256.hexdigest() != expected_sha256: + os.remove(archive_path) + raise ValueError("SHA256 checksum does not match expected value.") + + print("Checksum verified ({}). Extracting corpus...".format(expected_sha256)) + with tarfile.open(archive_path, "r:gz") as tar: + tar.extractall(path=output_path) + + # rename "JetStream-[id]" to just "JetStream" + for item in os.listdir(output_path): + if item.startswith("JetStream-"): + os.rename(os.path.join(output_path, item), os.path.join(output_path, "JetStream")) + break + + # Clean up the downloaded archive + os.remove(archive_path) + print(f"Corpus downloaded and extracted to: {output_path}") + +def main(): + print("\n------------------------------------\n") + print("Fetching PGO extended corpus information from Taskcluster...") + with open(TASKCLUSTER_PATH, "r", encoding="utf-8") as f: + benchmarks = yaml.safe_load(f) + corpus_url = benchmarks[EXTENDED_CORPUS_KEY] + fetch_info = corpus_url["fetch"] + download_corpus(fetch_info["url"], fetch_info["sha256"], "pgo-extended-corpus") + print("\n------------------------------------\n") + +if __name__ == "__main__": + main() diff --git a/src/browser/base/content/browser-box-inc-xhtml.patch b/src/browser/base/content/browser-box-inc-xhtml.patch index 938d1881c..6f5f7ee91 100644 --- a/src/browser/base/content/browser-box-inc-xhtml.patch +++ b/src/browser/base/content/browser-box-inc-xhtml.patch @@ -1,32 +1,40 @@ diff --git a/browser/base/content/browser-box.inc.xhtml b/browser/base/content/browser-box.inc.xhtml -index d58fcdf99843d110b708f3fbf9fb317787fadfcf..ba37068c52b24c6ebcb835c59b43ca2f1621a001 100644 +index d58fcdf99843d110b708f3fbf9fb317787fadfcf..cfc2aad902641609c3804e615c4cb66ce65299b7 100644 --- a/browser/base/content/browser-box.inc.xhtml +++ b/browser/base/content/browser-box.inc.xhtml -@@ -3,6 +3,9 @@ +@@ -3,12 +3,22 @@ # file, You can obtain one at http://mozilla.org/MPL/2.0/. ++#include navigator-toolbox.inc.xhtml + + + + diff --git a/src/browser/base/content/browser-xhtml.patch b/src/browser/base/content/browser-xhtml.patch index 9abce4268..0dfd8f916 100644 --- a/src/browser/base/content/browser-xhtml.patch +++ b/src/browser/base/content/browser-xhtml.patch @@ -1,5 +1,5 @@ diff --git a/browser/base/content/browser.xhtml b/browser/base/content/browser.xhtml -index b42287485c2baeabe831b0d54c6f09330b0caabd..6426bb6742401470e4e48b4049cd365e2a5952e8 100644 +index b42287485c2baeabe831b0d54c6f09330b0caabd..e404c2e028e24eb4fa9b97f143ba476c1b1461fd 100644 --- a/browser/base/content/browser.xhtml +++ b/browser/base/content/browser.xhtml @@ -19,6 +19,7 @@ @@ -21,12 +21,12 @@ index b42287485c2baeabe831b0d54c6f09330b0caabd..6426bb6742401470e4e48b4049cd365e # All sets except for popupsets (commands, keys, and stringbundles) -@@ -135,9 +138,11 @@ +@@ -135,9 +138,10 @@ +-#include navigator-toolbox.inc.xhtml + - #include navigator-toolbox.inc.xhtml #include browser-box.inc.xhtml + diff --git a/src/browser/base/content/zen-assets.inc.xhtml b/src/browser/base/content/zen-assets.inc.xhtml index b88b74cfe..f67426009 100644 --- a/src/browser/base/content/zen-assets.inc.xhtml +++ b/src/browser/base/content/zen-assets.inc.xhtml @@ -39,15 +39,3 @@ # file so that ESLint works correctly: # tools/lint/eslint/eslint-plugin-mozilla/lib/environments/browser-window.js - -# Scripts used all over the browser - - - - - - -s - - - diff --git a/src/browser/base/content/zen-preloaded.inc.xhtml b/src/browser/base/content/zen-preloaded.inc.xhtml index d7893b9e6..dd7e3e9e0 100644 --- a/src/browser/base/content/zen-preloaded.inc.xhtml +++ b/src/browser/base/content/zen-preloaded.inc.xhtml @@ -8,5 +8,3 @@ - - \ No newline at end of file diff --git a/src/build/moz-configure/lto-pgo-configure.patch b/src/build/moz-configure/lto-pgo-configure.patch index 5870f5f98..f91a32571 100644 --- a/src/build/moz-configure/lto-pgo-configure.patch +++ b/src/build/moz-configure/lto-pgo-configure.patch @@ -1,8 +1,16 @@ diff --git a/build/moz.configure/lto-pgo.configure b/build/moz.configure/lto-pgo.configure -index df2b0bf0081edfdc2c7bccaefc780d2b0c6555ff..8619fc5fbf284c7a5660d5b7a77494404e448e44 100644 +index df2b0bf0081edfdc2c7bccaefc780d2b0c6555ff..53a3b55de7650799e3730372e72ad7b4bb2eea03 100644 --- a/build/moz.configure/lto-pgo.configure +++ b/build/moz.configure/lto-pgo.configure -@@ -256,7 +256,6 @@ option( +@@ -234,6 +234,7 @@ def moz_pgo_rust(pgo, profile_use, profile_generate, c_compiler): + if c_compiler.type == "gcc": + die("Cannot use cross-language PGO with GCC.") + ++ log.info("Enabling cross-language PGO for Rust") + return True + + +@@ -256,7 +257,6 @@ option( help="Indicate that ld64 is free of symbol aliasing bugs", ) diff --git a/src/zen/common/ZenPreloadedScripts.js b/src/zen/common/ZenPreloadedScripts.js index 01fa01ddd..6c4265ce9 100644 --- a/src/zen/common/ZenPreloadedScripts.js +++ b/src/zen/common/ZenPreloadedScripts.js @@ -7,13 +7,52 @@ { Services.scriptloader.loadSubScript("chrome://browser/content/zen-components/ZenSpaceBookmarksStorage.js", this); - ChromeUtils.importESModule("chrome://browser/content/ZenStartup.mjs", { global: "current" }); - ChromeUtils.importESModule("resource:///modules/zen/ZenSpaceManager.mjs", { global: "current" }); - ChromeUtils.importESModule("chrome://browser/content/zen-components/ZenCompactMode.mjs", { global: "current" }); - ChromeUtils.importESModule("chrome://browser/content/ZenUIManager.mjs", { global: "current" }); - ChromeUtils.importESModule("chrome://browser/content/zen-components/ZenMods.mjs", { global: "current" }); - ChromeUtils.importESModule("chrome://browser/content/zen-components/ZenKeyboardShortcuts.mjs", { global: "current" }); - ChromeUtils.importESModule("chrome://browser/content/zen-components/ZenSessionStore.mjs", { global: "current" }); + let scripts = [ + "chrome://browser/content/ZenStartup.mjs", + "resource:///modules/zen/ZenSpaceManager.mjs", + "chrome://browser/content/zen-components/ZenCompactMode.mjs", + "chrome://browser/content/ZenUIManager.mjs", + "chrome://browser/content/zen-components/ZenMods.mjs", + "chrome://browser/content/zen-components/ZenKeyboardShortcuts.mjs", + "chrome://browser/content/zen-components/ZenSessionStore.mjs", + "chrome://browser/content/zen-components/ZenMediaController.mjs", + "chrome://browser/content/zen-components/ZenGlanceManager.mjs", + "chrome://browser/content/zen-components/ZenPinnedTabManager.mjs", + "chrome://browser/content/zen-components/ZenViewSplitter.mjs", + "chrome://browser/content/zen-components/ZenFolders.mjs", + "chrome://browser/content/zen-components/ZenEmojiPicker.mjs", + "chrome://browser/content/zen-components/ZenLiveFoldersUI.mjs", + ]; + + for (let script of scripts) { + ChromeUtils.importESModule(script, { global: "current" }); + } + + let customZenElements = [ + ["zen-folder", "chrome://browser/content/zen-components/ZenFolder.mjs"], + ["zen-download-animation", "chrome://browser/content/zen-components/ZenDownloadAnimation.mjs"], + ["zen-workspace-creation", "resource:///modules/zen/ZenSpaceCreation.mjs"], + ["zen-workspace", "resource:///modules/zen/ZenSpace.mjs"], + ["zen-workspace-icons", "resource:///modules/zen/ZenSpaceIcons.mjs"] + ]; + + document.addEventListener( + "DOMContentLoaded", + () => { + // Only sync-import widgets once the document has loaded. If a widget is + // used before DOMContentLoaded it will be imported and upgraded when + // registering the customElements.setElementCreationCallback(). + for (let [tag, script] of customZenElements) { + customElements.setElementCreationCallback( + tag, + function customElementCreationCallback() { + ChromeUtils.importESModule(script, { global: "current" }); + } + ); + } + }, + { once: true } + ); Services.scriptloader.loadSubScript("chrome://browser/content/zen-components/ZenDragAndDrop.js", this); } diff --git a/src/zen/common/modules/ZenStartup.mjs b/src/zen/common/modules/ZenStartup.mjs index a0611a8df..dd37719f8 100644 --- a/src/zen/common/modules/ZenStartup.mjs +++ b/src/zen/common/modules/ZenStartup.mjs @@ -17,7 +17,6 @@ class ZenStartup { init() { this.openWatermark(); - this.#changeSidebarLocation(); this.#zenInitBrowserLayout(); } @@ -147,21 +146,6 @@ class ZenStartup { }); } - #changeSidebarLocation() { - const kElementsToAppend = ["sidebar-splitter", "sidebar-box"]; - - const browser = document.getElementById("browser"); - browser.prepend(gNavToolbox); - - const sidebarPanelWrapper = document.getElementById("tabbrowser-tabbox"); - for (let id of kElementsToAppend) { - const elem = document.getElementById(id); - if (elem) { - sidebarPanelWrapper.prepend(elem); - } - } - } - #initUIComponents() { const kUIComponents = ["ZenProgressBar"]; for (let component of kUIComponents) { diff --git a/src/zen/common/styles/zen-single-components.css b/src/zen/common/styles/zen-single-components.css index 28373c559..a2386a42d 100644 --- a/src/zen/common/styles/zen-single-components.css +++ b/src/zen/common/styles/zen-single-components.css @@ -686,7 +686,7 @@ /* Loading progress bar */ #zen-loading-progress-bar { - --zen-loading-progress-bar-color: color-mix(in srgb, var(--zen-primary-color), light-dark(rgba(0, 0, 0, 0.7), rgba(255, 255, 255, 0.7)) 70%); + --zen-loading-progress-bar-color: color-mix(in srgb, var(--zen-primary-color), light-dark(rgba(0, 0, 0, 0.5), rgba(255, 255, 255, 0.5)) 70%); position: fixed; diff --git a/src/zen/drag-and-drop/ZenDragAndDrop.js b/src/zen/drag-and-drop/ZenDragAndDrop.js index 30154a4db..b69087884 100644 --- a/src/zen/drag-and-drop/ZenDragAndDrop.js +++ b/src/zen/drag-and-drop/ZenDragAndDrop.js @@ -1267,24 +1267,18 @@ ) { let lastTab = gBrowser.tabs.at(-1); let pinnedTabsCount = gBrowser._numVisiblePinTabsWithoutCollapsed; - let isHoveringSeparator = - event.target.parentElement.classList.contains( - "zen-workspace-pinned-tabs-section" - ); // Only if there are no normal tabs to drop after showIndicatorUnderNewTabButton = lastTab.hasAttribute("zen-empty-tab"); let useLastPinned = - (showIndicatorUnderNewTabButton && - !(pinnedTabsCount - gBrowser._numZenEssentials) && - Services.prefs.getBoolPref("zen.view.show-newtab-button-top")) || - isHoveringSeparator; + (hoveringPeriphery || + (showIndicatorUnderNewTabButton && + !(pinnedTabsCount - gBrowser._numZenEssentials))) && + Services.prefs.getBoolPref("zen.view.show-newtab-button-top"); dropElement = (useLastPinned - ? this._tabbrowserTabs.ariaFocusableItems.at( - pinnedTabsCount ? pinnedTabsCount - 1 : 0 - ) + ? this._tabbrowserTabs.ariaFocusableItems.at(pinnedTabsCount) : this._tabbrowserTabs.ariaFocusableItems.at(-1)) || lastTab; } } diff --git a/src/zen/split-view/ZenViewSplitter.mjs b/src/zen/split-view/ZenViewSplitter.mjs index 521ecd1d0..ce37c77ea 100644 --- a/src/zen/split-view/ZenViewSplitter.mjs +++ b/src/zen/split-view/ZenViewSplitter.mjs @@ -220,14 +220,8 @@ class nsZenViewSplitter extends nsZenDOMOperatedFeature { } const group = this._data[groupIndex]; const tabIndex = group.tabs.indexOf(tab); - group.tabs.splice(tabIndex, 1); - this.resetTabState(tab, forUnsplit); - if (tab.group && tab.group.hasAttribute("split-view-group")) { - gBrowser.ungroupTab(tab); - this.#dispatchItemEvent("ZenTabRemovedFromSplit", tab); - } - if (group.tabs.length < 2) { + if (group.tabs.length < 3) { // We need to remove all remaining tabs from the group when unsplitting let remainingTabs = [...group.tabs]; // Copy array since we'll modify it if (!dontRebuildGrid) { @@ -243,6 +237,14 @@ class nsZenViewSplitter extends nsZenDOMOperatedFeature { .removeAttribute("disabled"); } } else { + group.tabs.splice(tabIndex, 1); + + this.resetTabState(tab, forUnsplit); + if (tab.group && tab.group.hasAttribute("split-view-group")) { + gBrowser.ungroupTab(tab); + this.#dispatchItemEvent("ZenTabRemovedFromSplit", tab); + } + const node = this.getSplitNodeFromTab(tab); const toUpdate = this.removeNode(node); this.applyGridLayout(toUpdate);