Compare commits

...

52 Commits
1.18b ... dev

Author SHA1 Message Date
mr. m
26dabffb96 feat: Use the correct drag event to detect window enters, b=no-bug, c=no-component 2026-02-03 00:44:36 +01:00
mr. m
ead077d16e fix: Fixed private windows adopting Blank windows styling, b=closes #12211, c=no-component 2026-02-02 18:23:25 +01:00
mr. m
a72fa3f79e Merge branch 'dev' of https://github.com/zen-browser/desktop into dev 2026-02-02 14:57:49 +01:00
mr. m
33846dbce0 fix: Fixed drag and drop not calculating window bounds correctly, b=closes #12156, closes https://github.com/zen-browser/desktop/issues/11582, closes https://github.com/zen-browser/desktop/issues/12204, c=tabs 2026-02-02 14:57:24 +01:00
mr. m
32fffaabe7 fix: Dont allow essentials promo to be shown on unsynced windows, b=closes #12205, c=tabs 2026-02-02 12:41:42 +01:00
mr. m
bf96b512cb Merge branch 'dev' of https://github.com/zen-browser/desktop into dev 2026-02-02 01:10:55 +01:00
mr. m
32a42e797c feat: Fixed split view not working on windows when dropping, b=closes #12143, c=no-component 2026-02-02 01:10:48 +01:00
mr-cheffy
29b8555c66 docs: Update monthly issue metrics, b=(no bug), c={docs} 2026-02-01 03:13:23 +00:00
mr. m
ab7698b16f feat: Make sure to reset pinned changed url on unpin, b=no-bug, c=tabs 2026-01-31 20:03:13 +01:00
mr. m
cd0ef01fa1 Merge branch 'dev' of https://github.com/zen-browser/desktop into dev 2026-01-31 18:49:26 +01:00
mr. m
41d97ddd21 fix: Dont update the spaces menu for GTK, b=closes #12024, c=common 2026-01-31 18:34:55 +01:00
mr. m
a4386de00d fix: Fixed dragging tabs to different windows causing freeze, b=closes #12178, c=tabs 2026-01-31 18:29:37 +01:00
rain capsule
28a2e8697a fix: Update notification popup icon styles to account for showing state, p=#12033 2026-01-31 11:33:50 +01:00
TogiFerretFerret
2ae623b15c fix(split-view): correct backwards navigation in grid layout, p=#12160 2026-01-30 17:58:07 +01:00
TogiFerretFerret
8e7ce1c12b fix(ui): prevent closeTabByDblclick pref from blocking context menu rename, b=https://github.com/zen-browser/desktop/issues/12060, p=#12162 2026-01-30 17:50:11 +01:00
mr. m
b5efe62739 fix: Make sure drop indicator is under the last item when newtab button is below, b=no-bug, c=common 2026-01-29 11:05:43 +01:00
mr. m
e34ed3e882 feat: Fixed unpinning an essential tab directly from shortcuts, b=no-bug, c=folders, split-view, tabs, workspaces 2026-01-29 07:39:09 +01:00
mr. m
658e35ebde feat: Add more migration options, b=no-bug, c=no-component 2026-01-28 20:45:45 +01:00
mr. m
1176f5ac8b fix: Fixed auto focus not working on popup windows, b=closes #11377, c=common, workspaces 2026-01-28 12:12:52 +01:00
mr. m
4de01a9bc9 fix: Fixed drag-and-dropping tabs between windows not working with WS off, b=closes #12103, c=no-component 2026-01-28 10:31:19 +01:00
mr. m
35a9a9ea2a fix: Fixed low accesibility on text on sidenar, b=closes #12095, c=tests, workspaces 2026-01-27 23:53:25 +01:00
TogiFerretFerret
e78e2488ff fix(sync): prevent window shrinking by resetting scale/size in pseudo-image, p=#12082 2026-01-27 16:15:28 +01:00
mr. m
1c23ad92b3 Sync upstream Firefox to version 147.0.2, p=#12079 2026-01-27 15:03:38 +01:00
mr. m
32ba6ef81b fix: Fixed small QA issues, b=no-bug, c=common, compact-mode, split-view, tabs, tests 2026-01-27 14:35:27 +01:00
mr. m
a8559f84c1 Merge branch 'dev' of https://github.com/zen-browser/desktop into dev 2026-01-27 11:59:10 +01:00
mr. m
0e07f65bc0 feat: Add select-recently-used-on-close to the preferences page, b=no-bug, c=no-component 2026-01-27 11:59:04 +01:00
mr. m
4046dd01a1 chore: Sync upstream to Firefox 147.0.2, p=#12067 2026-01-27 09:00:57 +01:00
mr. m
e51592898e fix: Fixed restoring pinned tab to base url on startup not working, b=closes #12055, c=tabs 2026-01-26 18:42:54 +01:00
mr. m
9afbd1befd feat: Make sure to run a migration for deferred sessions as well, b=no-bug, c=tabs, workspaces 2026-01-26 17:24:12 +01:00
mr. m
ccc1e998da fix: Fixed 'Restore previous session' not working winth wsync disabled, b=closes #12034, c=common 2026-01-26 09:43:31 +01:00
mr. m
3a51b36a05 feat: Add debug log for last session state object, b=no-bug, c=no-component 2026-01-26 02:41:56 +01:00
mr. m
e05cb0e0dc feat: Make inspector shortcut use L key by default, b=no-bug, c=kbs 2026-01-26 02:20:20 +01:00
mr. m
a892721306 fix: Fixed dropping tabs into the same instance, b=closes #12032, c=no-component 2026-01-26 01:47:54 +01:00
mr. m
950f6dfb66 Revert "feat: Implement new wizzard watermarks, b=no-bug, c=configs"
This reverts commit 956841a76e.
2026-01-26 01:47:28 +01:00
mr. m
9b6937650d chore: Format project, b=no-bug, c=split-view 2026-01-25 20:02:16 +01:00
mr. m
2c63376782 fix: Fixed handling split data that may be undefined, b=no-bug, c=split-view 2026-01-25 19:58:18 +01:00
mr. m
f5356dbcb6 feat: Hide essentials visibility on the same thread, b=no-bug, c=no-component 2026-01-25 19:35:03 +01:00
mr. m
45ecacfb04 feat: Make sure to prioritize last session state before closed windows, b=no-bug, c=no-component 2026-01-25 18:23:07 +01:00
mr. m
4327684f9f feat: Make sure focus event only accepts the window object, b=no-bug, c=no-component 2026-01-25 18:10:26 +01:00
mr. m
8997a24996 fix: Fixed migration not working for previous states, b=bug #11994, c=no-component 2026-01-25 18:07:25 +01:00
mr. m
5a6a565b0f Merge branch 'dev' of https://github.com/zen-browser/desktop into dev 2026-01-25 17:44:08 +01:00
mr. m
d39fff2e4a fix: Fixed dimmed text color for linux, b=no-bug, c=glance, workspaces 2026-01-25 17:43:47 +01:00
Andrey Bochkarev
ab12e72cc5 fix: Prevent sidebar from flickering when moving a tab, p=#12016 2026-01-25 14:57:12 +01:00
mr. m
8a2e015048 fix: Fixed dragging split views into blank windows, b=no-bug, c=no-component 2026-01-25 12:26:26 +01:00
mr. m
83de087b0b feat: Dont bring unpinned tabs to new windows if window sync is disabled, b=no-bug, c=no-component 2026-01-25 12:22:53 +01:00
mr. m
5dea28a3cb feat: Fixed windows not initializing when window sync is disabled, b=closes #11999, p=#12015 2026-01-25 12:12:56 +01:00
mr. m
956841a76e feat: Implement new wizzard watermarks, b=no-bug, c=configs 2026-01-25 09:51:17 +01:00
mr. m
3f03ffb27b fix: Fixed Inconsistant capitalization in blank window locales, b=closes #12009, c=kbs 2026-01-25 00:05:49 +01:00
mr. m
5b685bc26d feat: Change default shortcut for unsynced windows, b=no-bug, c=windows, kbs 2026-01-24 15:34:46 +01:00
mr. m
6b255eabec feat: Fixed allowing folders to drop into normal tabs, b=no-bug, c=tabs 2026-01-24 08:58:36 +01:00
mr. m
1da0bed725 feat: Properly wait for session initialization event, b=no-bug, c=no-component 2026-01-23 23:19:43 +01:00
mr. m
a806bc7d0f fix: Fixed migration issue when clear history is enabled, b=closes #11993, c=flatpak, workspaces 2026-01-23 23:00:42 +01:00
37 changed files with 837 additions and 299 deletions

View File

@@ -34,8 +34,8 @@ Zen is a firefox-based browser with the aim of pushing your productivity to a ne
### Firefox Versions ### Firefox Versions
- [`Release`](https://zen-browser.app/download) - Is currently built using Firefox version `147.0.1`! 🚀 - [`Release`](https://zen-browser.app/download) - Is currently built using Firefox version `147.0.2`! 🚀
- [`Twilight`](https://zen-browser.app/download?twilight) - Is currently built using Firefox version `RC 147.0.1`! - [`Twilight`](https://zen-browser.app/download?twilight) - Is currently built using Firefox version `RC 147.0.2`!
### Contributing ### Contributing

View File

@@ -1 +1 @@
783b222b1b93fb9e8c52eb57558ef7f07bca6e7e 7712a9ac90683965f71be525fe2827467632715d

View File

@@ -20,7 +20,6 @@ finish-args:
- --socket=cups - --socket=cups
- --persist=.zen - --persist=.zen
- --env=DICPATH=/usr/share/hunspell - --env=DICPATH=/usr/share/hunspell
- --filesystem=xdg-config/gtk-3.0:ro
- --filesystem=xdg-download:rw - --filesystem=xdg-download:rw
- --filesystem=/run/.heim_org.h5l.kcm-socket - --filesystem=/run/.heim_org.h5l.kcm-socket
- --filesystem=xdg-run/speech-dispatcher:ro - --filesystem=xdg-run/speech-dispatcher:ro

View File

@@ -148,7 +148,7 @@ function SignAndPackage($name) {
$env:WIN32_REDIST_DIR="$PWD\win-cross\vs2022\VC\Redist\MSVC\14.38.33135\x64\Microsoft.VC143.CRT" $env:WIN32_REDIST_DIR="$PWD\win-cross\vs2022\VC\Redist\MSVC\14.38.33135\x64\Microsoft.VC143.CRT"
} }
$env:MAR="..\\build\\winsign\\mar.exe" $env:MAR="..\\build\\windows\\mar.exe"
if ($name -eq "arm64") { if ($name -eq "arm64") {
$env:SURFER_COMPAT="aarch64" $env:SURFER_COMPAT="aarch64"
} else { } else {

View File

@@ -0,0 +1,262 @@
# Issue Metrics
| Metric | Average | Median | 90th percentile |
| --- | --- | --- | ---: |
| Time to first response | 14:19:40 | 2:07:00 | 1 day, 4:29:24 |
| Time to close | 23:19:13 | 6:44:05 | 2 days, 5:35:23 |
| Metric | Count |
| --- | ---: |
| Number of items that remain open | 103 |
| Number of items closed | 141 |
| Total number of items created | 244 |
| Title | URL | Time to first response | Time to close |
| --- | --- | --- | --- |
| Filling in the search, query does not work with Ecosia | https://github.com/zen-browser/desktop/issues/12186 | None | None |
| Workspaces are not synchronized between Zen on Windows11 and macOS. | https://github.com/zen-browser/desktop/issues/12184 | 0:13:05 | 0:13:05 |
| the 1st 2 workspaces aren't visible in the workspace bar at the bottom (SOLVED) | https://github.com/zen-browser/desktop/issues/12182 | None | 0:52:19 |
| Broken web player and descript as part of page | https://github.com/zen-browser/desktop/issues/12181 | None | None |
| Websites having wrong icons in history panel | https://github.com/zen-browser/desktop/issues/12179 | 4:54:50 | None |
| Dragging and Dropping Tabs between Windows causes weird issues with Tab Sync enabled | https://github.com/zen-browser/desktop/issues/12178 | None | 16:59:50 |
| Incorrect Text - Resetting an Essential Tab should be called "Reset Essential Tab" instead of "Reset Pinned Tab" | https://github.com/zen-browser/desktop/issues/12177 | None | None |
| Windows management is broken - they keep cloning each other. | https://github.com/zen-browser/desktop/issues/12176 | 1:26:12 | 11:12:54 |
| Application menu visual glitches on KDE Plasma 5.27.5 and Kwin | https://github.com/zen-browser/desktop/issues/12175 | None | None |
| Middle mouse button does not delete tabs inside folders | https://github.com/zen-browser/desktop/issues/12174 | None | None |
| Window Sync Extents to Unpinned and Non Essential Tabs (unexpected) | https://github.com/zen-browser/desktop/issues/12173 | 0:48:02 | None |
| Clearing all tabs in window closes window | https://github.com/zen-browser/desktop/issues/12172 | 0:52:12 | None |
| Disabling window sync prevents tabs from being re-named and dragging out tab to new window will use the blank default window instead the previous behaviour. | https://github.com/zen-browser/desktop/issues/12171 | None | None |
| Update deleted all my tabs | https://github.com/zen-browser/desktop/issues/12170 | 0:40:34 | 21:14:31 |
| Right-click > Move Tab does not always show your Workspaces | https://github.com/zen-browser/desktop/issues/12168 | 1 day, 4:29:24 | None |
| background play isnt working | https://github.com/zen-browser/desktop/issues/12167 | None | None |
| Windows 11 - Update to 1.18.3b loses all tabs and essentials | https://github.com/zen-browser/desktop/issues/12166 | 0:49:13 | 0:49:13 |
| Zen wants to set itself as default browser after each update even if it already is | https://github.com/zen-browser/desktop/issues/12164 | None | None |
| 1.18.3b AutoUpdate Lost all Tabs including Essentials | https://github.com/zen-browser/desktop/issues/12163 | 0:55:04 | 19:43:42 |
| Gaming mouse's back/forward button keeps moving Workspaces instead of page | https://github.com/zen-browser/desktop/issues/12161 | 0:27:35 | 0:46:07 |
| Dragging multiple tabs from one window to another flips their order | https://github.com/zen-browser/desktop/issues/12159 | None | None |
| The pop-up UI button options for saving or saving passwords are not functional | https://github.com/zen-browser/desktop/issues/12158 | None | None |
| I lost all my folder and essentials due to the uptdate | https://github.com/zen-browser/desktop/issues/12157 | 0:35:43 | 0:35:43 |
| Dragging tabs between windows still doesn't work right | https://github.com/zen-browser/desktop/issues/12156 | 1:46:33 | None |
| Discord Camera playback | https://github.com/zen-browser/desktop/issues/12155 | None | None |
| Custom url homepage not working | https://github.com/zen-browser/desktop/issues/12154 | 13:36:48 | None |
| Numerous "New Tabs" when restoring session | https://github.com/zen-browser/desktop/issues/12152 | 0:17:33 | None |
| Feature Request: Allow manual editing of pinned tab URLs | https://github.com/zen-browser/desktop/issues/12151 | 1:19:36 | 1:19:36 |
| "Find in page" bar has white background wth black theme | https://github.com/zen-browser/desktop/issues/12150 | None | 0:00:43 |
| Open a local index.html with zen | https://github.com/zen-browser/desktop/issues/12149 | 4:53:15 | 8:41:06 |
| No synchronization of tabs between computers | https://github.com/zen-browser/desktop/issues/12148 | 0:41:19 | 1:04:28 |
| Cursor stuck as `default` everywhere after updating to 1.18.3b | https://github.com/zen-browser/desktop/issues/12145 | None | 21:06:24 |
| An issue with custom keyboard shortcuts; Particular keys fail to work | https://github.com/zen-browser/desktop/issues/12144 | 13:30:14 | None |
| 1.18.3b broke the drag to split tabs function (with a recording to show this in TROUBLE SHOOTING mode) | https://github.com/zen-browser/desktop/issues/12143 | 0:23:19 | None |
| Loaded tabs are faded out in new windows | https://github.com/zen-browser/desktop/issues/12142 | 8:30:17 | None |
| Window Sync with multi monitors is a nightmare. | https://github.com/zen-browser/desktop/issues/12141 | 0:36:59 | 8:04:12 |
| Multiple Windows On Launch In Wayland | https://github.com/zen-browser/desktop/issues/12140 | 0:12:51 | None |
| Update Broken, Cont. | https://github.com/zen-browser/desktop/issues/12139 | 14:23:05 | None |
| Some Settings Are Not Persisting Between Restarts | https://github.com/zen-browser/desktop/issues/12138 | 2:27:50 | None |
| "What's New" page text error for 1.18b | https://github.com/zen-browser/desktop/issues/12137 | 5:46:25 | 17:40:01 |
| Grouping Tabs Together has become bugged on new update | https://github.com/zen-browser/desktop/issues/12136 | 2:38:32 | None |
| Supabase Dashboard is not loading | https://github.com/zen-browser/desktop/issues/12135 | 6:13:09 | 20:45:26 |
| Workspace bookmark | https://github.com/zen-browser/desktop/issues/12134 | None | None |
| Broken Firefox Sync: Bookmarks no longer syncing between Zen Desktop and Firefox Mobile after recent update | https://github.com/zen-browser/desktop/issues/12133 | 1:22:35 | None |
| 软件启动的时候会弹出两个窗口 | https://github.com/zen-browser/desktop/issues/12132 | 2:08:29 | 2:08:29 |
| Latest Update deleted all my Tabs | https://github.com/zen-browser/desktop/issues/12131 | 0:08:05 | 0:07:30 |
| Cannot drag tabs from window with 2 or more tabs into another window | https://github.com/zen-browser/desktop/issues/12130 | 0:06:58 | 0:06:58 |
| Window sync completely breaks my workflow | https://github.com/zen-browser/desktop/issues/12127 | 0:11:09 | 1:42:54 |
| Full screen video content cut off when browser window in full screen | https://github.com/zen-browser/desktop/issues/12126 | None | 0:39:59 |
| Passkeys do not work on GitHub | https://github.com/zen-browser/desktop/issues/12125 | None | None |
| Apple login does not work via apple.com's oauth API | https://github.com/zen-browser/desktop/issues/12124 | None | None |
| "Open previous windows and tabs" setting breaks when zen.window-sync.prefer-unsynced-windows is set to false | https://github.com/zen-browser/desktop/issues/12121 | 0:54:22 | 8:23:30 |
| Zen struggle rendering large DOM lists containing lots of child elements | https://github.com/zen-browser/desktop/issues/12119 | 2 days, 21:36:13 | None |
| Drag and drop tabs to different workspaces between two different zen windows causes the tabs to disappear after restart | https://github.com/zen-browser/desktop/issues/12116 | 0:04:16 | None |
| Windows Sync and Tabs | https://github.com/zen-browser/desktop/issues/12115 | 0:05:26 | 0:05:26 |
| Loss of open tabs after update 1.18.x | https://github.com/zen-browser/desktop/issues/12114 | 1:10:05 | 1:59:02 |
| Tab focus returns to parent tab instead of adjacent tab when closing multiple results | https://github.com/zen-browser/desktop/issues/12113 | 11:47:07 | 14:11:10 |
| New window does not auto focus url bar with zen.urlbar.replace-newtab set to false | https://github.com/zen-browser/desktop/issues/12112 | None | None |
| 1.18b completely breaks Simple Tab Groups | https://github.com/zen-browser/desktop/issues/12111 | 0:06:51 | 0:06:51 |
| Essentials icon keep disappearing | https://github.com/zen-browser/desktop/issues/12110 | 0:13:16 | 0:13:16 |
| Random Infinite Loading/Crashes when watching a YouTube video | https://github.com/zen-browser/desktop/issues/12109 | 1:23:12 | None |
| Zen icon deleted after an update | https://github.com/zen-browser/desktop/issues/12108 | 0:08:52 | 0:08:52 |
| Bug with folders with split tabs after update 1.18.2b (Mac) | https://github.com/zen-browser/desktop/issues/12107 | 0:17:10 | None |
| Weird bug when repoen zen the tabs keeps recover | https://github.com/zen-browser/desktop/issues/12106 | 0:33:42 | None |
| Notification can't be closed when tabs are on the right side (mailto notify) | https://github.com/zen-browser/desktop/issues/12104 | 2:40:15 | None |
| Cannot move tab from one window to another | https://github.com/zen-browser/desktop/issues/12103 | 0:12:36 | 0:13:32 |
| on Essential Tabs , when i recieve a message on whatsapp it gets hidden, i do get notification but it doesnt show | https://github.com/zen-browser/desktop/issues/12101 | 0:08:34 | 0:08:36 |
| Continue where you let off for bookmarks | https://github.com/zen-browser/desktop/issues/12100 | 1:16:25 | 3:48:13 |
| Essential tabs disappearing after excessive clicks | https://github.com/zen-browser/desktop/issues/12099 | 4:13:22 | 4:13:22 |
| Enhanced Tracking Protection reverts back to strict on launch | https://github.com/zen-browser/desktop/issues/12096 | 7:40:37 | 19:27:51 |
| Sidebar tab title color / contrast changed in v1.18 | https://github.com/zen-browser/desktop/issues/12095 | None | 0:13:40 |
| New window does not open correct space. | https://github.com/zen-browser/desktop/issues/12094 | 0:01:55 | None |
| Bug: Essentials tabs disappear after rapid activation | https://github.com/zen-browser/desktop/issues/12092 | 0:31:21 | 1:23:25 |
| Tabs being cloned to all windows | https://github.com/zen-browser/desktop/issues/12088 | 0:06:01 | 0:47:56 |
| Pinned extensions disappear when more than 1 is pinned | https://github.com/zen-browser/desktop/issues/12087 | 1 day, 14:00:23 | None |
| Bookmark icons not showing properly | https://github.com/zen-browser/desktop/issues/12084 | 0:03:11 | None |
| There is a problem with Zen when opening tabs: it is slow | https://github.com/zen-browser/desktop/issues/12083 | None | None |
| Jump to a blank page after closing all normal tabs | https://github.com/zen-browser/desktop/issues/12081 | None | 1 day, 21:13:35 |
| Dragging and Dropping tabs within the sidebar. Tab pops out as white box. | https://github.com/zen-browser/desktop/issues/12080 | 2:07:00 | None |
| Essential tabs dissapear from sidebar UI | https://github.com/zen-browser/desktop/issues/12078 | 0:01:44 | 0:01:44 |
| F6 doesn't float url bar | https://github.com/zen-browser/desktop/issues/12076 | 0:16:04 | 3:38:13 |
| Blank window. Completely unusable | https://github.com/zen-browser/desktop/issues/12075 | 0:05:13 | 1:07:49 |
| View Page Source opens in No Container Tab | https://github.com/zen-browser/desktop/issues/12074 | 0:04:07 | None |
| Zen starting out blank with corrupted tabs | https://github.com/zen-browser/desktop/issues/12073 | 0:05:16 | 2 days, 10:11:43 |
| Essentials becoming invisible / absent until browser restarted | https://github.com/zen-browser/desktop/issues/12072 | 0:06:59 | 0:06:59 |
| Proxmox UI Shell renders unreadable. Previously worked. | https://github.com/zen-browser/desktop/issues/12071 | None | None |
| Grid Split navigations is backwards | https://github.com/zen-browser/desktop/issues/12070 | 22:32:57 | 3 days, 7:21:01 |
| Bookmarks no longer synchronize | https://github.com/zen-browser/desktop/issues/12069 | None | None |
| Can't use MacOs specific video features (Portrait, Studio Light, Background) | https://github.com/zen-browser/desktop/issues/12068 | None | None |
| Turning off zen.window-sync.enabled to false leads to broken new window | https://github.com/zen-browser/desktop/issues/12066 | 0:37:44 | 1:57:03 |
| Can future versions please not clear out tabs and folder trees when updating/upgrade? | https://github.com/zen-browser/desktop/issues/12064 | None | 4:57:15 |
| "New Blank Window" uses wrong theme color | https://github.com/zen-browser/desktop/issues/12062 | 9:49:13 | 11:15:18 |
| [linux] Edit label/title for tab doesn't work | https://github.com/zen-browser/desktop/issues/12060 | 2:25:26 | 3 days, 18:16:00 |
| Missing option to disable synced windows | https://github.com/zen-browser/desktop/issues/12059 | None | 0:01:21 |
| Disable Window Sync option in settings? | https://github.com/zen-browser/desktop/issues/12058 | 0:12:41 | 0:12:41 |
| Tab titles not updating when window sync is disabled | https://github.com/zen-browser/desktop/issues/12057 | 0:05:48 | 0:10:29 |
| Essentials entry randomly disappeared from UI | https://github.com/zen-browser/desktop/issues/12056 | 0:12:56 | 0:12:56 |
| Pinned tabs not resseting on startup | https://github.com/zen-browser/desktop/issues/12055 | 2:00:07 | 2:30:05 |
| [Wayland] Zen browser shows white blank panel on startup | https://github.com/zen-browser/desktop/issues/12054 | 1:24:35 | 1 day, 12:37:36 |
| [Tab Sync] Tab in Glance mode opens as regular tab on other window. | https://github.com/zen-browser/desktop/issues/12051 | 1 day, 19:56:04 | None |
| workspace tabs desync across windows | https://github.com/zen-browser/desktop/issues/12050 | 0:11:59 | None |
| Essential tab stop working | https://github.com/zen-browser/desktop/issues/12045 | 0:46:10 | 0:46:10 |
| PWA apps render issue | https://github.com/zen-browser/desktop/issues/12044 | 1:32:16 | 3 days, 1:18:16 |
| MacOS - Wrong tab selected when going backwards | https://github.com/zen-browser/desktop/issues/12043 | 0:04:04 | None |
| Problem with important tabs | https://github.com/zen-browser/desktop/issues/12042 | 2 days, 4:15:21 | 2 days, 20:49:00 |
| Pinned and essential tabs randomly disappear | https://github.com/zen-browser/desktop/issues/12040 | 0:34:50 | 0:34:50 |
| Sidebar overflows in compact mode | https://github.com/zen-browser/desktop/issues/12039 | 1 day, 4:05:41 | None |
| Dragging tabs between worksapce is buggy [I think due to sync] | https://github.com/zen-browser/desktop/issues/12037 | 5 days, 11:35:22 | 5 days, 11:35:22 |
| Sidebar doesnt close automatically after creating a new tab in Compact Mode | https://github.com/zen-browser/desktop/issues/12036 | 2 days, 6:04:10 | None |
| The extension items in the context menu multiplying with every right click | https://github.com/zen-browser/desktop/issues/12035 | 3:50:26 | None |
| Disabling zen.window-sync.enabled breaks "Open previous windows and tabs" | https://github.com/zen-browser/desktop/issues/12034 | 4:38:30 | 6:11:16 |
| Tab cannot be grabbed and taken into a different Zen browser instance | https://github.com/zen-browser/desktop/issues/12032 | 0:11:57 | 1:21:44 |
| Window sync with zoom | https://github.com/zen-browser/desktop/issues/12031 | 3:33:29 | 1 day, 17:09:02 |
| New Window doesn't work with window sync disabled. | https://github.com/zen-browser/desktop/issues/12030 | None | 1:21:07 |
| Move to space not listed in context menu | https://github.com/zen-browser/desktop/issues/12029 | 1:28:17 | 1:28:17 |
| All my workspaces and tabs just gone after update, wtf ? :) | https://github.com/zen-browser/desktop/issues/12028 | 0:31:31 | 1:41:41 |
| Global menu show but unresponsive. | https://github.com/zen-browser/desktop/issues/12024 | 0:06:03 | 6 days, 1:49:53 |
| Debian 13 | Passkey doesn't show QR code | https://github.com/zen-browser/desktop/issues/12022 | 10:08:54 | None |
| Performance: Swiping across spaces with multiple tabs open is laggy | https://github.com/zen-browser/desktop/issues/12020 | 0:09:27 | 0:09:27 |
| Move to Space | https://github.com/zen-browser/desktop/issues/12019 | 0:08:00 | 0:08:00 |
| [UI Error] Zen Browser Settings UI Error | https://github.com/zen-browser/desktop/issues/12014 | 0:41:54 | 6:44:05 |
| Full-Screen PIP Mode Retains Dimmed State Indefinitely Due to Hover and System Inactivity | https://github.com/zen-browser/desktop/issues/12013 | None | None |
| "Check for Updates" Not Working | https://github.com/zen-browser/desktop/issues/12012 | 1:54:04 | 1:54:09 |
| Website lolalytics.com not working properly after updating to 1.18.1b | https://github.com/zen-browser/desktop/issues/12011 | 10:35:46 | 11:32:35 |
| No "Open a new Blank Window" action when right-clicking zen on taskbar | https://github.com/zen-browser/desktop/issues/12010 | 9:50:45 | None |
| Inconsistant capitalization in application menu | https://github.com/zen-browser/desktop/issues/12009 | None | 0:15:37 |
| Disable window/tab sync by default | https://github.com/zen-browser/desktop/issues/12008 | 0:03:34 | 17:22:46 |
| Sync not working + pinned tabs do not resert url | https://github.com/zen-browser/desktop/issues/12006 | 0:15:54 | 7:59:09 |
| Some UI elements not renderring correctly | https://github.com/zen-browser/desktop/issues/12005 | 3:40:46 | 4:36:15 |
| installer prolbem | https://github.com/zen-browser/desktop/issues/12004 | 2:13:28 | 2:13:28 |
| Issues with Sidebar Dragging Exiting Full-Screen & Legacy Ctrl+Tab Behavior | https://github.com/zen-browser/desktop/issues/12003 | 4:33:38 | None |
| Cannot Rename “New Folder” in the Sidebar | https://github.com/zen-browser/desktop/issues/12002 | 0:58:42 | 1:48:21 |
| Custom font doesn't work | https://github.com/zen-browser/desktop/issues/12001 | 1 day, 8:53:16 | 1 day, 8:53:16 |
| Windows accent coloring issue with zen | https://github.com/zen-browser/desktop/issues/12000 | 1:11:28 | 1:11:28 |
| Disabling zen.window-sync.enabled breaks new zen instances | https://github.com/zen-browser/desktop/issues/11999 | 4:34:06 | 22:44:50 |
| Pinned tabs don't scale: hundreds of pins freeze browser | https://github.com/zen-browser/desktop/issues/11997 | 6:50:35 | 1 day, 13:33:03 |
| All tabs are gone (also pinned) when updating to 1.18b | https://github.com/zen-browser/desktop/issues/11994 | 4:42:08 | None |
| "blank window" at startup | https://github.com/zen-browser/desktop/issues/11993 | 0:02:32 | 0:52:40 |
| Crashing when playing WASMGC game | https://github.com/zen-browser/desktop/issues/11990 | 0:31:55 | None |
| Pinned Tabs disappearing/invisible | https://github.com/zen-browser/desktop/issues/11989 | 11:31:45 | 11:31:45 |
| Zen process opens but the window doesn't | https://github.com/zen-browser/desktop/issues/11985 | 0:22:24 | None |
| Zen has recently got really inconsistent performance (especially after the last few updates). | https://github.com/zen-browser/desktop/issues/11982 | 0:52:04 | None |
| Twitch.tv Video Streams Not Loading | https://github.com/zen-browser/desktop/issues/11980 | 0:19:27 | None |
| Page rendering is blank white | https://github.com/zen-browser/desktop/issues/11979 | 15:04:14 | 15:04:14 |
| Zen is unusable on Cosmic Desktop Environment (unable to remove a checkbox that spawns and hinders using the browser) | https://github.com/zen-browser/desktop/issues/11978 | 0:42:40 | 17:46:00 |
| Searching with # is not searching bookmarks by tag or title | https://github.com/zen-browser/desktop/issues/11976 | 1:54:07 | 11:45:13 |
| Conflict Between Browser Page Search Shortcut and Confluence Search | https://github.com/zen-browser/desktop/issues/11975 | None | None |
| Updater repeatedly reinstalls latest twilight build despite no version change. | https://github.com/zen-browser/desktop/issues/11974 | 0:19:47 | 6:53:06 |
| Randomly Control button stop functioning | https://github.com/zen-browser/desktop/issues/11972 | None | None |
| Low refresh rate on Zen Windows version after OS update | https://github.com/zen-browser/desktop/issues/11967 | 21:19:01 | None |
| Switching workspaces to a split view will cause the area surround the view to turn black for a second | https://github.com/zen-browser/desktop/issues/11965 | 17:19:30 | None |
| [Bug] Previous session permanently lost after closing and reopening Zen Browser | https://github.com/zen-browser/desktop/issues/11964 | 4:00:54 | 4:01:24 |
| Closing a normal zen window when an incognito zen browser is opened, removes all the tabs across all my workspaces. | https://github.com/zen-browser/desktop/issues/11963 | 2:10:13 | 2:10:13 |
| Only sidebar layout -- Always show bookmarks tool bar + window buttons | https://github.com/zen-browser/desktop/issues/11962 | 0:06:53 | 3:10:47 |
| Zen randomly crashes on macOS | https://github.com/zen-browser/desktop/issues/11958 | 3:36:36 | None |
| Essentials and pinned tabs don't load automatically on open | https://github.com/zen-browser/desktop/issues/11957 | 12:57:52 | 12:57:52 |
| Readme reports Firefox 147.0.1 for Release but latest release 1.17.15b (2025-12-20) is 146.0.1 | https://github.com/zen-browser/desktop/issues/11952 | 8:47:04 | 8:47:03 |
| Non-default container indicator not showing in workspace | https://github.com/zen-browser/desktop/issues/11951 | 0:13:01 | None |
| Zen not displaying websites on Intel HD graphics 2000 | https://github.com/zen-browser/desktop/issues/11950 | None | None |
| Private window tabs are mirrored in the main (non-private) window | https://github.com/zen-browser/desktop/issues/11949 | 2:34:54 | 4:47:55 |
| Media session metadata (title/artist/cover) does not update on site without page refresh | https://github.com/zen-browser/desktop/issues/11948 | 6:32:56 | 1 day, 6:51:54 |
| Nvidia overlay "Plugin-container is preventing the desktop capture" | https://github.com/zen-browser/desktop/issues/11947 | None | None |
| Login to self-hosted Bitwarden fails after initialization in multi-account setting | https://github.com/zen-browser/desktop/issues/11946 | 1 day, 14:57:08 | None |
| Accessing any URL under bitbucket.org returns 404 | https://github.com/zen-browser/desktop/issues/11944 | 2:26:35 | 1 day, 20:58:15 |
| Acrylic turns grey | https://github.com/zen-browser/desktop/issues/11937 | 0:01:44 | None |
| lang change | https://github.com/zen-browser/desktop/issues/11934 | 2:27:46 | 3:29:15 |
| MX Master 3 Forward/Back mouse buttons don't work if zen.workspaces.swipe-actions is false | https://github.com/zen-browser/desktop/issues/11923 | 1:53:09 | 1:53:09 |
| Tabs UI bug | https://github.com/zen-browser/desktop/issues/11922 | None | None |
| Positioning of titlebar window control buttons | https://github.com/zen-browser/desktop/issues/11918 | 11:28:41 | 11:28:41 |
| Zen won't follow XDG base directories | https://github.com/zen-browser/desktop/issues/11917 | 12:43:08 | None |
| Titlebar expands on hover even if Titlebar setting is Disabled from "Configure Toolbar" in Sidebar only mode of look and feel. | https://github.com/zen-browser/desktop/issues/11915 | None | None |
| Multiple window sessions result in same tabs open in all windows | https://github.com/zen-browser/desktop/issues/11914 | 1 day, 1:41:36 | 1 day, 1:41:36 |
| Misplaced Tab (Placed a tab above the new tab button but below the line that separates the pinned tabs) | https://github.com/zen-browser/desktop/issues/11911 | None | 4:09:21 |
| Sidebar width inconsistency | https://github.com/zen-browser/desktop/issues/11909 | None | None |
| Cannot expand / fullscreen twitter videos | https://github.com/zen-browser/desktop/issues/11908 | 2 days, 5:35:23 | 2 days, 5:35:23 |
| Menu shows unsecure connections as secure | https://github.com/zen-browser/desktop/issues/11905 | 2:21:24 | 3:35:25 |
| Top Toolbar appearing when using shortcut "Toggle Sidebar's Width" | https://github.com/zen-browser/desktop/issues/11903 | 5:08:25 | 5:08:25 |
| Only shows default icons for Google Messages for web | https://github.com/zen-browser/desktop/issues/11902 | None | 2:39:30 |
| The default section disappear from dot list at the below of the tab when swiching spaces | https://github.com/zen-browser/desktop/issues/11901 | 0:50:18 | None |
| Context menu partially hidden when right-clicking on a Bookmarks folder in the toolbar | https://github.com/zen-browser/desktop/issues/11898 | None | None |
| Refined Github(extension): Issues interface with notification header flickers / flashes | https://github.com/zen-browser/desktop/issues/11896 | None | None |
| Glance should work only for links | https://github.com/zen-browser/desktop/issues/11895 | None | 7:53:12 |
| Auto Unload Does Not And Has Never Unloaded a Single Tab Ever. | https://github.com/zen-browser/desktop/issues/11894 | None | 6:58:48 |
| Visual Bug: Line through sidebar and settings page | https://github.com/zen-browser/desktop/issues/11893 | None | 12:24:36 |
| 1password integration - not working | https://github.com/zen-browser/desktop/issues/11892 | 2:39:46 | 13:40:23 |
| Hardware acceleration worse on Zen vs others (CachyOS - NVIDIA - Wayland) | https://github.com/zen-browser/desktop/issues/11890 | 2:18:58 | 8:44:12 |
| Some tabs (inside a folder) are not drawn in the sidebar | https://github.com/zen-browser/desktop/issues/11888 | 18:13:05 | 18:13:05 |
| (macos) (twilight) pinning splitview tabs in folders causes addl tab group labels on restart/update | https://github.com/zen-browser/desktop/issues/11887 | None | 23:27:16 |
| How can I achieve window transparency on Windows (so that I can see through to the windows or desktop behind it)?/如何实现Windows下窗口透明化可以看到后面的窗口或桌面 | https://github.com/zen-browser/desktop/issues/11885 | 11:12:00 | 11:12:00 |
| Form validation checkbox message is white text on white background | https://github.com/zen-browser/desktop/issues/11884 | None | None |
| Fullscreen with F11 doesn't work as intended | https://github.com/zen-browser/desktop/issues/11883 | 6:30:42 | 6:30:46 |
| PiP window stays open empty and buttons dont work | https://github.com/zen-browser/desktop/issues/11881 | None | None |
| When switching browser layouts, extensions fixed to the toolbar may have display bugs | https://github.com/zen-browser/desktop/issues/11880 | None | 6:31:27 |
| Zen startup window has a transition from dark background (light background in light mode) + a flash before the mica kicks on windows 11. | https://github.com/zen-browser/desktop/issues/11876 | 1 day, 22:21:29 | None |
| Zen Hangs/Crashes - Have not been able to use for several months. | https://github.com/zen-browser/desktop/issues/11875 | 2 days, 0:58:56 | None |
| Settings modal is not in the right place! | https://github.com/zen-browser/desktop/issues/11873 | None | None |
| Macos: extention pop-ups open up at a different desktop in fullscreen | https://github.com/zen-browser/desktop/issues/11872 | 7:25:14 | 7:25:14 |
| Close Tab shortcut can close the window | https://github.com/zen-browser/desktop/issues/11871 | 2 days, 6:59:58 | 2 days, 6:59:58 |
| When on the login page, the extension icon in the address bar cannot be clicked | https://github.com/zen-browser/desktop/issues/11870 | 2 days, 8:04:14 | 19 days, 3:16:59 |
| Showing multiple empthy pages | https://github.com/zen-browser/desktop/issues/11869 | 4:22:38 | None |
| Control + click is not opening links in a new tab. | https://github.com/zen-browser/desktop/issues/11868 | 3 days, 21:19:59 | None |
| Folders and tabs of a workspace are not synced. | https://github.com/zen-browser/desktop/issues/11865 | 1:58:13 | 1:58:13 |
| No save button | https://github.com/zen-browser/desktop/issues/11864 | 0:15:11 | None |
| No Icon For Files | https://github.com/zen-browser/desktop/issues/11860 | 5:02:04 | 20:21:37 |
| Compatibility issue with aarch64 AppImage starting from v1.17b (GLIBCXX_3.4.26 not found) | https://github.com/zen-browser/desktop/issues/11859 | None | None |
| Adding New Bookmark in Compact Mode No Longer Pops Up Edit Panel | https://github.com/zen-browser/desktop/issues/11858 | 1 day, 18:54:21 | None |
| 什么时候能支持网页驱动 | https://github.com/zen-browser/desktop/issues/11857 | 12:28:29 | 12:28:29 |
| Workspace Switching Becomes Laggy with 4+ Workspaces and many pinned Tabs on Windows (NVIDIA GPU). | https://github.com/zen-browser/desktop/issues/11851 | 2:00:50 | None |
| Closing a recently opened tab returns to the top tab, not the previously focused tab | https://github.com/zen-browser/desktop/issues/11845 | 19:10:53 | 1 day, 17:02:53 |
| Wrong italian translation of "Workspace forward" in shortcuts settings | https://github.com/zen-browser/desktop/issues/11841 | 1:17:18 | None |
| Cannot close pinned tabs | https://github.com/zen-browser/desktop/issues/11838 | 0:21:08 | 0:23:33 |
| Copy URL shortcut does not copy URL before page has loaded | https://github.com/zen-browser/desktop/issues/11835 | None | None |
| Extensions not showing up in toolbar. | https://github.com/zen-browser/desktop/issues/11834 | 1:33:29 | 9:20:29 |
| Multiple duplicated Bookmarks | https://github.com/zen-browser/desktop/issues/11832 | None | None |
| [BUG] Closing and re-opening zen twighlight turns a bunch of tabs into 'New Tab's | https://github.com/zen-browser/desktop/issues/11831 | 15:57:31 | 7 days, 8:27:19 |
| Indent issue on active pinned tab in collapsed workspace | https://github.com/zen-browser/desktop/issues/11830 | 17:46:11 | 1 day, 6:07:21 |
| High Ram Usage | https://github.com/zen-browser/desktop/issues/11828 | None | 0:20:29 |
| Unable to install extentions in compact mode | https://github.com/zen-browser/desktop/issues/11827 | None | 1:11:29 |
| Extension icons display inconsitently when switching toolbar modes or resizing window | https://github.com/zen-browser/desktop/issues/11826 | 2:31:13 | None |
| MS Entra auth not working | https://github.com/zen-browser/desktop/issues/11825 | 3:14:28 | 20:29:41 |
| "Restore pinned tabs to their originally pinned URL on startup' option doesn't reset Pinned Tabs go back to Originally Pinned URL, i.e. doesn't reset them | https://github.com/zen-browser/desktop/issues/11823 | 2 days, 12:40:16 | None |
| Crashes when signing into aws console MFA passkey via lastpassword | https://github.com/zen-browser/desktop/issues/11820 | None | None |
| Using the dev console in glance causes weird ui | https://github.com/zen-browser/desktop/issues/11815 | 1:43:58 | None |
| The VS Code integrated extension “Live Server” does not automatically detect the Zen Browser, even when it is set as the default browser. | https://github.com/zen-browser/desktop/issues/11813 | 2:56:35 | 2 days, 12:21:43 |
| Ctrl+T does not open new tab if shortcuts are removed | https://github.com/zen-browser/desktop/issues/11811 | 0:40:23 | None |
| Sidebar title is overlapping with essential tabs after screen unlock | https://github.com/zen-browser/desktop/issues/11808 | None | 15:50:26 |
| button alignment does not change in pop-up window | https://github.com/zen-browser/desktop/issues/11805 | 0:10:14 | None |
| "Focus on <space>" action not available | https://github.com/zen-browser/desktop/issues/11804 | 0:03:34 | 1 day, 0:35:28 |
| Split View and Floating URL bugs when a Youtube video is in Full Screen and Ctrl + Shift + * is pressed. | https://github.com/zen-browser/desktop/issues/11803 | None | 7 days, 0:58:59 |
| Trackpad diagonal scroll unintentionally switches workspaces instead of scrolling tabs | https://github.com/zen-browser/desktop/issues/11802 | 2:20:42 | None |
| New tab opens when Alt+Tabbing or pressing Windows key while YouTube is playing | https://github.com/zen-browser/desktop/issues/11801 | 8:57:44 | None |
| Broken Installer (fixed) | https://github.com/zen-browser/desktop/issues/11800 | None | 1 day, 22:57:03 |
| subfolder collapse state issue when collapsing pinned area | https://github.com/zen-browser/desktop/issues/11799 | 11:27:53 | 1 day, 12:52:10 |
| Glance opens a new window for local file URLs (file://) | https://github.com/zen-browser/desktop/issues/11797 | None | None |
| acronis.com nginx a header or cookie larger than permitted | https://github.com/zen-browser/desktop/issues/11795 | None | None |
| Cannot listen to songs using the spotify integration on Musixmatch for lyric syncing in Zen | https://github.com/zen-browser/desktop/issues/11792 | 0:15:31 | 0:15:31 |
| Adding Split Tab Groups to a folder Makes the folder disappear | https://github.com/zen-browser/desktop/issues/11791 | 15 days, 4:38:37 | 15 days, 4:38:37 |
| Clear tabs button's separator is missing on Linux | https://github.com/zen-browser/desktop/issues/11789 | None | 3 days, 10:41:55 |
| [Twilight] Cannot add tab to bottom of folder | https://github.com/zen-browser/desktop/issues/11788 | 21:08:12 | 21:08:12 |
| Flathub version doesnt work on Debian 13 | https://github.com/zen-browser/desktop/issues/11787 | 25 days, 12:50:21 | None |
| Split View sidebar shows extra tab after restoring a closed tab (Ctrl+Shift+T) | https://github.com/zen-browser/desktop/issues/11785 | None | None |
| Cursor moved far right of window does not grab scrollbar when window is maximised | https://github.com/zen-browser/desktop/issues/11783 | 6:07:23 | 6:07:23 |
| HMR Not Working Correctly for Frontend Development | https://github.com/zen-browser/desktop/issues/11782 | 7:57:34 | 9:05:06 |
| Failing to obtain location | https://github.com/zen-browser/desktop/issues/11781 | 15:43:36 | 1 day, 17:23:10 |
_This report was generated with the [Issue Metrics Action](https://github.com/github/issue-metrics)_
Search query used to find these items: `repo:zen-browser/desktop is:issue created:2026-01-01..2026-01-31`

View File

@@ -53,8 +53,8 @@ category-zen-workspaces =
.tooltiptext = { pane-zen-tabs-title } .tooltiptext = { pane-zen-tabs-title }
pane-settings-workspaces-title = Workspaces pane-settings-workspaces-title = Workspaces
zen-tabs-unloader-enabled = zen-tabs-select-recently-used-on-close =
.label = Enable Tab Unloader .label = When closing a tab, switch to the most recently used tab instead of the next tab
zen-tabs-close-on-back-with-no-history = zen-tabs-close-on-back-with-no-history =
.label = Close tab and switch to its owner tab (or most recently used tab) when going back with no history .label = Close tab and switch to its owner tab (or most recently used tab) when going back with no history

View File

@@ -23,4 +23,4 @@ zen-menubar-appearance-dark =
.label = Dark .label = Dark
zen-menubar-new-unsynced-window = zen-menubar-new-unsynced-window =
.label = New Blank Window .label = New blank window

View File

@@ -6,7 +6,7 @@
value: true value: true
- name: zen.session-store.log - name: zen.session-store.log
value: "@IS_TWILIGHT@" value: true
- name: zen.session-store.restore-unsynced-windows - name: zen.session-store.restore-unsynced-windows
value: true value: true

View File

@@ -1193,6 +1193,11 @@ Preferences.addAll([
type: "bool", type: "bool",
default: false, default: false,
}, },
{
id: "zen.tabs.select-recently-used-on-close",
type: "bool",
default: true,
},
]); ]);
Preferences.addSetting({ Preferences.addSetting({

View File

@@ -37,15 +37,10 @@
class="description-deemphasized" class="description-deemphasized"
data-l10n-id="zen-tabs-cycle-by-attribute-warning" data-l10n-id="zen-tabs-cycle-by-attribute-warning"
hidden="true"/> hidden="true"/>
<checkbox data-l10n-id="zen-tabs-select-recently-used-on-close"
preference="zen.tabs.select-recently-used-on-close"/>
</groupbox> </groupbox>
<hbox id="zenTabsUnloadCategory"
class="subcategory"
hidden="true"
data-category="paneZenTabManagement">
<html:h1 data-l10n-id="pane-zen-tabs-unloader-title"/>
</hbox>
<hbox id="zenPinnedTabsManagerCategory" <hbox id="zenPinnedTabsManagerCategory"
class="subcategory" class="subcategory"
hidden="true" hidden="true"

View File

@@ -1,5 +1,5 @@
diff --git a/browser/components/tabbrowser/content/drag-and-drop.js b/browser/components/tabbrowser/content/drag-and-drop.js diff --git a/browser/components/tabbrowser/content/drag-and-drop.js b/browser/components/tabbrowser/content/drag-and-drop.js
index 57800333445ec7850742145527e04ae8d504b0bb..65361da4791b6418705f364f750f409b1f2bf82b 100644 index 57800333445ec7850742145527e04ae8d504b0bb..a13875436a72f89178455a09c8665b9a1ef240b5 100644
--- a/browser/components/tabbrowser/content/drag-and-drop.js --- a/browser/components/tabbrowser/content/drag-and-drop.js
+++ b/browser/components/tabbrowser/content/drag-and-drop.js +++ b/browser/components/tabbrowser/content/drag-and-drop.js
@@ -35,6 +35,9 @@ @@ -35,6 +35,9 @@
@@ -39,7 +39,7 @@ index 57800333445ec7850742145527e04ae8d504b0bb..65361da4791b6418705f364f750f409b
event.stopPropagation(); event.stopPropagation();
+ if (draggedTab && dropEffect == "move") { + if (draggedTab && dropEffect == "move") {
+ this.handle_drop_transition?.(draggedTab._dragData.dropElement, draggedTab, movingTabs, draggedTab._dragData.dropBefore); + this.handle_drop_transition?.(draggedTab._dragData.dropElement, draggedTab, movingTabs, draggedTab._dragData.dropBefore);
+ gZenPinnedTabManager.moveToAnotherTabContainerIfNecessary(event, movingTabs); + gZenPinnedTabManager.moveToAnotherTabContainerIfNecessary(event, draggedTab, movingTabs, this._getDropIndex(event));
+ } + }
if (draggedTab && dropEffect == "copy") { if (draggedTab && dropEffect == "copy") {
let duplicatedDraggedTab; let duplicatedDraggedTab;
@@ -102,7 +102,36 @@ index 57800333445ec7850742145527e04ae8d504b0bb..65361da4791b6418705f364f750f409b
postTransitionCleanup(); postTransitionCleanup();
} else { } else {
let onTransitionEnd = transitionendEvent => { let onTransitionEnd = transitionendEvent => {
@@ -584,6 +597,7 @@ @@ -513,7 +526,7 @@
if (tab.selected) {
selectedTab = tab;
indexForSelectedTab = newIndex;
- } else {
+ } else if (false) {
const newTab = gBrowser.adoptTab(tab, {
elementIndex: newIndex,
selectTab: tab == draggedTab,
@@ -523,7 +536,7 @@
}
}
}
- if (selectedTab) {
+ if (false) {
const newTab = gBrowser.adoptTab(selectedTab, {
elementIndex: indexForSelectedTab,
selectTab: selectedTab == draggedTab,
@@ -534,10 +547,6 @@
}
// Restore tab selection
- gBrowser.addRangeToMultiSelectedTabs(
- this._tabbrowserTabs.dragAndDropElements[dropIndex],
- this._tabbrowserTabs.dragAndDropElements[newIndex - 1]
- );
} else {
// Pass true to disallow dropping javascript: or data: urls
let links;
@@ -584,6 +593,7 @@
let nextItem = this._tabbrowserTabs.dragAndDropElements[newIndex]; let nextItem = this._tabbrowserTabs.dragAndDropElements[newIndex];
let tabGroup = isTab(nextItem) && nextItem.group; let tabGroup = isTab(nextItem) && nextItem.group;
@@ -110,7 +139,7 @@ index 57800333445ec7850742145527e04ae8d504b0bb..65361da4791b6418705f364f750f409b
gBrowser.loadTabs(urls, { gBrowser.loadTabs(urls, {
inBackground, inBackground,
replace, replace,
@@ -621,7 +635,16 @@ @@ -621,7 +631,16 @@
this._expandGroupOnDrop(draggedTab); this._expandGroupOnDrop(draggedTab);
} }
this._resetTabsAfterDrop(draggedTab.ownerDocument); this._resetTabsAfterDrop(draggedTab.ownerDocument);
@@ -128,7 +157,7 @@ index 57800333445ec7850742145527e04ae8d504b0bb..65361da4791b6418705f364f750f409b
if ( if (
dt.mozUserCancelled || dt.mozUserCancelled ||
dt.dropEffect != "none" || dt.dropEffect != "none" ||
@@ -825,7 +848,10 @@ @@ -825,7 +844,10 @@
_getDragTarget(event, { ignoreSides = false } = {}) { _getDragTarget(event, { ignoreSides = false } = {}) {
let { target } = event; let { target } = event;
while (target) { while (target) {
@@ -140,7 +169,7 @@ index 57800333445ec7850742145527e04ae8d504b0bb..65361da4791b6418705f364f750f409b
break; break;
} }
target = target.parentNode; target = target.parentNode;
@@ -842,14 +868,17 @@ @@ -842,14 +864,17 @@
return null; return null;
} }
} }
@@ -160,7 +189,7 @@ index 57800333445ec7850742145527e04ae8d504b0bb..65361da4791b6418705f364f750f409b
!this._tabbrowserTabs.expandOnHover !this._tabbrowserTabs.expandOnHover
); );
} }
@@ -880,7 +909,8 @@ @@ -880,7 +905,8 @@
isTabGroupLabel(draggedTab) && isTabGroupLabel(draggedTab) &&
draggedTab._dragData?.expandGroupOnDrop draggedTab._dragData?.expandGroupOnDrop
) { ) {
@@ -170,7 +199,7 @@ index 57800333445ec7850742145527e04ae8d504b0bb..65361da4791b6418705f364f750f409b
} }
} }
@@ -1058,7 +1088,6 @@ @@ -1058,7 +1084,6 @@
// using updateDragImage. On Linux, we can use a panel. // using updateDragImage. On Linux, we can use a panel.
if (platform == "win" || platform == "macosx") { if (platform == "win" || platform == "macosx") {
captureListener = function () { captureListener = function () {
@@ -178,7 +207,7 @@ index 57800333445ec7850742145527e04ae8d504b0bb..65361da4791b6418705f364f750f409b
}; };
} else { } else {
// Create a panel to use it in setDragImage // Create a panel to use it in setDragImage
@@ -1096,7 +1125,6 @@ @@ -1096,7 +1121,6 @@
); );
dragImageOffset = dragImageOffset * scale; dragImageOffset = dragImageOffset * scale;
} }
@@ -186,7 +215,7 @@ index 57800333445ec7850742145527e04ae8d504b0bb..65361da4791b6418705f364f750f409b
// _dragData.offsetX/Y give the coordinates that the mouse should be // _dragData.offsetX/Y give the coordinates that the mouse should be
// positioned relative to the corner of the new window created upon // positioned relative to the corner of the new window created upon
@@ -1115,7 +1143,7 @@ @@ -1115,7 +1139,7 @@
let dropEffect = this.getDropEffectForTabDrag(event); let dropEffect = this.getDropEffectForTabDrag(event);
let isMovingInTabStrip = !fromTabList && dropEffect == "move"; let isMovingInTabStrip = !fromTabList && dropEffect == "move";
let collapseTabGroupDuringDrag = let collapseTabGroupDuringDrag =
@@ -195,7 +224,7 @@ index 57800333445ec7850742145527e04ae8d504b0bb..65361da4791b6418705f364f750f409b
tab._dragData = { tab._dragData = {
offsetX: this._tabbrowserTabs.verticalMode offsetX: this._tabbrowserTabs.verticalMode
@@ -1125,7 +1153,7 @@ @@ -1125,7 +1149,7 @@
? event.screenY - window.screenY - tabOffset ? event.screenY - window.screenY - tabOffset
: event.screenY - window.screenY, : event.screenY - window.screenY,
scrollPos: scrollPos:
@@ -204,7 +233,7 @@ index 57800333445ec7850742145527e04ae8d504b0bb..65361da4791b6418705f364f750f409b
? this._tabbrowserTabs.pinnedTabsContainer.scrollPosition ? this._tabbrowserTabs.pinnedTabsContainer.scrollPosition
: this._tabbrowserTabs.arrowScrollbox.scrollPosition, : this._tabbrowserTabs.arrowScrollbox.scrollPosition,
screenX: event.screenX, screenX: event.screenX,
@@ -1152,6 +1180,7 @@ @@ -1152,6 +1176,7 @@
if (collapseTabGroupDuringDrag) { if (collapseTabGroupDuringDrag) {
tab.group.collapsed = true; tab.group.collapsed = true;
@@ -212,7 +241,7 @@ index 57800333445ec7850742145527e04ae8d504b0bb..65361da4791b6418705f364f750f409b
} }
} }
} }
@@ -1176,6 +1205,7 @@ @@ -1176,6 +1201,7 @@
if (tabStripItemElement.hasAttribute("dragtarget")) { if (tabStripItemElement.hasAttribute("dragtarget")) {
return; return;
} }
@@ -220,7 +249,7 @@ index 57800333445ec7850742145527e04ae8d504b0bb..65361da4791b6418705f364f750f409b
let isPinned = tab.pinned; let isPinned = tab.pinned;
let numPinned = gBrowser.pinnedTabCount; let numPinned = gBrowser.pinnedTabCount;
let dragAndDropElements = this._tabbrowserTabs.dragAndDropElements; let dragAndDropElements = this._tabbrowserTabs.dragAndDropElements;
@@ -1601,7 +1631,6 @@ @@ -1601,7 +1627,6 @@
for (let item of this._tabbrowserTabs.dragAndDropElements) { for (let item of this._tabbrowserTabs.dragAndDropElements) {
item = elementToMove(item); item = elementToMove(item);
@@ -228,7 +257,7 @@ index 57800333445ec7850742145527e04ae8d504b0bb..65361da4791b6418705f364f750f409b
item.removeAttribute("multiselected-move-together"); item.removeAttribute("multiselected-move-together");
delete item._moveTogetherSelectedTabsData; delete item._moveTogetherSelectedTabsData;
} }
@@ -2429,7 +2458,6 @@ @@ -2429,7 +2454,6 @@
for (let item of this._tabbrowserTabs.dragAndDropElements) { for (let item of this._tabbrowserTabs.dragAndDropElements) {
this._resetGroupTarget(item); this._resetGroupTarget(item);
item = elementToMove(item); item = elementToMove(item);
@@ -236,7 +265,7 @@ index 57800333445ec7850742145527e04ae8d504b0bb..65361da4791b6418705f364f750f409b
} }
this._tabbrowserTabs.removeAttribute("movingtab-group"); this._tabbrowserTabs.removeAttribute("movingtab-group");
this._tabbrowserTabs.removeAttribute("movingtab-ungroup"); this._tabbrowserTabs.removeAttribute("movingtab-ungroup");
@@ -2460,17 +2488,14 @@ @@ -2460,17 +2484,14 @@
tab.style.left = ""; tab.style.left = "";
tab.style.top = ""; tab.style.top = "";
tab.style.maxWidth = ""; tab.style.maxWidth = "";

View File

@@ -1,5 +1,5 @@
diff --git a/browser/components/tabbrowser/content/tabbrowser.js b/browser/components/tabbrowser/content/tabbrowser.js diff --git a/browser/components/tabbrowser/content/tabbrowser.js b/browser/components/tabbrowser/content/tabbrowser.js
index 0eaca7a58e0026237b71b2ad515efe84d9e8c779..9c1fa86151f3d5896c45fef31a1417570d4f1266 100644 index 0eaca7a58e0026237b71b2ad515efe84d9e8c779..7f759f43a4aa1e0d96f8003a50c5df269ec4a131 100644
--- a/browser/components/tabbrowser/content/tabbrowser.js --- a/browser/components/tabbrowser/content/tabbrowser.js
+++ b/browser/components/tabbrowser/content/tabbrowser.js +++ b/browser/components/tabbrowser/content/tabbrowser.js
@@ -398,6 +398,7 @@ @@ -398,6 +398,7 @@
@@ -119,7 +119,7 @@ index 0eaca7a58e0026237b71b2ad515efe84d9e8c779..9c1fa86151f3d5896c45fef31a141757
aTab.setAttribute("pinned", "true"); aTab.setAttribute("pinned", "true");
this._updateTabBarForPinnedTabs(); this._updateTabBarForPinnedTabs();
@@ -931,11 +994,18 @@ @@ -931,11 +994,19 @@
} }
this.#handleTabMove(aTab, () => { this.#handleTabMove(aTab, () => {
@@ -133,13 +133,14 @@ index 0eaca7a58e0026237b71b2ad515efe84d9e8c779..9c1fa86151f3d5896c45fef31a141757
// and back into arrowscrollbox. // and back into arrowscrollbox.
aTab.removeAttribute("pinned"); aTab.removeAttribute("pinned");
- this.tabContainer.arrowScrollbox.prepend(aTab); - this.tabContainer.arrowScrollbox.prepend(aTab);
+ aTab.removeAttribute("zen-essential");
+ if (!handled) { + if (!handled) {
+ gZenWorkspaces.activeWorkspaceStrip.prepend(aTab); + gZenWorkspaces.activeWorkspaceStrip.prepend(aTab);
+ } + }
}); });
aTab.style.marginInlineStart = ""; aTab.style.marginInlineStart = "";
@@ -1112,6 +1182,9 @@ @@ -1112,6 +1183,9 @@
let LOCAL_PROTOCOLS = ["chrome:", "about:", "resource:", "data:"]; let LOCAL_PROTOCOLS = ["chrome:", "about:", "resource:", "data:"];
@@ -149,7 +150,7 @@ index 0eaca7a58e0026237b71b2ad515efe84d9e8c779..9c1fa86151f3d5896c45fef31a141757
if ( if (
aIconURL && aIconURL &&
!LOCAL_PROTOCOLS.some(protocol => aIconURL.startsWith(protocol)) !LOCAL_PROTOCOLS.some(protocol => aIconURL.startsWith(protocol))
@@ -1121,6 +1194,9 @@ @@ -1121,6 +1195,9 @@
); );
return; return;
} }
@@ -159,7 +160,7 @@ index 0eaca7a58e0026237b71b2ad515efe84d9e8c779..9c1fa86151f3d5896c45fef31a141757
let browser = this.getBrowserForTab(aTab); let browser = this.getBrowserForTab(aTab);
browser.mIconURL = aIconURL; browser.mIconURL = aIconURL;
@@ -1393,7 +1469,6 @@ @@ -1393,7 +1470,6 @@
// Preview mode should not reset the owner // Preview mode should not reset the owner
if (!this._previewMode && !oldTab.selected) { if (!this._previewMode && !oldTab.selected) {
@@ -167,7 +168,7 @@ index 0eaca7a58e0026237b71b2ad515efe84d9e8c779..9c1fa86151f3d5896c45fef31a141757
} }
let lastRelatedTab = this._lastRelatedTabMap.get(oldTab); let lastRelatedTab = this._lastRelatedTabMap.get(oldTab);
@@ -1484,6 +1559,7 @@ @@ -1484,6 +1560,7 @@
if (!this._previewMode) { if (!this._previewMode) {
newTab.recordTimeFromUnloadToReload(); newTab.recordTimeFromUnloadToReload();
newTab.updateLastAccessed(); newTab.updateLastAccessed();
@@ -175,7 +176,7 @@ index 0eaca7a58e0026237b71b2ad515efe84d9e8c779..9c1fa86151f3d5896c45fef31a141757
oldTab.updateLastAccessed(); oldTab.updateLastAccessed();
// if this is the foreground window, update the last-seen timestamps. // if this is the foreground window, update the last-seen timestamps.
if (this.ownerGlobal == BrowserWindowTracker.getTopWindow()) { if (this.ownerGlobal == BrowserWindowTracker.getTopWindow()) {
@@ -1636,6 +1712,9 @@ @@ -1636,6 +1713,9 @@
} }
let activeEl = document.activeElement; let activeEl = document.activeElement;
@@ -185,7 +186,7 @@ index 0eaca7a58e0026237b71b2ad515efe84d9e8c779..9c1fa86151f3d5896c45fef31a141757
// If focus is on the old tab, move it to the new tab. // If focus is on the old tab, move it to the new tab.
if (activeEl == oldTab) { if (activeEl == oldTab) {
newTab.focus(); newTab.focus();
@@ -1959,6 +2038,11 @@ @@ -1959,6 +2039,11 @@
} }
_setTabLabel(aTab, aLabel, { beforeTabOpen, isContentTitle, isURL } = {}) { _setTabLabel(aTab, aLabel, { beforeTabOpen, isContentTitle, isURL } = {}) {
@@ -197,7 +198,7 @@ index 0eaca7a58e0026237b71b2ad515efe84d9e8c779..9c1fa86151f3d5896c45fef31a141757
if (!aLabel || aLabel.includes("about:reader?")) { if (!aLabel || aLabel.includes("about:reader?")) {
return false; return false;
} }
@@ -2067,7 +2151,7 @@ @@ -2067,7 +2152,7 @@
newIndex = this.selectedTab._tPos + 1; newIndex = this.selectedTab._tPos + 1;
} }
@@ -206,7 +207,7 @@ index 0eaca7a58e0026237b71b2ad515efe84d9e8c779..9c1fa86151f3d5896c45fef31a141757
if (this.isTabGroupLabel(targetTab)) { if (this.isTabGroupLabel(targetTab)) {
throw new Error( throw new Error(
"Replacing a tab group label with a tab is not supported" "Replacing a tab group label with a tab is not supported"
@@ -2342,6 +2426,7 @@ @@ -2342,6 +2427,7 @@
uriIsAboutBlank, uriIsAboutBlank,
userContextId, userContextId,
skipLoad, skipLoad,
@@ -214,7 +215,7 @@ index 0eaca7a58e0026237b71b2ad515efe84d9e8c779..9c1fa86151f3d5896c45fef31a141757
} = {}) { } = {}) {
let b = document.createXULElement("browser"); let b = document.createXULElement("browser");
// Use the JSM global to create the permanentKey, so that if the // Use the JSM global to create the permanentKey, so that if the
@@ -2415,8 +2500,7 @@ @@ -2415,8 +2501,7 @@
// we use a different attribute name for this? // we use a different attribute name for this?
b.setAttribute("name", name); b.setAttribute("name", name);
} }
@@ -224,7 +225,7 @@ index 0eaca7a58e0026237b71b2ad515efe84d9e8c779..9c1fa86151f3d5896c45fef31a141757
b.setAttribute("transparent", "true"); b.setAttribute("transparent", "true");
} }
@@ -2581,7 +2665,7 @@ @@ -2581,7 +2666,7 @@
let panel = this.getPanel(browser); let panel = this.getPanel(browser);
let uniqueId = this._generateUniquePanelID(); let uniqueId = this._generateUniquePanelID();
@@ -233,7 +234,7 @@ index 0eaca7a58e0026237b71b2ad515efe84d9e8c779..9c1fa86151f3d5896c45fef31a141757
aTab.linkedPanel = uniqueId; aTab.linkedPanel = uniqueId;
// Inject the <browser> into the DOM if necessary. // Inject the <browser> into the DOM if necessary.
@@ -2640,8 +2724,8 @@ @@ -2640,8 +2725,8 @@
// If we transitioned from one browser to two browsers, we need to set // If we transitioned from one browser to two browsers, we need to set
// hasSiblings=false on both the existing browser and the new browser. // hasSiblings=false on both the existing browser and the new browser.
if (this.tabs.length == 2) { if (this.tabs.length == 2) {
@@ -244,7 +245,7 @@ index 0eaca7a58e0026237b71b2ad515efe84d9e8c779..9c1fa86151f3d5896c45fef31a141757
} else { } else {
aTab.linkedBrowser.browsingContext.hasSiblings = this.tabs.length > 1; aTab.linkedBrowser.browsingContext.hasSiblings = this.tabs.length > 1;
} }
@@ -2828,7 +2912,6 @@ @@ -2828,7 +2913,6 @@
this.selectedTab = this.addTrustedTab(BROWSER_NEW_TAB_URL, { this.selectedTab = this.addTrustedTab(BROWSER_NEW_TAB_URL, {
tabIndex: tab._tPos + 1, tabIndex: tab._tPos + 1,
userContextId: tab.userContextId, userContextId: tab.userContextId,
@@ -252,7 +253,7 @@ index 0eaca7a58e0026237b71b2ad515efe84d9e8c779..9c1fa86151f3d5896c45fef31a141757
focusUrlBar: true, focusUrlBar: true,
}); });
resolve(this.selectedBrowser); resolve(this.selectedBrowser);
@@ -2938,6 +3021,9 @@ @@ -2938,6 +3022,9 @@
schemelessInput, schemelessInput,
hasValidUserGestureActivation = false, hasValidUserGestureActivation = false,
textDirectiveUserActivation = false, textDirectiveUserActivation = false,
@@ -262,7 +263,7 @@ index 0eaca7a58e0026237b71b2ad515efe84d9e8c779..9c1fa86151f3d5896c45fef31a141757
} = {} } = {}
) { ) {
// all callers of addTab that pass a params object need to pass // all callers of addTab that pass a params object need to pass
@@ -2948,10 +3034,17 @@ @@ -2948,10 +3035,17 @@
); );
} }
@@ -280,7 +281,7 @@ index 0eaca7a58e0026237b71b2ad515efe84d9e8c779..9c1fa86151f3d5896c45fef31a141757
// If we're opening a foreground tab, set the owner by default. // If we're opening a foreground tab, set the owner by default.
ownerTab ??= inBackground ? null : this.selectedTab; ownerTab ??= inBackground ? null : this.selectedTab;
@@ -2959,6 +3052,7 @@ @@ -2959,6 +3053,7 @@
if (this.selectedTab.owner) { if (this.selectedTab.owner) {
this.selectedTab.owner = null; this.selectedTab.owner = null;
} }
@@ -288,7 +289,7 @@ index 0eaca7a58e0026237b71b2ad515efe84d9e8c779..9c1fa86151f3d5896c45fef31a141757
// Find the tab that opened this one, if any. This is used for // Find the tab that opened this one, if any. This is used for
// determining positioning, and inherited attributes such as the // determining positioning, and inherited attributes such as the
@@ -3011,6 +3105,22 @@ @@ -3011,6 +3106,22 @@
noInitialLabel, noInitialLabel,
skipBackgroundNotify, skipBackgroundNotify,
}); });
@@ -311,7 +312,7 @@ index 0eaca7a58e0026237b71b2ad515efe84d9e8c779..9c1fa86151f3d5896c45fef31a141757
if (insertTab) { if (insertTab) {
// Insert the tab into the tab container in the correct position. // Insert the tab into the tab container in the correct position.
this.#insertTabAtIndex(t, { this.#insertTabAtIndex(t, {
@@ -3019,6 +3129,7 @@ @@ -3019,6 +3130,7 @@
ownerTab, ownerTab,
openerTab, openerTab,
pinned, pinned,
@@ -319,7 +320,7 @@ index 0eaca7a58e0026237b71b2ad515efe84d9e8c779..9c1fa86151f3d5896c45fef31a141757
bulkOrderedOpen, bulkOrderedOpen,
tabGroup: tabGroup ?? openerTab?.group, tabGroup: tabGroup ?? openerTab?.group,
}); });
@@ -3037,6 +3148,7 @@ @@ -3037,6 +3149,7 @@
openWindowInfo, openWindowInfo,
skipLoad, skipLoad,
triggeringRemoteType, triggeringRemoteType,
@@ -327,7 +328,7 @@ index 0eaca7a58e0026237b71b2ad515efe84d9e8c779..9c1fa86151f3d5896c45fef31a141757
})); }));
if (focusUrlBar) { if (focusUrlBar) {
@@ -3161,6 +3273,12 @@ @@ -3161,6 +3274,12 @@
} }
} }
@@ -340,7 +341,7 @@ index 0eaca7a58e0026237b71b2ad515efe84d9e8c779..9c1fa86151f3d5896c45fef31a141757
// Additionally send pinned tab events // Additionally send pinned tab events
if (pinned) { if (pinned) {
this.#notifyPinnedStatus(t); this.#notifyPinnedStatus(t);
@@ -3375,6 +3493,7 @@ @@ -3375,6 +3494,7 @@
isAdoptingGroup = false, isAdoptingGroup = false,
isUserTriggered = false, isUserTriggered = false,
telemetryUserCreateSource = "unknown", telemetryUserCreateSource = "unknown",
@@ -348,7 +349,7 @@ index 0eaca7a58e0026237b71b2ad515efe84d9e8c779..9c1fa86151f3d5896c45fef31a141757
} = {} } = {}
) { ) {
if ( if (
@@ -3385,9 +3504,6 @@ @@ -3385,9 +3505,6 @@
!this.isSplitViewWrapper(tabOrSplitView) !this.isSplitViewWrapper(tabOrSplitView)
) )
) { ) {
@@ -358,7 +359,7 @@ index 0eaca7a58e0026237b71b2ad515efe84d9e8c779..9c1fa86151f3d5896c45fef31a141757
} }
if (!color) { if (!color) {
@@ -3408,9 +3524,14 @@ @@ -3408,9 +3525,14 @@
label, label,
isAdoptingGroup isAdoptingGroup
); );
@@ -375,7 +376,7 @@ index 0eaca7a58e0026237b71b2ad515efe84d9e8c779..9c1fa86151f3d5896c45fef31a141757
); );
group.addTabs(tabsAndSplitViews); group.addTabs(tabsAndSplitViews);
@@ -3531,7 +3652,7 @@ @@ -3531,7 +3653,7 @@
} }
this.#handleTabMove(tab, () => this.#handleTabMove(tab, () =>
@@ -384,7 +385,15 @@ index 0eaca7a58e0026237b71b2ad515efe84d9e8c779..9c1fa86151f3d5896c45fef31a141757
); );
} }
@@ -3746,6 +3867,7 @@ @@ -3599,6 +3721,7 @@
color: group.color,
insertBefore: newTabs[0],
isAdoptingGroup: true,
+ forSplitView: group.hasAttribute('split-view-group'),
});
}
@@ -3746,6 +3869,7 @@
openWindowInfo, openWindowInfo,
skipLoad, skipLoad,
triggeringRemoteType, triggeringRemoteType,
@@ -392,7 +401,7 @@ index 0eaca7a58e0026237b71b2ad515efe84d9e8c779..9c1fa86151f3d5896c45fef31a141757
} }
) { ) {
// If we don't have a preferred remote type (or it is `NOT_REMOTE`), and // If we don't have a preferred remote type (or it is `NOT_REMOTE`), and
@@ -3815,6 +3937,7 @@ @@ -3815,6 +3939,7 @@
openWindowInfo, openWindowInfo,
name, name,
skipLoad, skipLoad,
@@ -400,7 +409,7 @@ index 0eaca7a58e0026237b71b2ad515efe84d9e8c779..9c1fa86151f3d5896c45fef31a141757
}); });
} }
@@ -4003,7 +4126,7 @@ @@ -4003,7 +4128,7 @@
// Add a new tab if needed. // Add a new tab if needed.
if (!tab) { if (!tab) {
let createLazyBrowser = let createLazyBrowser =
@@ -409,7 +418,7 @@ index 0eaca7a58e0026237b71b2ad515efe84d9e8c779..9c1fa86151f3d5896c45fef31a141757
let url = "about:blank"; let url = "about:blank";
if (tabData.entries?.length) { if (tabData.entries?.length) {
@@ -4040,8 +4163,10 @@ @@ -4040,8 +4165,10 @@
insertTab: false, insertTab: false,
skipLoad: true, skipLoad: true,
preferredRemoteType, preferredRemoteType,
@@ -421,7 +430,7 @@ index 0eaca7a58e0026237b71b2ad515efe84d9e8c779..9c1fa86151f3d5896c45fef31a141757
if (select) { if (select) {
tabToSelect = tab; tabToSelect = tab;
} }
@@ -4053,7 +4178,8 @@ @@ -4053,7 +4180,8 @@
this.pinTab(tab); this.pinTab(tab);
// Then ensure all the tab open/pinning information is sent. // Then ensure all the tab open/pinning information is sent.
this._fireTabOpen(tab, {}); this._fireTabOpen(tab, {});
@@ -431,7 +440,7 @@ index 0eaca7a58e0026237b71b2ad515efe84d9e8c779..9c1fa86151f3d5896c45fef31a141757
let { groupId } = tabData; let { groupId } = tabData;
const tabGroup = tabGroupWorkingData.get(groupId); const tabGroup = tabGroupWorkingData.get(groupId);
// if a tab refers to a tab group we don't know, skip any group // if a tab refers to a tab group we don't know, skip any group
@@ -4067,7 +4193,10 @@ @@ -4067,7 +4195,10 @@
tabGroup.stateData.id, tabGroup.stateData.id,
tabGroup.stateData.color, tabGroup.stateData.color,
tabGroup.stateData.collapsed, tabGroup.stateData.collapsed,
@@ -443,7 +452,7 @@ index 0eaca7a58e0026237b71b2ad515efe84d9e8c779..9c1fa86151f3d5896c45fef31a141757
); );
tabsFragment.appendChild(tabGroup.node); tabsFragment.appendChild(tabGroup.node);
} }
@@ -4112,9 +4241,23 @@ @@ -4112,9 +4243,23 @@
// to remove the old selected tab. // to remove the old selected tab.
if (tabToSelect) { if (tabToSelect) {
let leftoverTab = this.selectedTab; let leftoverTab = this.selectedTab;
@@ -459,15 +468,15 @@ index 0eaca7a58e0026237b71b2ad515efe84d9e8c779..9c1fa86151f3d5896c45fef31a141757
+ gZenWorkspaces._initialTab._shouldRemove = true; + gZenWorkspaces._initialTab._shouldRemove = true;
+ } + }
+ } + }
} + }
+ else { + else {
+ gZenWorkspaces._tabToRemoveForEmpty = this.selectedTab; + gZenWorkspaces._tabToRemoveForEmpty = this.selectedTab;
+ } }
+ this._hasAlreadyInitializedZenSessionStore = true; + this._hasAlreadyInitializedZenSessionStore = true;
if (tabs.length > 1 || !tabs[0].selected) { if (tabs.length > 1 || !tabs[0].selected) {
this._updateTabsAfterInsert(); this._updateTabsAfterInsert();
@@ -4305,11 +4448,14 @@ @@ -4305,11 +4450,14 @@
if (ownerTab) { if (ownerTab) {
tab.owner = ownerTab; tab.owner = ownerTab;
} }
@@ -483,7 +492,7 @@ index 0eaca7a58e0026237b71b2ad515efe84d9e8c779..9c1fa86151f3d5896c45fef31a141757
if ( if (
!bulkOrderedOpen && !bulkOrderedOpen &&
((openerTab && ((openerTab &&
@@ -4321,7 +4467,7 @@ @@ -4321,7 +4469,7 @@
let lastRelatedTab = let lastRelatedTab =
openerTab && this._lastRelatedTabMap.get(openerTab); openerTab && this._lastRelatedTabMap.get(openerTab);
let previousTab = lastRelatedTab || openerTab || this.selectedTab; let previousTab = lastRelatedTab || openerTab || this.selectedTab;
@@ -492,7 +501,7 @@ index 0eaca7a58e0026237b71b2ad515efe84d9e8c779..9c1fa86151f3d5896c45fef31a141757
tabGroup = previousTab.group; tabGroup = previousTab.group;
} }
if ( if (
@@ -4337,7 +4483,7 @@ @@ -4337,7 +4485,7 @@
previousTab.splitview previousTab.splitview
) + 1; ) + 1;
} else if (previousTab.visible) { } else if (previousTab.visible) {
@@ -501,7 +510,7 @@ index 0eaca7a58e0026237b71b2ad515efe84d9e8c779..9c1fa86151f3d5896c45fef31a141757
} else if (previousTab == FirefoxViewHandler.tab) { } else if (previousTab == FirefoxViewHandler.tab) {
elementIndex = 0; elementIndex = 0;
} }
@@ -4365,14 +4511,14 @@ @@ -4365,14 +4513,14 @@
} }
// Ensure index is within bounds. // Ensure index is within bounds.
if (tab.pinned) { if (tab.pinned) {
@@ -520,7 +529,7 @@ index 0eaca7a58e0026237b71b2ad515efe84d9e8c779..9c1fa86151f3d5896c45fef31a141757
if (pinned && !itemAfter?.pinned) { if (pinned && !itemAfter?.pinned) {
itemAfter = null; itemAfter = null;
@@ -4385,7 +4531,7 @@ @@ -4385,7 +4533,7 @@
this.tabContainer._invalidateCachedTabs(); this.tabContainer._invalidateCachedTabs();
@@ -529,7 +538,7 @@ index 0eaca7a58e0026237b71b2ad515efe84d9e8c779..9c1fa86151f3d5896c45fef31a141757
if ( if (
(this.isTab(itemAfter) && itemAfter.group == tabGroup) || (this.isTab(itemAfter) && itemAfter.group == tabGroup) ||
this.isSplitViewWrapper(itemAfter) this.isSplitViewWrapper(itemAfter)
@@ -4416,7 +4562,11 @@ @@ -4416,7 +4564,11 @@
const tabContainer = pinned const tabContainer = pinned
? this.tabContainer.pinnedTabsContainer ? this.tabContainer.pinnedTabsContainer
: this.tabContainer; : this.tabContainer;
@@ -541,7 +550,7 @@ index 0eaca7a58e0026237b71b2ad515efe84d9e8c779..9c1fa86151f3d5896c45fef31a141757
} }
if (tab.group?.collapsed) { if (tab.group?.collapsed) {
@@ -4431,6 +4581,7 @@ @@ -4431,6 +4583,7 @@
if (pinned) { if (pinned) {
this._updateTabBarForPinnedTabs(); this._updateTabBarForPinnedTabs();
} }
@@ -549,7 +558,7 @@ index 0eaca7a58e0026237b71b2ad515efe84d9e8c779..9c1fa86151f3d5896c45fef31a141757
TabBarVisibility.update(); TabBarVisibility.update();
} }
@@ -4983,6 +5134,7 @@ @@ -4983,6 +5136,7 @@
telemetrySource, telemetrySource,
} = {} } = {}
) { ) {
@@ -557,7 +566,7 @@ index 0eaca7a58e0026237b71b2ad515efe84d9e8c779..9c1fa86151f3d5896c45fef31a141757
// When 'closeWindowWithLastTab' pref is enabled, closing all tabs // When 'closeWindowWithLastTab' pref is enabled, closing all tabs
// can be considered equivalent to closing the window. // can be considered equivalent to closing the window.
if ( if (
@@ -5072,6 +5224,7 @@ @@ -5072,6 +5226,7 @@
if (lastToClose) { if (lastToClose) {
this.removeTab(lastToClose, aParams); this.removeTab(lastToClose, aParams);
} }
@@ -565,7 +574,7 @@ index 0eaca7a58e0026237b71b2ad515efe84d9e8c779..9c1fa86151f3d5896c45fef31a141757
} catch (e) { } catch (e) {
console.error(e); console.error(e);
} }
@@ -5110,6 +5263,12 @@ @@ -5110,6 +5265,12 @@
aTab._closeTimeNoAnimTimerId = Glean.browserTabclose.timeNoAnim.start(); aTab._closeTimeNoAnimTimerId = Glean.browserTabclose.timeNoAnim.start();
} }
@@ -578,7 +587,7 @@ index 0eaca7a58e0026237b71b2ad515efe84d9e8c779..9c1fa86151f3d5896c45fef31a141757
// Handle requests for synchronously removing an already // Handle requests for synchronously removing an already
// asynchronously closing tab. // asynchronously closing tab.
if (!animate && aTab.closing) { if (!animate && aTab.closing) {
@@ -5124,6 +5283,9 @@ @@ -5124,6 +5285,9 @@
// state). // state).
let tabWidth = window.windowUtils.getBoundsWithoutFlushing(aTab).width; let tabWidth = window.windowUtils.getBoundsWithoutFlushing(aTab).width;
let isLastTab = this.#isLastTabInWindow(aTab); let isLastTab = this.#isLastTabInWindow(aTab);
@@ -588,7 +597,7 @@ index 0eaca7a58e0026237b71b2ad515efe84d9e8c779..9c1fa86151f3d5896c45fef31a141757
if ( if (
!this._beginRemoveTab(aTab, { !this._beginRemoveTab(aTab, {
closeWindowFastpath: true, closeWindowFastpath: true,
@@ -5172,7 +5334,13 @@ @@ -5172,7 +5336,13 @@
// We're not animating, so we can cancel the animation stopwatch. // We're not animating, so we can cancel the animation stopwatch.
Glean.browserTabclose.timeAnim.cancel(aTab._closeTimeAnimTimerId); Glean.browserTabclose.timeAnim.cancel(aTab._closeTimeAnimTimerId);
aTab._closeTimeAnimTimerId = null; aTab._closeTimeAnimTimerId = null;
@@ -603,7 +612,7 @@ index 0eaca7a58e0026237b71b2ad515efe84d9e8c779..9c1fa86151f3d5896c45fef31a141757
return; return;
} }
@@ -5306,7 +5474,7 @@ @@ -5306,7 +5476,7 @@
closeWindowWithLastTab != null closeWindowWithLastTab != null
? closeWindowWithLastTab ? closeWindowWithLastTab
: !window.toolbar.visible || : !window.toolbar.visible ||
@@ -612,7 +621,7 @@ index 0eaca7a58e0026237b71b2ad515efe84d9e8c779..9c1fa86151f3d5896c45fef31a141757
if (closeWindow) { if (closeWindow) {
// We've already called beforeunload on all the relevant tabs if we get here, // We've already called beforeunload on all the relevant tabs if we get here,
@@ -5330,6 +5498,7 @@ @@ -5330,6 +5500,7 @@
newTab = true; newTab = true;
} }
@@ -620,7 +629,7 @@ index 0eaca7a58e0026237b71b2ad515efe84d9e8c779..9c1fa86151f3d5896c45fef31a141757
aTab._endRemoveArgs = [closeWindow, newTab]; aTab._endRemoveArgs = [closeWindow, newTab];
// swapBrowsersAndCloseOther will take care of closing the window without animation. // swapBrowsersAndCloseOther will take care of closing the window without animation.
@@ -5370,13 +5539,7 @@ @@ -5370,13 +5541,7 @@
aTab._mouseleave(); aTab._mouseleave();
if (newTab) { if (newTab) {
@@ -635,7 +644,7 @@ index 0eaca7a58e0026237b71b2ad515efe84d9e8c779..9c1fa86151f3d5896c45fef31a141757
} else { } else {
TabBarVisibility.update(); TabBarVisibility.update();
} }
@@ -5509,6 +5672,7 @@ @@ -5509,6 +5674,7 @@
this.tabs[i]._tPos = i; this.tabs[i]._tPos = i;
} }
@@ -643,7 +652,7 @@ index 0eaca7a58e0026237b71b2ad515efe84d9e8c779..9c1fa86151f3d5896c45fef31a141757
if (!this._windowIsClosing) { if (!this._windowIsClosing) {
// update tab close buttons state // update tab close buttons state
this.tabContainer._updateCloseButtons(); this.tabContainer._updateCloseButtons();
@@ -5732,6 +5896,7 @@ @@ -5732,6 +5898,7 @@
} }
let excludeTabs = new Set(aExcludeTabs); let excludeTabs = new Set(aExcludeTabs);
@@ -651,7 +660,7 @@ index 0eaca7a58e0026237b71b2ad515efe84d9e8c779..9c1fa86151f3d5896c45fef31a141757
// If this tab has a successor, it should be selectable, since // If this tab has a successor, it should be selectable, since
// hiding or closing a tab removes that tab as a successor. // hiding or closing a tab removes that tab as a successor.
@@ -5744,15 +5909,22 @@ @@ -5744,15 +5911,22 @@
!excludeTabs.has(aTab.owner) && !excludeTabs.has(aTab.owner) &&
Services.prefs.getBoolPref("browser.tabs.selectOwnerOnClose") Services.prefs.getBoolPref("browser.tabs.selectOwnerOnClose")
) { ) {
@@ -676,7 +685,7 @@ index 0eaca7a58e0026237b71b2ad515efe84d9e8c779..9c1fa86151f3d5896c45fef31a141757
let tab = this.tabContainer.findNextTab(aTab, { let tab = this.tabContainer.findNextTab(aTab, {
direction: 1, direction: 1,
filter: _tab => remainingTabs.includes(_tab), filter: _tab => remainingTabs.includes(_tab),
@@ -5766,7 +5938,7 @@ @@ -5766,7 +5940,7 @@
} }
if (tab) { if (tab) {
@@ -685,7 +694,7 @@ index 0eaca7a58e0026237b71b2ad515efe84d9e8c779..9c1fa86151f3d5896c45fef31a141757
} }
// If no qualifying visible tab was found, see if there is a tab in // If no qualifying visible tab was found, see if there is a tab in
@@ -5787,7 +5959,7 @@ @@ -5787,7 +5961,7 @@
}); });
} }
@@ -694,7 +703,7 @@ index 0eaca7a58e0026237b71b2ad515efe84d9e8c779..9c1fa86151f3d5896c45fef31a141757
} }
_blurTab(aTab) { _blurTab(aTab) {
@@ -5798,7 +5970,7 @@ @@ -5798,7 +5972,7 @@
* @returns {boolean} * @returns {boolean}
* False if swapping isn't permitted, true otherwise. * False if swapping isn't permitted, true otherwise.
*/ */
@@ -703,7 +712,7 @@ index 0eaca7a58e0026237b71b2ad515efe84d9e8c779..9c1fa86151f3d5896c45fef31a141757
// Do not allow transfering a private tab to a non-private window // Do not allow transfering a private tab to a non-private window
// and vice versa. // and vice versa.
if ( if (
@@ -5852,6 +6024,7 @@ @@ -5852,6 +6026,7 @@
// fire the beforeunload event in the process. Close the other // fire the beforeunload event in the process. Close the other
// window if this was its last tab. // window if this was its last tab.
if ( if (
@@ -711,7 +720,7 @@ index 0eaca7a58e0026237b71b2ad515efe84d9e8c779..9c1fa86151f3d5896c45fef31a141757
!remoteBrowser._beginRemoveTab(aOtherTab, { !remoteBrowser._beginRemoveTab(aOtherTab, {
adoptedByTab: aOurTab, adoptedByTab: aOurTab,
closeWindowWithLastTab: true, closeWindowWithLastTab: true,
@@ -5863,7 +6036,7 @@ @@ -5863,7 +6038,7 @@
// If this is the last tab of the window, hide the window // If this is the last tab of the window, hide the window
// immediately without animation before the docshell swap, to avoid // immediately without animation before the docshell swap, to avoid
// about:blank being painted. // about:blank being painted.
@@ -720,7 +729,7 @@ index 0eaca7a58e0026237b71b2ad515efe84d9e8c779..9c1fa86151f3d5896c45fef31a141757
if (closeWindow) { if (closeWindow) {
let win = aOtherTab.ownerGlobal; let win = aOtherTab.ownerGlobal;
win.windowUtils.suppressAnimation(true); win.windowUtils.suppressAnimation(true);
@@ -5987,11 +6160,13 @@ @@ -5987,11 +6162,13 @@
} }
// Finish tearing down the tab that's going away. // Finish tearing down the tab that's going away.
@@ -734,7 +743,7 @@ index 0eaca7a58e0026237b71b2ad515efe84d9e8c779..9c1fa86151f3d5896c45fef31a141757
this.setTabTitle(aOurTab); this.setTabTitle(aOurTab);
@@ -6193,10 +6368,10 @@ @@ -6193,10 +6370,10 @@
SessionStore.deleteCustomTabValue(aTab, "hiddenBy"); SessionStore.deleteCustomTabValue(aTab, "hiddenBy");
} }
@@ -747,7 +756,7 @@ index 0eaca7a58e0026237b71b2ad515efe84d9e8c779..9c1fa86151f3d5896c45fef31a141757
aTab.selected || aTab.selected ||
aTab.closing || aTab.closing ||
// Tabs that are sharing the screen, microphone or camera cannot be hidden. // Tabs that are sharing the screen, microphone or camera cannot be hidden.
@@ -6254,7 +6429,8 @@ @@ -6254,7 +6431,8 @@
* *
* @param {MozTabbrowserTab|MozTabbrowserTabGroup|MozTabbrowserTabGroup.labelElement} aTab * @param {MozTabbrowserTab|MozTabbrowserTabGroup|MozTabbrowserTabGroup.labelElement} aTab
*/ */
@@ -757,7 +766,7 @@ index 0eaca7a58e0026237b71b2ad515efe84d9e8c779..9c1fa86151f3d5896c45fef31a141757
if (this.tabs.length == 1) { if (this.tabs.length == 1) {
return null; return null;
} }
@@ -6278,12 +6454,14 @@ @@ -6278,12 +6456,14 @@
} }
// tell a new window to take the "dropped" tab // tell a new window to take the "dropped" tab
@@ -773,7 +782,7 @@ index 0eaca7a58e0026237b71b2ad515efe84d9e8c779..9c1fa86151f3d5896c45fef31a141757
} }
/** /**
@@ -6388,7 +6566,7 @@ @@ -6388,7 +6568,7 @@
* `true` if element is a `<tab-group>` * `true` if element is a `<tab-group>`
*/ */
isTabGroup(element) { isTabGroup(element) {
@@ -782,7 +791,7 @@ index 0eaca7a58e0026237b71b2ad515efe84d9e8c779..9c1fa86151f3d5896c45fef31a141757
} }
/** /**
@@ -6473,8 +6651,8 @@ @@ -6473,8 +6653,8 @@
} }
// Don't allow mixing pinned and unpinned tabs. // Don't allow mixing pinned and unpinned tabs.
@@ -793,7 +802,7 @@ index 0eaca7a58e0026237b71b2ad515efe84d9e8c779..9c1fa86151f3d5896c45fef31a141757
} else { } else {
tabIndex = Math.max(tabIndex, this.pinnedTabCount); tabIndex = Math.max(tabIndex, this.pinnedTabCount);
} }
@@ -6500,10 +6678,16 @@ @@ -6500,10 +6680,16 @@
this.#handleTabMove( this.#handleTabMove(
element, element,
() => { () => {
@@ -812,7 +821,7 @@ index 0eaca7a58e0026237b71b2ad515efe84d9e8c779..9c1fa86151f3d5896c45fef31a141757
if (neighbor && this.isTab(element) && tabIndex > element._tPos) { if (neighbor && this.isTab(element) && tabIndex > element._tPos) {
neighbor.after(element); neighbor.after(element);
} else { } else {
@@ -6561,23 +6745,31 @@ @@ -6561,23 +6747,31 @@
#moveTabNextTo(element, targetElement, moveBefore = false, metricsContext) { #moveTabNextTo(element, targetElement, moveBefore = false, metricsContext) {
if (this.isTabGroupLabel(targetElement)) { if (this.isTabGroupLabel(targetElement)) {
targetElement = targetElement.group; targetElement = targetElement.group;
@@ -850,7 +859,7 @@ index 0eaca7a58e0026237b71b2ad515efe84d9e8c779..9c1fa86151f3d5896c45fef31a141757
} else if (!element.pinned && targetElement && targetElement.pinned) { } else if (!element.pinned && targetElement && targetElement.pinned) {
// If the caller asks to move an unpinned element next to a pinned // If the caller asks to move an unpinned element next to a pinned
// tab, move the unpinned element to be the first unpinned element // tab, move the unpinned element to be the first unpinned element
@@ -6590,14 +6782,34 @@ @@ -6590,14 +6784,34 @@
// move the tab group right before the first unpinned tab. // move the tab group right before the first unpinned tab.
// 4. Moving a tab group and the first unpinned tab is grouped: // 4. Moving a tab group and the first unpinned tab is grouped:
// move the tab group right before the first unpinned tab's tab group. // move the tab group right before the first unpinned tab's tab group.
@@ -886,7 +895,7 @@ index 0eaca7a58e0026237b71b2ad515efe84d9e8c779..9c1fa86151f3d5896c45fef31a141757
element.pinned element.pinned
? this.tabContainer.pinnedTabsContainer ? this.tabContainer.pinnedTabsContainer
: this.tabContainer; : this.tabContainer;
@@ -6606,7 +6818,7 @@ @@ -6606,7 +6820,7 @@
element, element,
() => { () => {
if (moveBefore) { if (moveBefore) {
@@ -895,7 +904,7 @@ index 0eaca7a58e0026237b71b2ad515efe84d9e8c779..9c1fa86151f3d5896c45fef31a141757
} else if (targetElement) { } else if (targetElement) {
targetElement.after(element); targetElement.after(element);
} else { } else {
@@ -6676,10 +6888,10 @@ @@ -6676,10 +6890,10 @@
* @param {TabMetricsContext} [metricsContext] * @param {TabMetricsContext} [metricsContext]
*/ */
moveTabToExistingGroup(aTab, aGroup, metricsContext) { moveTabToExistingGroup(aTab, aGroup, metricsContext) {
@@ -908,7 +917,7 @@ index 0eaca7a58e0026237b71b2ad515efe84d9e8c779..9c1fa86151f3d5896c45fef31a141757
return; return;
} }
if (aTab.group && aTab.group.id === aGroup.id) { if (aTab.group && aTab.group.id === aGroup.id) {
@@ -6751,6 +6963,7 @@ @@ -6751,6 +6965,7 @@
let state = { let state = {
tabIndex: tab._tPos, tabIndex: tab._tPos,
@@ -916,7 +925,7 @@ index 0eaca7a58e0026237b71b2ad515efe84d9e8c779..9c1fa86151f3d5896c45fef31a141757
}; };
if (tab.visible) { if (tab.visible) {
state.elementIndex = tab.elementIndex; state.elementIndex = tab.elementIndex;
@@ -6777,7 +6990,7 @@ @@ -6777,7 +6992,7 @@
let changedTabGroup = let changedTabGroup =
previousTabState.tabGroupId != currentTabState.tabGroupId; previousTabState.tabGroupId != currentTabState.tabGroupId;
@@ -925,7 +934,7 @@ index 0eaca7a58e0026237b71b2ad515efe84d9e8c779..9c1fa86151f3d5896c45fef31a141757
tab.dispatchEvent( tab.dispatchEvent(
new CustomEvent("TabMove", { new CustomEvent("TabMove", {
bubbles: true, bubbles: true,
@@ -6818,6 +7031,10 @@ @@ -6818,6 +7033,10 @@
moveActionCallback(); moveActionCallback();
@@ -936,11 +945,11 @@ index 0eaca7a58e0026237b71b2ad515efe84d9e8c779..9c1fa86151f3d5896c45fef31a141757
// Clear tabs cache after moving nodes because the order of tabs may have // Clear tabs cache after moving nodes because the order of tabs may have
// changed. // changed.
this.tabContainer._invalidateCachedTabs(); this.tabContainer._invalidateCachedTabs();
@@ -6869,6 +7086,19 @@ @@ -6869,6 +7088,18 @@
* The new tab in the current window, null if the tab couldn't be adopted. * The new tab in the current window, null if the tab couldn't be adopted.
*/ */
adoptTab(aTab, { elementIndex, tabIndex, selectTab = false } = {}) { adoptTab(aTab, { elementIndex, tabIndex, selectTab = false } = {}) {
+ if (window.gZenWorkspaces.currentWindowIsSyncing === aTab.ownerGlobal.gZenWorkspaces.currentWindowIsSyncing) { + if (window.gZenWorkspaces.currentWindowIsSyncing && aTab.ownerGlobal.gZenWorkspaces?.currentWindowIsSyncing) {
+ const tabId = aTab.id; + const tabId = aTab.id;
+ const thisTab = window.gZenWindowSync.getItemFromWindow(window, tabId); + const thisTab = window.gZenWindowSync.getItemFromWindow(window, tabId);
+ if (thisTab) { + if (thisTab) {
@@ -951,12 +960,11 @@ index 0eaca7a58e0026237b71b2ad515efe84d9e8c779..9c1fa86151f3d5896c45fef31a141757
+ } + }
+ return thisTab; + return thisTab;
+ } + }
+ return;
+ } + }
// Swap the dropped tab with a new one we create and then close // Swap the dropped tab with a new one we create and then close
// it in the other window (making it seem to have moved between // it in the other window (making it seem to have moved between
// windows). We also ensure that the tab we create to swap into has // windows). We also ensure that the tab we create to swap into has
@@ -6910,6 +7140,8 @@ @@ -6910,6 +7141,8 @@
params.userContextId = aTab.getAttribute("usercontextid"); params.userContextId = aTab.getAttribute("usercontextid");
} }
let newTab = this.addWebTab("about:blank", params); let newTab = this.addWebTab("about:blank", params);
@@ -965,7 +973,7 @@ index 0eaca7a58e0026237b71b2ad515efe84d9e8c779..9c1fa86151f3d5896c45fef31a141757
let newBrowser = this.getBrowserForTab(newTab); let newBrowser = this.getBrowserForTab(newTab);
aTab.container.tabDragAndDrop.finishAnimateTabMove(); aTab.container.tabDragAndDrop.finishAnimateTabMove();
@@ -7718,7 +7950,7 @@ @@ -7718,7 +7951,7 @@
// preventDefault(). It will still raise the window if appropriate. // preventDefault(). It will still raise the window if appropriate.
break; break;
} }
@@ -974,7 +982,7 @@ index 0eaca7a58e0026237b71b2ad515efe84d9e8c779..9c1fa86151f3d5896c45fef31a141757
window.focus(); window.focus();
aEvent.preventDefault(); aEvent.preventDefault();
break; break;
@@ -7735,7 +7967,6 @@ @@ -7735,7 +7968,6 @@
} }
case "TabGroupCollapse": case "TabGroupCollapse":
aEvent.target.tabs.forEach(tab => { aEvent.target.tabs.forEach(tab => {
@@ -982,7 +990,7 @@ index 0eaca7a58e0026237b71b2ad515efe84d9e8c779..9c1fa86151f3d5896c45fef31a141757
}); });
break; break;
case "TabGroupCreateByUser": case "TabGroupCreateByUser":
@@ -7895,7 +8126,9 @@ @@ -7895,7 +8127,9 @@
let filter = this._tabFilters.get(tab); let filter = this._tabFilters.get(tab);
if (filter) { if (filter) {
@@ -992,7 +1000,7 @@ index 0eaca7a58e0026237b71b2ad515efe84d9e8c779..9c1fa86151f3d5896c45fef31a141757
let listener = this._tabListeners.get(tab); let listener = this._tabListeners.get(tab);
if (listener) { if (listener) {
@@ -8698,6 +8931,7 @@ @@ -8698,6 +8932,7 @@
aWebProgress.isTopLevel aWebProgress.isTopLevel
) { ) {
this.mTab.setAttribute("busy", "true"); this.mTab.setAttribute("busy", "true");
@@ -1000,7 +1008,7 @@ index 0eaca7a58e0026237b71b2ad515efe84d9e8c779..9c1fa86151f3d5896c45fef31a141757
gBrowser._tabAttrModified(this.mTab, ["busy"]); gBrowser._tabAttrModified(this.mTab, ["busy"]);
this.mTab._notselectedsinceload = !this.mTab.selected; this.mTab._notselectedsinceload = !this.mTab.selected;
} }
@@ -8778,6 +9012,7 @@ @@ -8778,6 +9013,7 @@
// known defaults. Note we use the original URL since about:newtab // known defaults. Note we use the original URL since about:newtab
// redirects to a prerendered page. // redirects to a prerendered page.
const shouldRemoveFavicon = const shouldRemoveFavicon =
@@ -1008,7 +1016,7 @@ index 0eaca7a58e0026237b71b2ad515efe84d9e8c779..9c1fa86151f3d5896c45fef31a141757
!this.mBrowser.mIconURL && !this.mBrowser.mIconURL &&
!ignoreBlank && !ignoreBlank &&
!(originalLocation.spec in FAVICON_DEFAULTS); !(originalLocation.spec in FAVICON_DEFAULTS);
@@ -9803,7 +10038,7 @@ var TabContextMenu = { @@ -9803,7 +10039,7 @@ var TabContextMenu = {
); );
contextUnpinSelectedTabs.hidden = contextUnpinSelectedTabs.hidden =
!this.contextTab.pinned || !this.multiselected; !this.contextTab.pinned || !this.multiselected;

View File

@@ -98,6 +98,12 @@ export class nsZenMenuBar {
</menu>`); </menu>`);
document.getElementById("view-menu").after(spacesMenubar); document.getElementById("view-menu").after(spacesMenubar);
document.getElementById("zen-spaces-menubar").addEventListener("popupshowing", () => { document.getElementById("zen-spaces-menubar").addEventListener("popupshowing", () => {
if (AppConstants.platform === "linux") {
// On linux, there seems to be a bug where the menu freezes up and makes the browser
// suppiciously unresponsive if we try to update the menu while it's opening.
// See https://github.com/zen-browser/desktop/issues/12024
return;
}
gZenWorkspaces.updateWorkspacesChangeContextMenu(); gZenWorkspaces.updateWorkspacesChangeContextMenu();
}); });
} }
@@ -124,6 +130,9 @@ export class nsZenMenuBar {
} }
#hideWindowRestoreMenus() { #hideWindowRestoreMenus() {
if (!Services.prefs.getBoolPref("zen.window-sync.enabled", true)) {
return;
}
const itemsToHide = ["appMenuRecentlyClosedWindows", "historyUndoWindowMenu"]; const itemsToHide = ["appMenuRecentlyClosedWindows", "historyUndoWindowMenu"];
for (const id of itemsToHide) { for (const id of itemsToHide) {
const element = PanelMultiView.getViewNode(document, id); const element = PanelMultiView.getViewNode(document, id);

View File

@@ -87,7 +87,6 @@ class ZenStartup {
await delayedStartupPromise; await delayedStartupPromise;
await SessionStore.promiseAllWindowsRestored; await SessionStore.promiseAllWindowsRestored;
delete gZenUIManager.promiseInitialized; delete gZenUIManager.promiseInitialized;
this.#initSearchBar();
gZenCompactModeManager.init(); gZenCompactModeManager.init();
// Fix for https://github.com/zen-browser/desktop/issues/7605, specially in compact mode // Fix for https://github.com/zen-browser/desktop/issues/7605, specially in compact mode
if (gURLBar.hasAttribute("breakout-extend")) { if (gURLBar.hasAttribute("breakout-extend")) {
@@ -154,11 +153,6 @@ class ZenStartup {
} }
} }
#initSearchBar() {
// Only focus the url bar
gURLBar.focus();
}
#checkForWelcomePage() { #checkForWelcomePage() {
if (!Services.prefs.getBoolPref("zen.welcome-screen.seen", false)) { if (!Services.prefs.getBoolPref("zen.welcome-screen.seen", false)) {
Services.prefs.setBoolPref("zen.welcome-screen.seen", true); Services.prefs.setBoolPref("zen.welcome-screen.seen", true);

View File

@@ -891,8 +891,8 @@ window.gZenVerticalTabsManager = {
marginBottom: isLastItem() ? ["0px", "0px"] : [transform, "0px"], marginBottom: isLastItem() ? ["0px", "0px"] : [transform, "0px"],
}, },
{ {
duration: 0.11, duration: 0.075,
easing: "ease-out", easing: "easeOut",
} }
) )
.then(() => {}) .then(() => {})
@@ -913,8 +913,8 @@ window.gZenVerticalTabsManager = {
filter: ["blur(1px)", "blur(0px)"], filter: ["blur(1px)", "blur(0px)"],
}, },
{ {
duration: 0.11, duration: 0.075,
easing: "ease-out", easing: "easeOut",
} }
) )
.then(() => {}) .then(() => {})
@@ -949,7 +949,7 @@ window.gZenVerticalTabsManager = {
}, },
{ {
duration: 0.075, duration: 0.075,
easing: "ease-out", easing: "easeOut",
} }
); );
}, },
@@ -1362,7 +1362,7 @@ window.gZenVerticalTabsManager = {
// Check if name is blank, reset if so // Check if name is blank, reset if so
// Always remove, so we can always rename and if it's empty, // Always remove, so we can always rename and if it's empty,
// it will reset to the original name anyway // it will reset to the original name anyway
if (hasChanged) { if (hasChanged || (this._tabEdited.zenStaticLabel && newName)) {
this._tabEdited.zenStaticLabel = newName; this._tabEdited.zenStaticLabel = newName;
gBrowser._setTabLabel(this._tabEdited, newName); gBrowser._setTabLabel(this._tabEdited, newName);
gZenUIManager.showToast("zen-tabs-renamed"); gZenUIManager.showToast("zen-tabs-renamed");
@@ -1403,7 +1403,8 @@ window.gZenVerticalTabsManager = {
if ( if (
this._tabEdited || this._tabEdited ||
((!Services.prefs.getBoolPref("zen.tabs.rename-tabs") || ((!Services.prefs.getBoolPref("zen.tabs.rename-tabs") ||
Services.prefs.getBoolPref("browser.tabs.closeTabByDblclick")) && (Services.prefs.getBoolPref("browser.tabs.closeTabByDblclick") &&
event.type === "dblclick")) &&
isTab) || isTab) ||
!gZenVerticalTabsManager._prefsSidebarExpanded !gZenVerticalTabsManager._prefsSidebarExpanded
) { ) {

View File

@@ -61,6 +61,9 @@
.zen-pseudo-browser-image { .zen-pseudo-browser-image {
position: absolute; position: absolute;
transform: scale(1);
width: 100%;
height: 100%;
inset: 0; inset: 0;
opacity: 0.4; opacity: 0.4;
pointer-events: none; pointer-events: none;

View File

@@ -309,7 +309,7 @@
order: 2; order: 2;
} }
#notification-popup-box:not([open]) { #notification-popup-box:not([open]):not(:has(> [showing="true"])) {
margin-inline-start: calc(-10px - 2 * var(--urlbar-icon-padding)); margin-inline-start: calc(-10px - 2 * var(--urlbar-icon-padding));
opacity: 0; opacity: 0;
transition: all 0.2s; transition: all 0.2s;

View File

@@ -743,6 +743,10 @@ window.gZenCompactModeManager = {
return; return;
} }
if (this._isTabBeingDragged) {
return;
}
if (this.hoverableElements[i].keepHoverDuration) { if (this.hoverableElements[i].keepHoverDuration) {
this.flashElement( this.flashElement(
target, target,

View File

@@ -12,6 +12,7 @@
#zen-dragover-background { #zen-dragover-background {
width: calc(100% - var(--zen-toolbox-padding) * 2 - 5px); width: calc(100% - var(--zen-toolbox-padding) * 2 - 5px);
left: unset; left: unset;
transform: translateY(-4px);
} }
#zen-tabbox-wrapper { #zen-tabbox-wrapper {

View File

@@ -105,7 +105,7 @@
startTabDrag(event, tab, ...args) { startTabDrag(event, tab, ...args) {
this.ZenDragAndDropService.onDragStart(1); this.ZenDragAndDropService.onDragStart(1);
gZenCompactModeManager._isTabBeingDragged = true;
super.startTabDrag(event, tab, ...args); super.startTabDrag(event, tab, ...args);
const dt = event.dataTransfer; const dt = event.dataTransfer;
if (isTabGroupLabel(tab)) { if (isTabGroupLabel(tab)) {
@@ -117,9 +117,7 @@
this.originalDragImageArgs = [dragImage, offsetX, offsetY]; this.originalDragImageArgs = [dragImage, offsetX, offsetY];
dt.setDragImage(...this.originalDragImageArgs); dt.setDragImage(...this.originalDragImageArgs);
if (tab.hasAttribute("zen-essential")) { if (tab.hasAttribute("zen-essential")) {
setTimeout(() => {
tab.style.visibility = "hidden"; tab.style.visibility = "hidden";
}, 0);
} }
} }
@@ -627,6 +625,11 @@
gZenWorkspaces gZenWorkspaces
.changeWorkspaceShortcut(isNearLeftEdge ? -1 : 1, false, /* Disable wrapping */ true) .changeWorkspaceShortcut(isNearLeftEdge ? -1 : 1, false, /* Disable wrapping */ true)
.then((spaceChanged) => { .then((spaceChanged) => {
if (AppConstants.platform !== "macosx") {
// See the hack in #createDragImageForTabs for more details which
// explains why we need to do this on non-macOS platforms.
return;
}
let tabs = this.originalDragImageArgs[0].children; let tabs = this.originalDragImageArgs[0].children;
const { isDarkMode, isExplicitMode } = const { isDarkMode, isExplicitMode } =
gZenThemePicker.getGradientForWorkspace(spaceChanged); gZenThemePicker.getGradientForWorkspace(spaceChanged);
@@ -669,12 +672,20 @@
if (!isTab(draggedTab)) { if (!isTab(draggedTab)) {
return; return;
} }
const { clientX, clientY } = event; let { screenX, clientX, screenY, clientY } = event;
const { innerWidth, innerHeight } = window; if (!screenX && !screenY) {
return;
}
const { innerWidth: winWidth, innerHeight: winHeight } = window;
let allowedMargin = Services.prefs.getIntPref("zen.tabs.dnd-outside-window-margin", 5);
const isOutOfWindow = const isOutOfWindow =
clientX < 0 || clientX > innerWidth || clientY < 0 || clientY > innerHeight; clientX <= allowedMargin ||
clientX >= winWidth - allowedMargin ||
clientY <= allowedMargin ||
clientY >= winHeight - allowedMargin;
if (isOutOfWindow && !this.#isOutOfWindow) { if (isOutOfWindow && !this.#isOutOfWindow) {
this.#isOutOfWindow = true; this.#isOutOfWindow = true;
gZenViewSplitter.onBrowserDragEndToSplit(event, true);
this.#maybeClearVerticalPinnedGridDragOver(); this.#maybeClearVerticalPinnedGridDragOver();
this.clearSpaceSwitchTimer(); this.clearSpaceSwitchTimer();
this.clearDragOverVisuals(); this.clearDragOverVisuals();
@@ -698,7 +709,7 @@
this.originalDragImageArgs[1], this.originalDragImageArgs[1],
this.originalDragImageArgs[2] this.originalDragImageArgs[2]
); );
window.addEventListener("dragover", this.handle_windowDragEnter, { window.addEventListener("dragenter", this.handle_windowDragEnter, {
once: true, once: true,
capture: true, capture: true,
}); });
@@ -713,6 +724,7 @@
const dt = event.dataTransfer; const dt = event.dataTransfer;
const activeWorkspace = gZenWorkspaces.activeWorkspace; const activeWorkspace = gZenWorkspaces.activeWorkspace;
let draggedTab = dt.mozGetDataAt(TAB_DROP_TYPE, 0); let draggedTab = dt.mozGetDataAt(TAB_DROP_TYPE, 0);
if (draggedTab.ownerGlobal === window) {
if ( if (
isTab(draggedTab) && isTab(draggedTab) &&
!draggedTab.hasAttribute("zen-essential") && !draggedTab.hasAttribute("zen-essential") &&
@@ -728,6 +740,7 @@
draggedTab = draggedTab.group; draggedTab = draggedTab.group;
gZenFolders.changeFolderToSpace(draggedTab, activeWorkspace, { hasDndSwitch: true }); gZenFolders.changeFolderToSpace(draggedTab, activeWorkspace, { hasDndSwitch: true });
} }
}
gZenWorkspaces.updateTabsContainers(); gZenWorkspaces.updateTabsContainers();
} }
@@ -756,7 +769,8 @@
draggedTab.hasAttribute("zen-essential") || draggedTab.hasAttribute("zen-essential") ||
draggedTab.getAttribute("zen-workspace-id") != gZenWorkspaces.activeWorkspace || draggedTab.getAttribute("zen-workspace-id") != gZenWorkspaces.activeWorkspace ||
!dropElement.visible || !dropElement.visible ||
!draggedTab.visible !draggedTab.visible ||
draggedTab.ownerGlobal !== window
) { ) {
return; return;
} }
@@ -845,21 +859,22 @@
handle_dragend(event) { handle_dragend(event) {
const dt = event.dataTransfer; const dt = event.dataTransfer;
const draggedTab = dt.mozGetDataAt(TAB_DROP_TYPE, 0); const draggedTab = dt.mozGetDataAt(TAB_DROP_TYPE, 0);
let ownerGlobal = draggedTab?.ownerGlobal;
draggedTab.style.visibility = ""; draggedTab.style.visibility = "";
let currentEssenialContainer = gZenWorkspaces.getCurrentEssentialsContainer(); let currentEssenialContainer = ownerGlobal.gZenWorkspaces.getCurrentEssentialsContainer();
if (currentEssenialContainer?.essentialsPromo) { if (currentEssenialContainer?.essentialsPromo) {
currentEssenialContainer.essentialsPromo.remove(); currentEssenialContainer.essentialsPromo.remove();
} }
// We also call it here to ensure we clear any highlight if the drop happened // We also call it here to ensure we clear any highlight if the drop happened
// outside of a valid drop target. // outside of a valid drop target.
gZenFolders.highlightGroupOnDragOver(null); ownerGlobal.gZenFolders.highlightGroupOnDragOver(null);
this.ZenDragAndDropService.onDragEnd(); this.ZenDragAndDropService.onDragEnd();
super.handle_dragend(event); super.handle_dragend(event);
this.#removeDragOverBackground(); this.#removeDragOverBackground();
gZenPinnedTabManager.removeTabContainersDragoverClass(); ownerGlobal.gZenPinnedTabManager.removeTabContainersDragoverClass();
this.#maybeClearVerticalPinnedGridDragOver(); this.#maybeClearVerticalPinnedGridDragOver();
this.originalDragImageArgs = []; this.originalDragImageArgs = [];
window.removeEventListener("dragover", this.handle_windowDragEnter, { capture: true }); window.removeEventListener("dragenter", this.handle_windowDragEnter, { capture: true });
this.#isOutOfWindow = false; this.#isOutOfWindow = false;
if (this._browserDragImageWrapper) { if (this._browserDragImageWrapper) {
this._browserDragImageWrapper.remove(); this._browserDragImageWrapper.remove();
@@ -869,6 +884,10 @@
this._tempDragImageParent.remove(); this._tempDragImageParent.remove();
delete this._tempDragImageParent; delete this._tempDragImageParent;
} }
delete ownerGlobal.gZenCompactModeManager._isTabBeingDragged;
if (dt.dropEffect !== "move") {
ownerGlobal.gZenCompactModeManager._clearAllHoverStates();
}
} }
#applyDragOverBackground(element) { #applyDragOverBackground(element) {
@@ -921,7 +940,7 @@
if (event.target.classList.contains("zen-workspace-empty-space") || hoveringPeriphery) { if (event.target.classList.contains("zen-workspace-empty-space") || hoveringPeriphery) {
let lastTab = gBrowser.tabs.at(-1); let lastTab = gBrowser.tabs.at(-1);
dropElement = dropElement =
(hoveringPeriphery (hoveringPeriphery && Services.prefs.getBoolPref("zen.view.show-newtab-button-top")
? this._tabbrowserTabs.ariaFocusableItems.at( ? this._tabbrowserTabs.ariaFocusableItems.at(
gBrowser._numVisiblePinTabsWithoutCollapsed gBrowser._numVisiblePinTabsWithoutCollapsed
) )
@@ -970,11 +989,13 @@
if ( if (
isTabGroupLabel(draggedTab) && isTabGroupLabel(draggedTab) &&
draggedTab.group?.isZenFolder && draggedTab.group?.isZenFolder &&
(isTab(dropElement) || dropElement.hasAttribute("split-view-group")) && (((isTab(dropElement) || dropElement.hasAttribute("split-view-group")) &&
(!dropElement.pinned || dropElement.hasAttribute("zen-essential")) (!dropElement.pinned || dropElement.hasAttribute("zen-essential"))) ||
showIndicatorUnderNewTabButton)
) { ) {
dropElement = null;
this.clearDragOverVisuals(); this.clearDragOverVisuals();
return null; return [dropElement, dropBefore];
} }
if ( if (
isTab(dropElement) || isTab(dropElement) ||
@@ -989,7 +1010,7 @@
let top = 0; let top = 0;
threshold = threshold =
Services.prefs.getIntPref("browser.tabs.dragDrop.moveOverThresholdPercent") / 100; Services.prefs.getIntPref("browser.tabs.dragDrop.moveOverThresholdPercent") / 100;
if (overlapPercent > threshold) { if (overlapPercent > threshold || showIndicatorUnderNewTabButton) {
top = Math.round(rect.top + rect.height) + "px"; top = Math.round(rect.top + rect.height) + "px";
dropBefore = false; dropBefore = false;
} else { } else {
@@ -1268,6 +1289,9 @@
return; return;
} }
// eslint-disable-next-line mozilla/valid-services
Services.zen.playHapticFeedback();
dragData.animDropElementIndex = newIndex; dragData.animDropElementIndex = newIndex;
dragData.dropElement = tabs[Math.min(newIndex, tabs.length - 1)]; dragData.dropElement = tabs[Math.min(newIndex, tabs.length - 1)];
dragData.dropBefore = newIndex < tabs.length; dragData.dropBefore = newIndex < tabs.length;

View File

@@ -1038,6 +1038,7 @@ class nsZenFolders extends nsZenDOMOperatedFeature {
const tabFolderWorkingData = new Map(); const tabFolderWorkingData = new Map();
for (const folderData of data) { for (const folderData of data) {
try {
const workingData = { const workingData = {
stateData: folderData, stateData: folderData,
node: null, node: null,
@@ -1076,6 +1077,9 @@ class nsZenFolders extends nsZenDOMOperatedFeature {
oldGroup.remove(); oldGroup.remove();
} }
} }
} catch (e) {
console.error("Error restoring Zen Folders session data:", e);
}
} }
for (const { node, containingTabsFragment } of tabFolderWorkingData.values()) { for (const { node, containingTabsFragment } of tabFolderWorkingData.values()) {

View File

@@ -640,7 +640,6 @@ class nsZenGlanceManager extends nsZenDOMOperatedFeature {
left: [], left: [],
width: [], width: [],
height: [], height: [],
transform: [],
}; };
const steps = this.#ARC_CONFIG.ARC_STEPS; const steps = this.#ARC_CONFIG.ARC_STEPS;
@@ -674,7 +673,6 @@ class nsZenGlanceManager extends nsZenDOMOperatedFeature {
const y = const y =
startPosition.y + distanceY * eased + arcDirection * arcHeight * (1 - (2 * eased - 1) ** 2); startPosition.y + distanceY * eased + arcDirection * arcHeight * (1 - (2 * eased - 1) ** 2);
sequence.transform.push(`translate(-50%, -50%)`);
sequence.top.push(`${y}px`); sequence.top.push(`${y}px`);
sequence.left.push(`${x}px`); sequence.left.push(`${x}px`);
sequence.width.push(`${currentWidth}px`); sequence.width.push(`${currentWidth}px`);

View File

@@ -800,6 +800,10 @@ class nsZenKeyboardShortcutsLoader {
continue; continue;
} }
let parsed = KeyShortcut.parseFromXHTML(key, { group: "devTools" }); let parsed = KeyShortcut.parseFromXHTML(key, { group: "devTools" });
// Move "inspector" shortcut to use "L" key instead of "I"
if (parsed.getID() == "key_inspector" || parsed.getID() == "key_inspectorMac") {
parsed.setNewBinding("L");
}
newShortcutList.push(parsed); newShortcutList.push(parsed);
} }
@@ -1109,16 +1113,14 @@ class nsZenKeyboardShortcutsVersioner {
if (version < 15) { if (version < 15) {
// Migrate from version 13 to 14 // Migrate from version 13 to 14
// Add shortcut to open a new unsynced window: Default accelt+option+N (Ctrl+Alt+N on non-macOS) // Add shortcut to open a new unsynced window: Default accelt+shift+N
data.push( data.push(
new KeyShortcut( new KeyShortcut(
"zen-new-unsynced-window", "zen-new-unsynced-window",
"N", "N",
"", "",
ZEN_OTHER_SHORTCUTS_GROUP, ZEN_OTHER_SHORTCUTS_GROUP,
AppConstants.platform === "win" nsKeyShortcutModifiers.fromObject({ accel: true, shift: true }),
? nsKeyShortcutModifiers.fromObject({ alt: true })
: nsKeyShortcutModifiers.fromObject({ accel: true, alt: true }),
"cmd_zenNewNavigatorUnsynced", "cmd_zenNewNavigatorUnsynced",
"zen-new-unsynced-window-shortcut" "zen-new-unsynced-window-shortcut"
) )

View File

@@ -84,6 +84,7 @@ export class nsZenSessionManager {
compression: "lz4", compression: "lz4",
backupFile, backupFile,
}); });
this.log("Session file path:", this.#file.path);
this.#deferredBackupTask = new lazy.DeferredTask(async () => { this.#deferredBackupTask = new lazy.DeferredTask(async () => {
await this.#createBackupsIfNeeded(); await this.#createBackupsIfNeeded();
}, REGENERATION_DEBOUNCE_RATE_MS); }, REGENERATION_DEBOUNCE_RATE_MS);
@@ -150,6 +151,34 @@ export class nsZenSessionManager {
folderIcon: row.getResultByName("folder_icon"), folderIcon: row.getResultByName("folder_icon"),
isFolderCollapsed: Boolean(row.getResultByName("is_folder_collapsed")), isFolderCollapsed: Boolean(row.getResultByName("is_folder_collapsed")),
})); }));
try {
data.recoveryData = await IOUtils.readJSON(
PathUtils.join(
Services.dirsvc.get("ProfD", Ci.nsIFile).path,
"sessionstore-backups",
"recovery.jsonlz4"
),
{ decompress: true }
);
this.log("Recovered recovery data from sessionstore-backups");
} catch {
/* ignore errors reading recovery data */
}
if (!data.recoverYData) {
try {
data.recoveryData = await IOUtils.readJSON(
PathUtils.join(
Services.dirsvc.get("ProfD", Ci.nsIFile).path,
"sessionstore-backups",
"recovery.jsonlz4"
),
{ decompress: true }
);
this.log("Recovered recovery data from sessionstore-backups");
} catch {
/* ignore errors reading recovery data */
}
}
this._migrationData = data; this._migrationData = data;
} catch { } catch {
/* ignore errors during migration */ /* ignore errors during migration */
@@ -165,6 +194,7 @@ export class nsZenSessionManager {
async readFile() { async readFile() {
let fileExists = await IOUtils.exists(this.#storeFilePath); let fileExists = await IOUtils.exists(this.#storeFilePath);
if (!fileExists) { if (!fileExists) {
this.log("Session file does not exist, running migration", this.#storeFilePath);
this._shouldRunMigration = true; this._shouldRunMigration = true;
} }
this.init(); this.init();
@@ -181,6 +211,7 @@ export class nsZenSessionManager {
} }
this.#sidebar = this.#file.data || {}; this.#sidebar = this.#file.data || {};
if (!this.#sidebar.spaces?.length && !this._shouldRunMigration) { if (!this.#sidebar.spaces?.length && !this._shouldRunMigration) {
this.log("No spaces data found in session file, running migration", this.#sidebar);
// If we have no spaces data, we should run migration // If we have no spaces data, we should run migration
// to restore them from the database. Note we also do a // to restore them from the database. Note we also do a
// check if we already planned to run migration for optimization. // check if we already planned to run migration for optimization.
@@ -189,6 +220,13 @@ export class nsZenSessionManager {
} }
} }
get #shouldRestoreOnlyPinned() {
return (
Services.prefs.getIntPref("browser.startup.page", 1) !== BROWSER_STARTUP_RESUME_SESSION ||
lazy.PrivateBrowsingUtils.permanentPrivateBrowsing
);
}
/** /**
* Called when the session file is read. Restores the sidebar data * Called when the session file is read. Restores the sidebar data
* into all windows. * into all windows.
@@ -197,15 +235,22 @@ export class nsZenSessionManager {
* The initial session state read from the session file. * The initial session state read from the session file.
*/ */
onFileRead(initialState) { onFileRead(initialState) {
if (!lazy.gWindowSyncEnabled) {
return initialState;
}
// For the first time after migration, we restore the tabs // For the first time after migration, we restore the tabs
// That where going to be restored by SessionStore. The sidebar // That where going to be restored by SessionStore. The sidebar
// object will always be empty after migration because we haven't // object will always be empty after migration because we haven't
// gotten the opportunity to save the session yet. // gotten the opportunity to save the session yet.
if (this._shouldRunMigration) { if (this._shouldRunMigration) {
this.#runStateMigration(initialState); initialState = this.#runStateMigration(initialState);
}
if (!lazy.gWindowSyncEnabled) {
if (initialState?.windows?.length && this.#shouldRestoreOnlyPinned) {
this.log("Window sync disabled, restoring only pinned tabs");
for (let i = 0; i < initialState.windows.length; i++) {
let winData = initialState.windows[i];
winData.tabs = (winData.tabs || []).filter((tab) => tab.pinned);
}
}
return initialState;
} }
// If there are no windows, we create an empty one. By default, // If there are no windows, we create an empty one. By default,
// firefox would create simply a new empty window, but we want // firefox would create simply a new empty window, but we want
@@ -215,14 +260,15 @@ export class nsZenSessionManager {
if (!initialState?.windows?.length) { if (!initialState?.windows?.length) {
this.log("No windows found in initial state, creating an empty one"); this.log("No windows found in initial state, creating an empty one");
initialState ||= {}; initialState ||= {};
initialState.windows = this._shouldRunMigration ? [] : [{}]; initialState.windows = [
{
tabs: [],
},
];
} }
// When we don't have browser.startup.page set to resume session, // When we don't have browser.startup.page set to resume session,
// we only want to restore the pinned tabs into the new windows. // we only want to restore the pinned tabs into the new windows.
const shouldRestoreOnlyPinned = if (this.#shouldRestoreOnlyPinned && this.#sidebar?.tabs) {
Services.prefs.getIntPref("browser.startup.page", 1) !== BROWSER_STARTUP_RESUME_SESSION ||
lazy.PrivateBrowsingUtils.permanentPrivateBrowsing;
if (shouldRestoreOnlyPinned && this.#sidebar?.tabs) {
this.log("Restoring only pinned tabs into windows"); this.log("Restoring only pinned tabs into windows");
const sidebar = this.#sidebar; const sidebar = this.#sidebar;
sidebar.tabs = (sidebar.tabs || []).filter((tab) => tab.pinned); sidebar.tabs = (sidebar.tabs || []).filter((tab) => tab.pinned);
@@ -249,9 +295,9 @@ export class nsZenSessionManager {
} }
this.#restoreWindowData(winData); this.#restoreWindowData(winData);
} }
} else { } else if (initialState) {
this.log("Saving windata state after migration"); this.log("Saving windata state after migration");
this.saveState(initialState); this.saveState(Cu.cloneInto(initialState, {}));
} }
delete this._shouldRunMigration; delete this._shouldRunMigration;
return initialState; return initialState;
@@ -272,8 +318,19 @@ export class nsZenSessionManager {
* @param {object} initialState * @param {object} initialState
* The initial session state read from the session file. * The initial session state read from the session file.
*/ */
// eslint-disable-next-line complexity
#runStateMigration(initialState) { #runStateMigration(initialState) {
this.log("Restoring tabs from Places DB after migration", initialState, this._migrationData); this.log(
"Restoring tabs from Places DB after migration",
initialState,
initialState?.lastSessionState,
this._migrationData
);
if (!initialState?.windows?.length && this._migrationData?.recoveryData) {
this.log("Using recovery data for migration");
initialState = this._migrationData.recoveryData;
}
delete this._migrationData?.recoveryData;
// Restore spaces into the sidebar object if we don't // Restore spaces into the sidebar object if we don't
// have any yet. // have any yet.
if (!this.#sidebar.spaces?.length) { if (!this.#sidebar.spaces?.length) {
@@ -282,6 +339,12 @@ export class nsZenSessionManager {
spaces: this._migrationData?.spaces || [], spaces: this._migrationData?.spaces || [],
}; };
} }
if (
!initialState?.windows?.length &&
(initialState?.lastSessionState || initialState?.deferredInitialState)
) {
initialState = { ...(initialState.lastSessionState || initialState.deferredInitialState) };
}
// There might be cases where there are no windows in the // There might be cases where there are no windows in the
// initial state, for example if the user had 'restore previous // initial state, for example if the user had 'restore previous
// session' disabled before migration. In that case, we try // session' disabled before migration. In that case, we try
@@ -295,6 +358,14 @@ export class nsZenSessionManager {
this.log("Restoring tabs from last closed normal window"); this.log("Restoring tabs from last closed normal window");
} }
} }
if (!initialState?.windows?.length) {
initialState ||= {};
initialState.windows = [
{
tabs: [],
},
];
}
for (const winData of initialState?.windows || []) { for (const winData of initialState?.windows || []) {
winData.spaces = this._migrationData?.spaces || []; winData.spaces = this._migrationData?.spaces || [];
if (winData.tabs) { if (winData.tabs) {
@@ -309,9 +380,7 @@ export class nsZenSessionManager {
} }
} }
} }
// Save the state to the sidebar object so that it gets written return initialState;
// to the session file.
delete this._migrationData;
} }
/** /**
@@ -332,7 +401,7 @@ export class nsZenSessionManager {
saveState(state) { saveState(state) {
let windows = state?.windows || []; let windows = state?.windows || [];
windows = windows.filter((win) => this.#isWindowSaveable(win)); windows = windows.filter((win) => this.#isWindowSaveable(win));
if (!windows.length || !lazy.gWindowSyncEnabled) { if (!windows.length) {
// Don't save (or even collect) anything in permanent private // Don't save (or even collect) anything in permanent private
// browsing mode. We also don't want to save if there are no windows. // browsing mode. We also don't want to save if there are no windows.
return; return;
@@ -512,7 +581,7 @@ export class nsZenSessionManager {
* Whether this new window is being restored from a closed window. * Whether this new window is being restored from a closed window.
*/ */
restoreNewWindow(aWindow, SessionStoreInternal, fromClosedWindow = false) { restoreNewWindow(aWindow, SessionStoreInternal, fromClosedWindow = false) {
if (aWindow.gZenWorkspaces?.privateWindowOrDisabled || !lazy.gWindowSyncEnabled) { if (aWindow.gZenWorkspaces?.privateWindowOrDisabled) {
return; return;
} }
this.log("Restoring new window with Zen session data"); this.log("Restoring new window with Zen session data");
@@ -530,6 +599,10 @@ export class nsZenSessionManager {
this.#restoreWindowData(newWindow); this.#restoreWindowData(newWindow);
} }
newWindow.tabs = this.#filterUnusedTabs(newWindow.tabs || []); newWindow.tabs = this.#filterUnusedTabs(newWindow.tabs || []);
if (!lazy.gWindowSyncEnabled) {
// Don't bring over any unpinned tabs if window sync is disabled.
newWindow.tabs = newWindow.tabs.filter((tab) => tab.pinned);
}
// These are window-specific from the previous window state that // These are window-specific from the previous window state that
// we don't want to restore into the new window. Otherwise, new // we don't want to restore into the new window. Otherwise, new

View File

@@ -10,18 +10,18 @@ const lazy = {};
ChromeUtils.defineESModuleGetters(lazy, { ChromeUtils.defineESModuleGetters(lazy, {
BrowserWindowTracker: "resource:///modules/BrowserWindowTracker.sys.mjs", BrowserWindowTracker: "resource:///modules/BrowserWindowTracker.sys.mjs",
SessionStore: "resource:///modules/sessionstore/SessionStore.sys.mjs",
TabStateFlusher: "resource:///modules/sessionstore/TabStateFlusher.sys.mjs", TabStateFlusher: "resource:///modules/sessionstore/TabStateFlusher.sys.mjs",
// eslint-disable-next-line mozilla/valid-lazy // eslint-disable-next-line mozilla/valid-lazy
ZenSessionStore: "resource:///modules/zen/ZenSessionManager.sys.mjs", ZenSessionStore: "resource:///modules/zen/ZenSessionManager.sys.mjs",
TabStateCache: "resource:///modules/sessionstore/TabStateCache.sys.mjs", TabStateCache: "resource:///modules/sessionstore/TabStateCache.sys.mjs",
setTimeout: "resource://gre/modules/Timer.sys.mjs", setTimeout: "resource://gre/modules/Timer.sys.mjs",
PrivateBrowsingUtils: "resource://gre/modules/PrivateBrowsingUtils.sys.mjs",
}); });
XPCOMUtils.defineLazyPreferenceGetter(lazy, "gWindowSyncEnabled", "zen.window-sync.enabled"); XPCOMUtils.defineLazyPreferenceGetter(lazy, "gWindowSyncEnabled", "zen.window-sync.enabled", true);
XPCOMUtils.defineLazyPreferenceGetter(lazy, "gShouldLog", "zen.window-sync.log", true); XPCOMUtils.defineLazyPreferenceGetter(lazy, "gShouldLog", "zen.window-sync.log", true);
const OBSERVING = ["browser-window-before-show"]; const OBSERVING = ["browser-window-before-show", "sessionstore-windows-restored"];
const INSTANT_EVENTS = ["SSWindowClosing"]; const INSTANT_EVENTS = ["SSWindowClosing"];
const UNSYNCED_WINDOW_EVENTS = ["TabOpen"]; const UNSYNCED_WINDOW_EVENTS = ["TabOpen"];
const EVENTS = [ const EVENTS = [
@@ -141,16 +141,13 @@ class nsZenWindowSync {
} }
init() { init() {
if (!lazy.gWindowSyncEnabled || this.#initialized) { if (this.#initialized) {
return; return;
} }
this.#initialized = true; this.#initialized = true;
for (let topic of OBSERVING) { for (let topic of OBSERVING) {
Services.obs.addObserver(this, topic); Services.obs.addObserver(this, topic);
} }
lazy.SessionStore.promiseAllWindowsRestored.then(() => {
this.#onSessionStoreInitialized();
});
} }
uninit() { uninit() {
@@ -193,6 +190,10 @@ class nsZenWindowSync {
// to avoid confusing the old private window behavior. // to avoid confusing the old private window behavior.
let forcedSync = !aWindow.gZenWorkspaces?.privateWindowOrDisabled; let forcedSync = !aWindow.gZenWorkspaces?.privateWindowOrDisabled;
let hasUnsyncedArg = false; let hasUnsyncedArg = false;
// See issue https://github.com/zen-browser/desktop/issues/12211
if (lazy.PrivateBrowsingUtils.isWindowPrivate(aWindow)) {
aWindow._zenStartupSyncFlag = "synced";
}
if (aWindow._zenStartupSyncFlag === "synced") { if (aWindow._zenStartupSyncFlag === "synced") {
forcedSync = true; forcedSync = true;
} else if (aWindow._zenStartupSyncFlag === "unsynced") { } else if (aWindow._zenStartupSyncFlag === "unsynced") {
@@ -240,6 +241,9 @@ class nsZenWindowSync {
if (tab.pinned && !tab._zenPinnedInitialState) { if (tab.pinned && !tab._zenPinnedInitialState) {
await this.setPinnedTabState(tab); await this.setPinnedTabState(tab);
} }
if (!lazy.gWindowSyncEnabled) {
tab._zenContentsVisible = true;
}
} }
}); });
} }
@@ -297,6 +301,10 @@ class nsZenWindowSync {
this.#onWindowBeforeShow(aSubject); this.#onWindowBeforeShow(aSubject);
break; break;
} }
case "sessionstore-windows-restored": {
this.#onSessionStoreInitialized();
break;
}
} }
} }
@@ -309,6 +317,9 @@ class nsZenWindowSync {
) { ) {
return; return;
} }
if (!lazy.gWindowSyncEnabled && !UNSYNCED_WINDOW_EVENTS.includes(aEvent.type)) {
return;
}
if (INSTANT_EVENTS.includes(aEvent.type)) { if (INSTANT_EVENTS.includes(aEvent.type)) {
this.#handleNextEvent(aEvent); this.#handleNextEvent(aEvent);
return; return;
@@ -514,7 +525,11 @@ class nsZenWindowSync {
*/ */
#moveItemToMatchOriginal(aOriginalItem, aTargetItem, aWindow, { isEssential, isPinned }) { #moveItemToMatchOriginal(aOriginalItem, aTargetItem, aWindow, { isEssential, isPinned }) {
const { gBrowser, gZenWorkspaces } = aWindow; const { gBrowser, gZenWorkspaces } = aWindow;
const originalSibling = aOriginalItem.previousElementSibling; let originalSibling = aOriginalItem.previousElementSibling;
if (originalSibling?.classList.contains("space-fake-collapsible-start")) {
// Skip space fake elements.
originalSibling = originalSibling.previousElementSibling;
}
let isFirstTab = true; let isFirstTab = true;
if (gBrowser.isTabGroup(originalSibling) || gBrowser.isTab(originalSibling)) { if (gBrowser.isTabGroup(originalSibling) || gBrowser.isTab(originalSibling)) {
isFirstTab = isFirstTab =
@@ -1084,7 +1099,7 @@ class nsZenWindowSync {
} }
tab._zenContentsVisible = true; tab._zenContentsVisible = true;
tab.id = this.#newTabSyncId; tab.id = this.#newTabSyncId;
if (isUnsyncedWindow) { if (isUnsyncedWindow || !lazy.gWindowSyncEnabled) {
return; return;
} }
this.#runOnAllWindows(window, (win) => { this.#runOnAllWindows(window, (win) => {
@@ -1168,6 +1183,9 @@ class nsZenWindowSync {
} }
on_focus(aEvent) { on_focus(aEvent) {
if (typeof aEvent.target !== "object") {
return;
}
const { ownerGlobal: window } = aEvent.target; const { ownerGlobal: window } = aEvent.target;
if ( if (
!window?.gBrowser || !window?.gBrowser ||

View File

@@ -1386,10 +1386,10 @@ class nsZenViewSplitter extends nsZenDOMOperatedFeature {
new nsSplitLeafNode(tabs[i], 50), new nsSplitLeafNode(tabs[i], 50),
new nsSplitLeafNode(tabs[i + 1], 50), new nsSplitLeafNode(tabs[i + 1], 50),
]; ];
rootNode.addChild(columnNode); rootNode.addChild(columnNode, false);
} }
if (tabs.length % 2 !== 0) { if (tabs.length % 2 !== 0) {
rootNode.addChild(new nsSplitLeafNode(tabs[tabs.length - 1], rowWidth)); rootNode.addChild(new nsSplitLeafNode(tabs[tabs.length - 1], rowWidth), false);
} }
} }
@@ -2093,6 +2093,7 @@ class nsZenViewSplitter extends nsZenDOMOperatedFeature {
this._sessionRestoring = true; this._sessionRestoring = true;
for (const groupData of data) { for (const groupData of data) {
try {
const group = document.getElementById(groupData.groupId); const group = document.getElementById(groupData.groupId);
if (!gBrowser.isTabGroup(group)) { if (!gBrowser.isTabGroup(group)) {
continue; continue;
@@ -2131,7 +2132,14 @@ class nsZenViewSplitter extends nsZenDOMOperatedFeature {
const layout = deserializeNode(groupData.layoutTree); const layout = deserializeNode(groupData.layoutTree);
const splitData = this.splitTabs(group.tabs, groupData.gridType, -1); const splitData = this.splitTabs(group.tabs, groupData.gridType, -1);
if (splitData) {
splitData.layoutTree = layout; splitData.layoutTree = layout;
} else {
gBrowser.removeTabGroup(group);
}
} catch (e) {
console.error("Error restoring split view session data:", e);
}
} }
delete this._sessionRestoring; delete this._sessionRestoring;

View File

@@ -76,6 +76,17 @@ class nsZenPinnedTabManager extends nsZenDOMOperatedFeature {
this._zenClickEventListener = this._onTabClick.bind(this); this._zenClickEventListener = this._onTabClick.bind(this);
gZenWorkspaces._resolvePinnedInitialized(); gZenWorkspaces._resolvePinnedInitialized();
if (lazy.zenPinnedTabRestorePinnedTabsToPinnedUrl) {
gZenWorkspaces.promiseInitialized.then(() => {
for (const tab of gZenWorkspaces.allStoredTabs) {
try {
this.resetPinnedTab(tab);
} catch (ex) {
console.error("Error restoring pinned tab:", ex);
}
}
});
}
} }
log(message) { log(message) {
@@ -130,6 +141,7 @@ class nsZenPinnedTabManager extends nsZenDOMOperatedFeature {
tab.removeEventListener("click", tab._zenClickEventListener); tab.removeEventListener("click", tab._zenClickEventListener);
delete tab._zenClickEventListener; delete tab._zenClickEventListener;
} }
this.resetPinChangedUrl(tab);
break; break;
default: default:
console.warn("ZenPinnedTabManager: Unhandled tab event", action); console.warn("ZenPinnedTabManager: Unhandled tab event", action);
@@ -162,7 +174,7 @@ class nsZenPinnedTabManager extends nsZenDOMOperatedFeature {
this._resetTabToStoredState(tab); this._resetTabToStoredState(tab);
} }
async replacePinnedUrlWithCurrent(tab = undefined) { replacePinnedUrlWithCurrent(tab = undefined) {
tab ??= TabContextMenu.contextTab; tab ??= TabContextMenu.contextTab;
if (!tab || !tab.pinned) { if (!tab || !tab.pinned) {
return; return;
@@ -547,13 +559,50 @@ class nsZenPinnedTabManager extends nsZenDOMOperatedFeature {
} }
// eslint-disable-next-line complexity // eslint-disable-next-line complexity
moveToAnotherTabContainerIfNecessary(event, movingTabs) { moveToAnotherTabContainerIfNecessary(event, draggedTab, movingTabs, dropIndex) {
if (!this.enabled) { if (!this.enabled) {
return false; return false;
} }
movingTabs = movingTabs.map((tab) => { let newIndex = dropIndex;
return tab.ownerGlobal !== window ? gBrowser.adoptTab(tab) : tab; let fromDifferentWindow = false;
movingTabs = Array.from(movingTabs)
.reverse()
.map((tab) => {
let workspaceId;
if (tab.ownerGlobal !== window) {
fromDifferentWindow = true;
if (
!tab.hasAttribute("zen-essential") &&
tab.getAttribute("zen-workspace-id") != gZenWorkspaces.activeWorkspace
) {
workspaceId = gZenWorkspaces.activeWorkspace;
tab.ownerGlobal.gBrowser.selectedTab = tab.ownerGlobal.gBrowser._findTabToBlurTo(
tab,
movingTabs
);
tab.ownerGlobal.gZenWorkspaces.moveTabToWorkspace(tab, workspaceId);
}
// Move the tabs into this window. To avoid multiple tab-switches in
// the original window, the selected tab should be adopted last.
tab = gBrowser.adoptTab(tab, {
elementIndex: newIndex,
selectTab: tab == draggedTab,
}); });
if (tab) {
++newIndex;
}
if (workspaceId) {
tab.setAttribute("zen-workspace-id", workspaceId);
}
}
return tab;
});
if (fromDifferentWindow) {
gBrowser.addRangeToMultiSelectedTabs(
gBrowser.tabContainer.dragAndDropElements[dropIndex],
gBrowser.tabContainer.dragAndDropElements[newIndex - 1]
);
}
try { try {
const pinnedTabsTarget = event.target.closest( const pinnedTabsTarget = event.target.closest(
":is(.zen-current-workspace-indicator, .zen-workspace-pinned-tabs-section)" ":is(.zen-current-workspace-indicator, .zen-workspace-pinned-tabs-section)"
@@ -565,13 +614,19 @@ class nsZenPinnedTabManager extends nsZenDOMOperatedFeature {
currentEssenialContainer.essentialsPromo.remove(); currentEssenialContainer.essentialsPromo.remove();
} }
movingTabs = movingTabs.filter((tab) =>
gBrowser.isTabGroupLabel(tab) && tab.group?.isZenFolder
? !tabsTarget && !essentialTabsTarget
: true
);
// TODO: Solve the issue of adding a tab between two groups // TODO: Solve the issue of adding a tab between two groups
// Remove group labels from the moving tabs and replace it // Remove group labels from the moving tabs and replace it
// with the sub tabs // with the sub tabs
for (let i = 0; i < movingTabs.length; i++) { for (let i = 0; i < movingTabs.length; i++) {
const draggedTab = movingTabs[i]; const tab = movingTabs[i];
if (gBrowser.isTabGroupLabel(draggedTab)) { if (gBrowser.isTabGroupLabel(tab)) {
const group = draggedTab.group; const group = tab.group;
// remove label and add sub tabs to moving tabs // remove label and add sub tabs to moving tabs
if (group) { if (group) {
movingTabs.splice(i, 1, ...group.tabs); movingTabs.splice(i, 1, ...group.tabs);
@@ -582,32 +637,32 @@ class nsZenPinnedTabManager extends nsZenDOMOperatedFeature {
let isVertical = this.expandedSidebarMode; let isVertical = this.expandedSidebarMode;
let moved = false; let moved = false;
let hasActuallyMoved; let hasActuallyMoved;
for (const draggedTab of movingTabs) { for (const tab of movingTabs) {
let isRegularTabs = false; let isRegularTabs = false;
// Check for essentials container // Check for essentials container
if (essentialTabsTarget) { if (essentialTabsTarget) {
if (!draggedTab.hasAttribute("zen-essential") && !draggedTab?.group) { if (!tab.hasAttribute("zen-essential") && !tab?.group?.hasAttribute("split-view-group")) {
moved = true; moved = true;
isVertical = false; isVertical = false;
hasActuallyMoved = this.addToEssentials(draggedTab); hasActuallyMoved = this.addToEssentials(tab);
} }
} }
// Check for pinned tabs container // Check for pinned tabs container
else if (pinnedTabsTarget) { else if (pinnedTabsTarget) {
if (!draggedTab.pinned) { if (!tab.pinned) {
gBrowser.pinTab(draggedTab); gBrowser.pinTab(tab);
} else if (draggedTab.hasAttribute("zen-essential")) { } else if (tab.hasAttribute("zen-essential")) {
this.removeEssentials(draggedTab, false); this.removeEssentials(tab, false);
moved = true; moved = true;
} }
} }
// Check for normal tabs container // Check for normal tabs container
else if (tabsTarget || event.target.id === "zen-tabs-wrapper") { else if (tabsTarget || event.target.id === "zen-tabs-wrapper") {
if (draggedTab.pinned && !draggedTab.hasAttribute("zen-essential")) { if (tab.pinned && !tab.hasAttribute("zen-essential")) {
gBrowser.unpinTab(draggedTab); gBrowser.unpinTab(tab);
isRegularTabs = true; isRegularTabs = true;
} else if (draggedTab.hasAttribute("zen-essential")) { } else if (tab.hasAttribute("zen-essential")) {
this.removeEssentials(draggedTab); this.removeEssentials(tab);
moved = true; moved = true;
isRegularTabs = true; isRegularTabs = true;
} }
@@ -648,7 +703,7 @@ class nsZenPinnedTabManager extends nsZenDOMOperatedFeature {
elementIndex++; elementIndex++;
} }
gBrowser.moveTabTo(draggedTab, { gBrowser.moveTabTo(tab, {
elementIndex, elementIndex,
forceUngrouped: targetElem?.group?.collapsed !== false, forceUngrouped: targetElem?.group?.collapsed !== false,
}); });

View File

@@ -22,7 +22,7 @@ zen-essentials-promo {
outline: 1px dashed currentColor; outline: 1px dashed currentColor;
} }
:root:not([zen-sidebar-expanded="true"]) & { :root:is(:not([zen-sidebar-expanded="true"]), [zen-unsynced-window="true"]) & {
display: none !important; display: none !important;
} }

View File

@@ -682,6 +682,13 @@ async function testFileAccessWindowsOnly() {
let tests = []; let tests = [];
let extDir = GetPerUserExtensionDir(); let extDir = GetPerUserExtensionDir();
// We used to unconditionally create this directory from Firefox, but that
// was dropped in bug 2001887. The value of this directory is questionable;
// the test was added in Firefox 56 (bug 1403744) to cover legacy add-ons,
// but legacy add-on support was discontinued in Firefox 57, and we stopped
// sideloading add-ons from this directory on all builds except ESR in
// Firefox 74 (bug 1602840).
await IOUtils.makeDirectory(extDir.path);
tests.push({ tests.push({
desc: "per-user extensions dir", desc: "per-user extensions dir",
ok: true, ok: true,

View File

@@ -22,6 +22,13 @@ add_setup(async function setup() {
const xdgConfigHome = Services.env.get("XDG_CONFIG_HOME"); const xdgConfigHome = Services.env.get("XDG_CONFIG_HOME");
Assert.greater(xdgConfigHome.length, 1, "XDG_CONFIG_HOME is defined"); Assert.greater(xdgConfigHome.length, 1, "XDG_CONFIG_HOME is defined");
// Verify the profile directory is inside XDG_CONFIG_HOME
const profileDir = Services.dirsvc.get("ProfD", Ci.nsIFile);
Assert.ok(
profileDir.path.startsWith(xdgConfigHome),
`Profile directory (${profileDir.path}) should be inside XDG_CONFIG_HOME (${xdgConfigHome})`
);
// If it is there, do actual testing // If it is there, do actual testing
sanityChecks(); sanityChecks();
}); });

View File

@@ -12,11 +12,14 @@ support-files = [
"browser_content_sandbox_utils.js", "browser_content_sandbox_utils.js",
"browser_content_sandbox_fs_tests.js", "browser_content_sandbox_fs_tests.js",
] ]
# .config needs to exists for the sandbox to properly add it test-directories = [
test-directories = ["/tmp/.xdg_default_test", "/tmp/.xdg_default_test/.config"] "/tmp/.xdg_default_test",
"/tmp/.xdg_default_test/.config/mozilla/firefox/xdg_default_profile",
]
environment = [ environment = [
"HOME=/tmp/.xdg_default_test", "HOME=/tmp/.xdg_default_test",
] ]
profile-path = "/tmp/.xdg_default_test/.config/mozilla/firefox/xdg_default_profile"
["browser_content_sandbox_fs_xdg_default.js"] ["browser_content_sandbox_fs_xdg_default.js"]
run-if = ["os == 'linux'"] run-if = ["os == 'linux'"]

View File

@@ -12,12 +12,17 @@ support-files = [
"browser_content_sandbox_utils.js", "browser_content_sandbox_utils.js",
"browser_content_sandbox_fs_tests.js", "browser_content_sandbox_fs_tests.js",
] ]
test-directories = ["/tmp/.xdg_mozLegacyHome_test/.config", "/tmp/.xdg_config_home_test"] test-directories = [
"/tmp/.xdg_mozLegacyHome_test/.config",
"/tmp/.xdg_config_home_test",
"/tmp/.xdg_mozLegacyHome_test/.mozilla/firefox/xdg_mozLegacyHome_profile",
]
environment = [ environment = [
"XDG_CONFIG_HOME=/tmp/.xdg_config_home_test", "XDG_CONFIG_HOME=/tmp/.xdg_config_home_test",
"HOME=/tmp/.xdg_mozLegacyHome_test", "HOME=/tmp/.xdg_mozLegacyHome_test",
"MOZ_LEGACY_HOME=1", "MOZ_LEGACY_HOME=1",
] ]
profile-path = "/tmp/.xdg_mozLegacyHome_test/.mozilla/firefox/xdg_mozLegacyHome_profile"
["browser_content_sandbox_fs_xdg_mozLegacyHome.js"] ["browser_content_sandbox_fs_xdg_mozLegacyHome.js"]
run-if = ["os == 'linux'"] run-if = ["os == 'linux'"]

View File

@@ -11,11 +11,15 @@ support-files = [
"browser_content_sandbox_utils.js", "browser_content_sandbox_utils.js",
"browser_content_sandbox_fs_tests.js", "browser_content_sandbox_fs_tests.js",
] ]
test-directories = "/tmp/.xdg_config_home_test" test-directories = [
"/tmp/.xdg_config_home_test",
"/tmp/.xdg_config_home_test/mozilla/firefox/xdg_config_home_profile",
]
environment = [ environment = [
"XDG_CONFIG_HOME=/tmp/.xdg_config_home_test", "XDG_CONFIG_HOME=/tmp/.xdg_config_home_test",
"MOZ_LEGACY_HOME=0", "MOZ_LEGACY_HOME=0",
] ]
profile-path = "/tmp/.xdg_config_home_test/mozilla/firefox/xdg_config_home_profile"
["browser_content_sandbox_fs_xdg_xdgConfigHome.js"] ["browser_content_sandbox_fs_xdg_xdgConfigHome.js"]
run-if = [ run-if = [

View File

@@ -1348,7 +1348,8 @@ export class nsZenThemePicker extends nsZenMultiWindowFeature {
} }
getToolbarColor(isDarkMode = false) { getToolbarColor(isDarkMode = false) {
return isDarkMode ? [255, 255, 255, 0.6] : [0, 0, 0, 0.6]; // Default toolbar const opacity = 0.8;
return isDarkMode ? [255, 255, 255, opacity] : [0, 0, 0, opacity]; // Default toolbar
} }
onWorkspaceChange(workspace, skipUpdate = false, theme = null) { onWorkspaceChange(workspace, skipUpdate = false, theme = null) {

View File

@@ -6,6 +6,12 @@
import { nsZenThemePicker } from "chrome://browser/content/zen-components/ZenGradientGenerator.mjs"; import { nsZenThemePicker } from "chrome://browser/content/zen-components/ZenGradientGenerator.mjs";
const lazy = {};
ChromeUtils.defineESModuleGetters(lazy, {
ZenSessionStore: "resource:///modules/zen/ZenSessionManager.sys.mjs",
});
/** /**
* Zen Spaces manager. This class is mainly responsible for the UI * Zen Spaces manager. This class is mainly responsible for the UI
* and user interactions but it also contains some logic to manage * and user interactions but it also contains some logic to manage
@@ -801,7 +807,7 @@ class nsZenWorkspaces {
chromeFlags & Ci.nsIWebBrowserChrome.CHROME_MENUBAR; chromeFlags & Ci.nsIWebBrowserChrome.CHROME_MENUBAR;
return this._shouldHaveWorkspaces; return this._shouldHaveWorkspaces;
} }
return this._shouldHaveWorkspaces; return this._shouldHaveWorkspaces && !document.documentElement.hasAttribute("taskbartab");
} }
get isPrivateWindow() { get isPrivateWindow() {
@@ -888,6 +894,13 @@ class nsZenWorkspaces {
return Promise.resolve(); return Promise.resolve();
} }
const spacesFromStore = aWinData.spaces || []; const spacesFromStore = aWinData.spaces || [];
if (
!this.privateWindowOrDisabled &&
spacesFromStore.length === 0 &&
lazy.ZenSessionStore._migrationData
) {
spacesFromStore.push(...lazy.ZenSessionStore._migrationData.spaces);
}
this._workspaceCache = spacesFromStore.length this._workspaceCache = spacesFromStore.length
? [...spacesFromStore] ? [...spacesFromStore]
: [this.#createWorkspaceData("Space", undefined)]; : [this.#createWorkspaceData("Space", undefined)];
@@ -1031,11 +1044,17 @@ class nsZenWorkspaces {
delete this._initialTab; delete this._initialTab;
} }
// Wait for the next event loop to ensure that the startup focus logic by
// firefox has finished doing it's thing.
setTimeout(() => {
setTimeout(() => {
if (gZenVerticalTabsManager._canReplaceNewTab && showed) { if (gZenVerticalTabsManager._canReplaceNewTab && showed) {
BrowserCommands.openTab(); BrowserCommands.openTab();
} else if (!showed) { } else if (!showed) {
gBrowser.selectedBrowser.focus(); gBrowser.selectedBrowser.focus();
} }
});
});
if ( if (
!gZenVerticalTabsManager._canReplaceNewTab && !gZenVerticalTabsManager._canReplaceNewTab &&

View File

@@ -155,8 +155,8 @@
/* Mark workspaces indicator */ /* Mark workspaces indicator */
.zen-current-workspace-indicator { .zen-current-workspace-indicator {
--indicator-gap: var(--toolbarbutton-inner-padding); --indicator-gap: calc(var(--toolbarbutton-inner-padding) - 1px);
padding: calc(3px + var(--tab-inline-padding) + var(--zen-toolbox-padding)); padding: calc(2px + var(--tab-inline-padding) + var(--zen-toolbox-padding));
font-weight: 500; font-weight: 500;
position: relative; position: relative;
max-height: var(--zen-workspace-indicator-height); max-height: var(--zen-workspace-indicator-height);
@@ -231,7 +231,7 @@
@media (-moz-platform: windows) { @media (-moz-platform: windows) {
& img { & img {
margin-bottom: -4px; margin-bottom: -2px;
} }
} }
} }

View File

@@ -5,8 +5,8 @@
"binaryName": "zen", "binaryName": "zen",
"version": { "version": {
"product": "firefox", "product": "firefox",
"version": "147.0.1", "version": "147.0.2",
"candidate": "147.0.1", "candidate": "147.0.2",
"candidateBuild": 1 "candidateBuild": 1
}, },
"buildOptions": { "buildOptions": {
@@ -20,7 +20,7 @@
"brandShortName": "Zen", "brandShortName": "Zen",
"brandFullName": "Zen Browser", "brandFullName": "Zen Browser",
"release": { "release": {
"displayVersion": "1.18b", "displayVersion": "1.18.4b",
"github": { "github": {
"repo": "zen-browser/desktop" "repo": "zen-browser/desktop"
}, },