Compare commits

..

63 Commits

Author SHA1 Message Date
mr. m
4869e25df3 Update scripts/update_external_patches.py
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Signed-off-by: mr. m <91018726+mr-cheffy@users.noreply.github.com>
2026-02-06 22:40:38 +01:00
mr. m
cc4b51529e chore: Automatically import patches from phabricator and librewolf, b=no-bug, c=workflows, scripts 2026-02-06 20:52:00 +01:00
mr. m
c9474cecc0 feat: Remove null-setting for split view data on restore, b=no-bug, c=no-component 2026-02-06 14:10:02 +01:00
mr. m
531be839c9 fix: Fixed frozen window when restore split data is null, b=closes #12260, c=no-component 2026-02-06 14:04:04 +01:00
mr. m
226486b973 fix: Fixed selecting tabs when pinned tabs are collapsed, b=no-bug, c=no-component 2026-02-06 12:45:24 +01:00
mr. m
5a137c95e5 fix: Fixed wrong highlight possition in compact mode, b=closes #12252, c=compact-mode 2026-02-05 23:23:17 +01:00
mr. m
e6154ceb99 feat: Make sure we properly restore split views when only pinned sync is enabled, b=no-bug, c=no-component 2026-02-05 23:01:49 +01:00
mr. m
1ea5d2fa6f feat: Import zen.window-sync.sync-only-pinned-tabs to the prefs list, b=no-bug, c=no-component 2026-02-05 11:18:02 +01:00
mr. m
97d5ebc21e feat: Add pref observer for zen.window-sync.sync-only-pinned-tabs setting, b=no-bug, c=no-component 2026-02-05 11:14:48 +01:00
mr. m
442ec2a5d1 chore: Bump version and format, b=no-bug, c=tests 2026-02-05 11:13:02 +01:00
mr. m
43ae672b44 feat: Revert migration step for syncing only pinned tabs, b=no-bug, c=common 2026-02-05 11:12:01 +01:00
mr. m
84a54c9dbb feat: Add option to only sync up pinned tabs, b=closes #12173, p=#12246, c=common, tabs 2026-02-05 11:05:37 +01:00
mr. m
6c53c3bf37 chore: Sync upstream Firefox to version 147.0.3, p=#12243
* chore: Sync upstream to `Firefox 147.0.3`

* Update candidate version to 147.0.3

Signed-off-by: mr. m <91018726+mr-cheffy@users.noreply.github.com>

* Update Twilight version to RC 147.0.3 in README

Signed-off-by: mr. m <91018726+mr-cheffy@users.noreply.github.com>

---------

Signed-off-by: mr. m <91018726+mr-cheffy@users.noreply.github.com>
2026-02-05 11:04:53 +01:00
mr. m
66686ab7f8 New Crowdin updates, p=#11954
* New translations zen-general.ftl (Lithuanian)

* New translations zen-general.ftl (Portuguese)

* New translations zen-preferences.ftl (Lithuanian)

* New translations zen-preferences.ftl (Swedish)

* New translations zen-preferences.ftl (Chinese Traditional)

* New translations zen-preferences.ftl (Welsh)

* New translations zen-menubar.ftl (French)

* New translations zen-menubar.ftl (Catalan)

* New translations zen-menubar.ftl (Hebrew)

* New translations zen-menubar.ftl (Hungarian)

* New translations zen-menubar.ftl (Korean)

* New translations zen-menubar.ftl (Lithuanian)

* New translations zen-menubar.ftl (Portuguese)

* New translations zen-menubar.ftl (Swedish)

* New translations zen-menubar.ftl (Turkish)

* New translations zen-menubar.ftl (Chinese Traditional)

* New translations zen-menubar.ftl (Icelandic)

* New translations zen-menubar.ftl (Portuguese, Brazilian)

* New translations zen-menubar.ftl (Welsh)

* New translations zen-preferences.ftl (Catalan)

* New translations zen-preferences.ftl (Russian)

* New translations zen-preferences.ftl (Turkish)

* New translations zen-general.ftl (Indonesian)

* New translations zen-workspaces.ftl (Chinese Traditional)

* New translations zen-menubar.ftl (Chinese Traditional)

* New translations zen-menubar.ftl (Indonesian)

* New translations zen-workspaces.ftl (Indonesian)

* New translations zen-preferences.ftl (Indonesian)

* New translations zen-general.ftl (Welsh)

* New translations zen-menubar.ftl (French)

* New translations zen-menubar.ftl (Irish)
2026-02-05 11:00:01 +01:00
mr. m
0c684a9bdb fix: Fixed drag and dropping folders into different spaces, b=no-bug, c=tabs 2026-02-03 20:51:52 +01:00
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
78 changed files with 1196 additions and 428 deletions

View File

@@ -73,15 +73,13 @@ jobs:
npm run sync
fi
- name: Run formatter
if: steps.check-upstream-branch.outputs.branch_exists == 'false'
run: |
sudo apt install python3-autopep8
npm run pretty
- name: Install autopep8
run: sudo apt install python3-autopep8
- name: Check if any files changed
id: git-check
run: |
npm run pretty
if [ -n "$(git status --porcelain)" ]; then
echo "files_changed=true" >> $GITHUB_OUTPUT
else
@@ -111,6 +109,15 @@ jobs:
if: steps.git-check.outputs.files_changed == 'true'
run: python3 scripts/import_external_tests.py || true
- name: Import external patches
if: steps.git-check.outputs.files_changed == 'true'
run: python3 scripts/import_external_patches.py || true
- name: Run formatter
if: steps.check-upstream-branch.outputs.branch_exists == 'false'
run: |
npm run pretty
- name: Create pull request
uses: peter-evans/create-pull-request@v7
if: steps.git-check.outputs.files_changed == 'true'

View File

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

View File

@@ -1 +1 @@
783b222b1b93fb9e8c52eb57558ef7f07bca6e7e
b1e00b74d3791a5a7bbd6ba3d32b69b60471e73b

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 &#124; 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

@@ -314,4 +314,4 @@ zen-devtools-toggle-storage-shortcut = Commuta l'emmagatzematge
zen-devtools-toggle-dom-shortcut = Commuta el DOM
zen-devtools-toggle-accessibility-shortcut = Commuta l'accessibilitat
zen-close-all-unpinned-tabs-shortcut = Tanca totes les pestanyes no fixades
zen-new-unsynced-window-shortcut = Nova finestra no sincronitzada
zen-new-unsynced-window-shortcut = Nova finestra en blanc

View File

@@ -19,4 +19,4 @@ zen-menubar-appearance-light =
zen-menubar-appearance-dark =
.label = Fosca
zen-menubar-new-unsynced-window =
.label = New Blank Window
.label = Nova finestra en blanc

View File

@@ -314,4 +314,4 @@ zen-devtools-toggle-storage-shortcut = Toglo Storio
zen-devtools-toggle-dom-shortcut = Toglo DOM
zen-devtools-toggle-accessibility-shortcut = Toglo Hygyrchedd
zen-close-all-unpinned-tabs-shortcut = Cau Pob Tab Heb ei Binio
zen-new-unsynced-window-shortcut = Ffenestr Newydd Heb ei Chydweddu
zen-new-unsynced-window-shortcut = Ffenestr Wag Newydd

View File

@@ -2,8 +2,8 @@
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
zen-panel-ui-current-profile-text = proffil cyfredol
unified-extensions-description = Mae ychwanegiadau'n cael ei defnyddio er mwyn ychwanegu fwy o weithrediadau i { -brand-short-name }.
zen-panel-ui-current-profile-text = y proffil cyfredol
unified-extensions-description = Mae estyniadau'n cael ei defnyddio er mwyn ychwanegu fwy o swyddogaeth i { -brand-short-name }.
tab-context-zen-reset-pinned-tab =
.label = Ailosod Tab wedi'i Binio
.accesskey = A
@@ -109,7 +109,7 @@ zen-sidebar-notification-updated-tooltip =
zen-sidebar-notification-restart-safe-mode-label = Rhywbeth wedi torri?
zen-sidebar-notification-restart-safe-mode-tooltip =
.title = Ailgychwyn yn y Modd Diogel
zen-window-sync-migration-dialog-title = Keep Your Windows in Sync
zen-window-sync-migration-dialog-message = Zen now syncs windows on the same device, so changes in one window are reflected across the others instantly.
zen-window-sync-migration-dialog-learn-more = Learn More
zen-window-sync-migration-dialog-accept = Got It
zen-window-sync-migration-dialog-title = Cadw Eich Ffenestr Wedi'u Cydweddu
zen-window-sync-migration-dialog-message = Mae Zen bellach yn cydweddu ffenestri ar yr un ddyfais, felly mae newidiadau mewn un ffenestr yn cael eu dangos ar y lleill yn syth.
zen-window-sync-migration-dialog-learn-more = Dysgu Rhagor
zen-window-sync-migration-dialog-accept = Iawn

View File

@@ -19,4 +19,4 @@ zen-menubar-appearance-light =
zen-menubar-appearance-dark =
.label = Tywyll
zen-menubar-new-unsynced-window =
.label = New Blank Window
.label = Ffenestr Wag Newydd

View File

@@ -53,12 +53,15 @@ category-zen-workspaces =
.tooltiptext = { pane-zen-tabs-title }
pane-settings-workspaces-title = Workspaces
zen-tabs-unloader-enabled =
.label = Enable Tab Unloader
zen-tabs-select-recently-used-on-close =
.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 =
.label = Close tab and switch to its owner tab (or most recently used tab) when going back with no history
zen-settings-workspaces-sync-unpinned-tabs =
.label = Sync only pinned tabs in workspaces
zen-tabs-cycle-by-attribute =
.label = Ctrl+Tab cycles within Essential or Workspace tabs only
zen-tabs-cycle-ignore-pending-tabs =

View File

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

View File

@@ -19,4 +19,4 @@ zen-menubar-appearance-light =
zen-menubar-appearance-dark =
.label = Sombre
zen-menubar-new-unsynced-window =
.label = New Blank Window
.label = Nouvelle fenêtre non synchronisée

View File

@@ -19,4 +19,4 @@ zen-menubar-appearance-light =
zen-menubar-appearance-dark =
.label = Dorcha
zen-menubar-new-unsynced-window =
.label = New Blank Window
.label = Fuinneog Nua Bán

View File

@@ -19,4 +19,4 @@ zen-menubar-appearance-light =
zen-menubar-appearance-dark =
.label = כהה
zen-menubar-new-unsynced-window =
.label = New Blank Window
.label = חלון ריק חדש

View File

@@ -19,4 +19,4 @@ zen-menubar-appearance-light =
zen-menubar-appearance-dark =
.label = Sötét
zen-menubar-new-unsynced-window =
.label = New Blank Window
.label = Új üres lap

View File

@@ -49,8 +49,8 @@ zen-tabs-close-on-back-with-no-history =
zen-tabs-cycle-by-attribute =
.label = Ctrl+Tab berputar hanya dalam tab Esensial atau Ruang Kerja
zen-tabs-cycle-ignore-pending-tabs =
.label = Ignore Pending tabs when cycling with Ctrl+Tab
zen-tabs-cycle-by-attribute-warning = Ctrl+Tab will cycle by recently used order, as it is enabled
.label = Lewati tab tak termuat saat beralih dengan Ctrl+Tab
zen-tabs-cycle-by-attribute-warning = Ctrl+Tab akan beralih berdasarkan urutan terakhir digunakan
zen-look-and-feel-compact-toolbar-themed =
.label = Gunakan latar belakang bertema untuk bilah atas dalam mode ringkas
zen-workspace-continue-where-left-off =
@@ -314,4 +314,4 @@ zen-devtools-toggle-storage-shortcut = Ubah Penyimpanan
zen-devtools-toggle-dom-shortcut = Ubah DOM
zen-devtools-toggle-accessibility-shortcut = Ubah Aksesibilitas
zen-close-all-unpinned-tabs-shortcut = Tutup Semua Tab yang Tidak Disematkan
zen-new-unsynced-window-shortcut = New Unsynced Window
zen-new-unsynced-window-shortcut = Jendela Kosong Baru

View File

@@ -60,8 +60,8 @@ zen-site-data-settings = Pengaturan
zen-generic-manage = Kelola
zen-generic-more = Selengkapnya
zen-generic-next = Lanjut
zen-essentials-promo-label = Add to Essentials
zen-essentials-promo-sublabel = Keep your favorite tabs just a click away
zen-essentials-promo-label = Tambahkan ke Essentials
zen-essentials-promo-sublabel = Akses tab favorit Anda hanya dengan sekali klik
# These labels will be used for the site data panel settings
zen-site-data-setting-allow = Diizinkan
zen-site-data-setting-block = Diblokir
@@ -109,7 +109,7 @@ zen-sidebar-notification-updated-tooltip =
zen-sidebar-notification-restart-safe-mode-label = Ada yang rusak?
zen-sidebar-notification-restart-safe-mode-tooltip =
.title = Mulai Ulang dalam Mode Aman
zen-window-sync-migration-dialog-title = Keep Your Windows in Sync
zen-window-sync-migration-dialog-message = Zen now syncs windows on the same device, so changes in one window are reflected across the others instantly.
zen-window-sync-migration-dialog-learn-more = Learn More
zen-window-sync-migration-dialog-accept = Got It
zen-window-sync-migration-dialog-title = Jaga Jendela Anda Tetap Sinkron
zen-window-sync-migration-dialog-message = Zen kini menyinkronkan jendela pada perangkat yang sama, sehingga perubahan di satu jendela akan langsung terlihat di jendela lainnya.
zen-window-sync-migration-dialog-learn-more = Pelajari Lebih Lanjut
zen-window-sync-migration-dialog-accept = Oke!

View File

@@ -4,19 +4,19 @@
zen-menubar-toggle-pinned-tabs =
.label =
{ $pinnedAreCollapsed ->
[true] Expand Pinned Tabs
*[false] Collapse Pinned Tabs
{ $pinnedAreCollapsed ->
[true] Perluas Tab yang Disematkan
*[false] Ciutkan Tab yang Disematkan
}
zen-menubar-appearance =
.label = Appearance
.label = Tampilan
zen-menubar-appearance-description =
.label = Websites will use:
.label = Situs web akan menggunakan:
zen-menubar-appearance-auto =
.label = Automatic
.label = Otomatis
zen-menubar-appearance-light =
.label = Light
.label = Terang
zen-menubar-appearance-dark =
.label = Dark
.label = Gelap
zen-menubar-new-unsynced-window =
.label = New Blank Window
.label = Jendela Kosong Baru

View File

@@ -4,13 +4,13 @@
zen-panel-ui-workspaces-text = Ruang Kerja Lainnya
zen-panel-ui-spaces-label =
.label = Spaces
.label = Ruang
zen-panel-ui-workspaces-create =
.label = Buat Ruang
zen-panel-ui-folder-create =
.label = Buat Folder
zen-panel-ui-new-empty-split =
.label = New Split
.label = Split Baru
zen-workspaces-panel-context-delete =
.label = Hapus Ruang
.accesskey = D
@@ -66,6 +66,6 @@ zen-workspaces-close-all-unpinned-tabs-title =
.label = Bersihkan
.tooltiptext = Tutup semua tab yang tidak disematkan
zen-panel-ui-workspaces-change-forward =
.label = Next Space
.label = Ruang Selanjutnya
zen-panel-ui-workspaces-change-back =
.label = Previous Space
.label = Ruang Sebelumnya

View File

@@ -19,4 +19,4 @@ zen-menubar-appearance-light =
zen-menubar-appearance-dark =
.label = Dökkt
zen-menubar-new-unsynced-window =
.label = New Blank Window
.label = Nýr auður gluggi

View File

@@ -19,4 +19,4 @@ zen-menubar-appearance-light =
zen-menubar-appearance-dark =
.label = 다크
zen-menubar-new-unsynced-window =
.label = New Blank Window
.label = 새 빈 창

View File

@@ -314,4 +314,4 @@ zen-devtools-toggle-storage-shortcut = Perjungti saugyklą
zen-devtools-toggle-dom-shortcut = Perjungti DOM
zen-devtools-toggle-accessibility-shortcut = Perjungti prieinamumą
zen-close-all-unpinned-tabs-shortcut = Užverti visas neprisegtas korteles
zen-new-unsynced-window-shortcut = Naujas nesinchronizuotas langas
zen-new-unsynced-window-shortcut = Naujas tuščias langas

View File

@@ -60,8 +60,8 @@ zen-site-data-settings = Nustatymai
zen-generic-manage = Tvarkyti
zen-generic-more = Daugiau
zen-generic-next = Sekantis
zen-essentials-promo-label = Add to Essentials
zen-essentials-promo-sublabel = Keep your favorite tabs just a click away
zen-essentials-promo-label = Įtraukti į būtiniausius
zen-essentials-promo-sublabel = Laikykite mėgstamas korteles vos nuo vienu paspaudimu
# These labels will be used for the site data panel settings
zen-site-data-setting-allow = Leidžiama
zen-site-data-setting-block = Užblokuota
@@ -109,7 +109,7 @@ zen-sidebar-notification-updated-tooltip =
zen-sidebar-notification-restart-safe-mode-label = Kažkas sugedo?
zen-sidebar-notification-restart-safe-mode-tooltip =
.title = Paleisti iš naujo saugioje režime
zen-window-sync-migration-dialog-title = Keep Your Windows in Sync
zen-window-sync-migration-dialog-message = Zen now syncs windows on the same device, so changes in one window are reflected across the others instantly.
zen-window-sync-migration-dialog-learn-more = Learn More
zen-window-sync-migration-dialog-accept = Got It
zen-window-sync-migration-dialog-title = Išlaikykite savo langus sinchronizuotus
zen-window-sync-migration-dialog-message = Zen“ dabar sinchronizuoja langus tame pačiame įrenginyje, todėl viename lange atlikti pakeitimai iš karto atsispindi ir kituose.
zen-window-sync-migration-dialog-learn-more = Sužinoti daugiau
zen-window-sync-migration-dialog-accept = Supratau

View File

@@ -19,4 +19,4 @@ zen-menubar-appearance-light =
zen-menubar-appearance-dark =
.label = Tamsų
zen-menubar-new-unsynced-window =
.label = New Blank Window
.label = Naujas tuščias langas

View File

@@ -19,4 +19,4 @@ zen-menubar-appearance-light =
zen-menubar-appearance-dark =
.label = Escuro
zen-menubar-new-unsynced-window =
.label = New Blank Window
.label = Nova janela em branco

View File

@@ -18,9 +18,9 @@ tab-context-zen-replace-pinned-url-with-current =
.label = Substituir o URL Fixado pelo URL Atual
.accesskey = C
tab-context-zen-edit-title =
.label = Change Label...
.label = Alterar etiqueta...
tab-context-zen-edit-icon =
.label = Change Icon...
.label = Alterar ícone...
zen-themes-corrupted = O seu ficheiro de modificações do { -brand-short-name } está corrompido. Elas foram redefinidas como iguais às do tema padrão.
zen-shortcuts-corrupted = O seu ficheiro de atalhos do { -brand-short-name } está corrompido. Eles foram redefinidos para os atalhos padrão.
# note: Do not translate the "<br/>" tags in the following string
@@ -109,7 +109,7 @@ zen-sidebar-notification-updated-tooltip =
zen-sidebar-notification-restart-safe-mode-label = Falhou alguma coisa?
zen-sidebar-notification-restart-safe-mode-tooltip =
.title = Reiniciar em Modo de Segurança
zen-window-sync-migration-dialog-title = Keep Your Windows in Sync
zen-window-sync-migration-dialog-message = Zen now syncs windows on the same device, so changes in one window are reflected across the others instantly.
zen-window-sync-migration-dialog-title = Mantenha As Suas Janelas Sincronizadas
zen-window-sync-migration-dialog-message = Agora, o Zen sincroniza as janelas no dispositivo, pelo que alterações numa janela são refletidas instantaneamente nas outras.
zen-window-sync-migration-dialog-learn-more = Learn More
zen-window-sync-migration-dialog-accept = Got It
zen-window-sync-migration-dialog-accept = Entendido

View File

@@ -19,4 +19,4 @@ zen-menubar-appearance-light =
zen-menubar-appearance-dark =
.label = Escuro
zen-menubar-new-unsynced-window =
.label = New Blank Window
.label = Nova janela sem sincronização

View File

@@ -314,4 +314,4 @@ zen-devtools-toggle-storage-shortcut = Переключить хранилище
zen-devtools-toggle-dom-shortcut = Переключить DOM
zen-devtools-toggle-accessibility-shortcut = Включить/выключить специальные возможности
zen-close-all-unpinned-tabs-shortcut = Закрыть все не закреплённые вкладки
zen-new-unsynced-window-shortcut = Новое несинхронизированное окно
zen-new-unsynced-window-shortcut = Новое пустое окно

View File

@@ -314,4 +314,4 @@ zen-devtools-toggle-storage-shortcut = Växla lagring
zen-devtools-toggle-dom-shortcut = Växla DOM
zen-devtools-toggle-accessibility-shortcut = Växla tillgänglighetsinställningar
zen-close-all-unpinned-tabs-shortcut = Stäng alla flikar som inte är fästa
zen-new-unsynced-window-shortcut = Nytt osynkroniserat fönster
zen-new-unsynced-window-shortcut = Nytt tomt fönster

View File

@@ -19,4 +19,4 @@ zen-menubar-appearance-light =
zen-menubar-appearance-dark =
.label = Mörkt
zen-menubar-new-unsynced-window =
.label = New Blank Window
.label = Nytt tomt fönster

View File

@@ -314,4 +314,4 @@ zen-devtools-toggle-storage-shortcut = Depolamayı Aç/Kapat
zen-devtools-toggle-dom-shortcut = DOM'u Aç/Kapat
zen-devtools-toggle-accessibility-shortcut = Erişilebilirliği Aç/Kapat
zen-close-all-unpinned-tabs-shortcut = Sabitlenmemiş Tüm Sekmeleri Kapat
zen-new-unsynced-window-shortcut = Senkronize Edilmemiş Yeni Pencere
zen-new-unsynced-window-shortcut = Yeni Boş Pencere

View File

@@ -19,4 +19,4 @@ zen-menubar-appearance-light =
zen-menubar-appearance-dark =
.label = Koyu
zen-menubar-new-unsynced-window =
.label = New Blank Window
.label = Yeni Boş Pencere

View File

@@ -314,4 +314,4 @@ zen-devtools-toggle-storage-shortcut = 開啟儲存空間檢測器
zen-devtools-toggle-dom-shortcut = 開啟 DOM
zen-devtools-toggle-accessibility-shortcut = 開啟輔助功能
zen-close-all-unpinned-tabs-shortcut = 關閉所有未釘選的分頁
zen-new-unsynced-window-shortcut = 開新未同步視窗
zen-new-unsynced-window-shortcut = 開新初始視窗

View File

@@ -19,4 +19,4 @@ zen-menubar-appearance-light =
zen-menubar-appearance-dark =
.label = 暗色
zen-menubar-new-unsynced-window =
.label = 新初始視窗
.label = 新初始視窗

View File

@@ -49,7 +49,7 @@ zen-panel-ui-gradient-click-to-add = 點擊新增顏色
zen-workspace-creation-name =
.placeholder = 工作區名稱
zen-move-tab-to-workspace-button =
.label = 移動至…
.label = 移動至…
.tooltiptext = 將此視窗所有頁面移至單一工作區
zen-workspaces-panel-context-reorder =
.label = 排序工作區

View File

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

View File

@@ -13,3 +13,6 @@
- name: zen.window-sync.open-link-in-new-unsynced-window
value: true
- name: zen.window-sync.sync-only-pinned-tabs
value: false

View File

@@ -1,41 +0,0 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
import os
import sys
import requests
BASE_URI = "https://phabricator.services.mozilla.com"
OUTPUT_DIR = os.path.join(os.getcwd(), "src", "firefox-patches")
def download_phab_patch(phab_id, output_file):
"""Download a Phabricator patch by its ID and save it to output_file."""
patch_url = f"{BASE_URI}/{phab_id}?download=true"
try:
print(f"Downloading patch from {patch_url}")
response = requests.get(patch_url)
response.raise_for_status() # Raise an error for bad responses
with open(output_file, 'wb') as f:
f.write(response.content)
print(f"Patch saved to {output_file}")
except requests.RequestException as e:
print(f"Error downloading patch: {e}")
sys.exit(1)
def main():
if len(sys.argv) < 2:
print("Usage: python download_phab_patch.py <PHABRICATOR_ID> [output_file]", file=sys.stderr)
sys.exit(1)
phab_id = sys.argv[1]
output_file = sys.argv[2] if len(sys.argv) > 2 else f"phab_{phab_id}"
output_file = os.path.join(OUTPUT_DIR, output_file + ".patch")
download_phab_patch(phab_id, output_file)
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,99 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
import os
import sys
import json
import requests
from json_with_comments import JSONWithCommentsDecoder
BASE_URI = "https://phabricator.services.mozilla.com"
OUTPUT_DIR = os.path.join(os.getcwd(), "src", "external-patches")
def die(message):
print(f"Error: {message}")
sys.exit(1)
def download_phab_patch(phab_id, output_file):
"""Download a Phabricator patch by its ID and save it to output_file."""
patch_url = f"{BASE_URI}/{phab_id}?download=true"
try:
print(f"Downloading patch from {patch_url}")
response = requests.get(patch_url)
response.raise_for_status() # Raise an error for bad responses
with open(output_file, 'wb') as f:
f.write(response.content)
print(f"Patch saved to {output_file}")
except requests.RequestException as e:
die(f"Failed to download patch {phab_id}: {e}")
def download_patch_from_url(url, output_file):
"""Download a patch from a given URL and save it to output_file."""
try:
print(f"Downloading patch from {url}")
response = requests.get(url)
response.raise_for_status() # Raise an error for bad responses
with open(output_file, 'wb') as f:
f.write(response.content)
print(f"Patch saved to {output_file}")
except requests.RequestException as e:
die(f"Failed to download patch from {url}: {e}")
def main():
with open(os.path.join(OUTPUT_DIR, "manifest.json"), 'r') as f:
manifest = json.load(f, cls=JSONWithCommentsDecoder)
expected_files = set()
for patch in manifest:
if patch.get("type") == "phabricator":
phab_id = patch.get("id")
name = patch.get("name")
if not phab_id or not name:
die(f"Patch entry missing 'id' or 'name': {patch}")
name = name.replace(" ", "_").lower()
output_file = os.path.join(OUTPUT_DIR, "firefox", f"{name}.patch")
print(f"Processing Phabricator patch: {phab_id} -> {output_file}")
download_phab_patch(phab_id, output_file)
expected_files.add(output_file)
elif patch.get("type") == "local":
print(f"Local patch: {patch.get('path')}")
expected_files.add(os.path.join(OUTPUT_DIR, patch.get("path")))
elif patch.get("type") == "patch":
url = patch.get("url")
dest = patch.get("dest")
if not url or not dest:
die(f"Patch entry missing 'url' or 'dest': {patch}")
filename = url.split("/")[-1]
output_file = os.path.join(OUTPUT_DIR, dest, filename)
download_patch_from_url(url, output_file)
replaces = patch.get("replaces", {})
for replace in replaces.keys():
value = replaces[replace]
with open(output_file, 'r') as f:
content = f.read()
if replace not in content:
die(f"Replace string '{replace}' not found in {output_file}")
with open(output_file, 'w') as f:
f.write(content.replace(replace, value))
expected_files.add(output_file)
else:
die(f"Unknown patch type: {patch.get('type')}")
# Check for unexpected files in the output directory
# and remove them if they are not in the expected_files set.
for root, dirs, files in os.walk(OUTPUT_DIR):
for file in files:
if file.endswith(".patch"):
file_path = os.path.join(root, file)
if file_path not in expected_files:
print(f"Removing unexpected patch file: {file_path}")
os.remove(file_path)
if __name__ == "__main__":
main()

View File

@@ -736,6 +736,7 @@ var gZenWorkspacesSettings = {
Services.prefs.addObserver("zen.glance.enabled", tabsUnloaderPrefListener); // We can use the same listener for both prefs
Services.prefs.addObserver("zen.workspaces.separate-essentials", tabsUnloaderPrefListener);
Services.prefs.addObserver("zen.glance.activation-method", tabsUnloaderPrefListener);
Services.prefs.addObserver("zen.window-sync.sync-only-pinned-tabs", tabsUnloaderPrefListener);
Services.prefs.addObserver(
"zen.tabs.ctrl-tab.ignore-essential-tabs",
toggleZenCycleByAttrWarning
@@ -745,6 +746,10 @@ var gZenWorkspacesSettings = {
Services.prefs.removeObserver("zen.glance.enabled", tabsUnloaderPrefListener);
Services.prefs.removeObserver("zen.glance.activation-method", tabsUnloaderPrefListener);
Services.prefs.removeObserver("zen.workspaces.separate-essentials", tabsUnloaderPrefListener);
Services.prefs.removeObserver(
"zen.window-sync.sync-only-pinned-tabs",
tabsUnloaderPrefListener
);
Services.prefs.removeObserver(
"zen.tabs.ctrl-tab.ignore-essential-tabs",
toggleZenCycleByAttrWarning
@@ -1193,6 +1198,16 @@ Preferences.addAll([
type: "bool",
default: false,
},
{
id: "zen.tabs.select-recently-used-on-close",
type: "bool",
default: true,
},
{
id: "zen.window-sync.sync-only-pinned-tabs",
type: "bool",
default: false,
},
]);
Preferences.addSetting({

View File

@@ -20,6 +20,9 @@
<label><html:h2 data-l10n-id="zen-settings-workspaces-header"/></label>
<description class="description-deemphasized" data-l10n-id="zen-settings-workspaces-description" />
<checkbox id="zenWorkspacesSyncUnpinnedTabs"
data-l10n-id="zen-settings-workspaces-sync-unpinned-tabs"
preference="zen.window-sync.sync-only-pinned-tabs"/>
<checkbox id="zenWorkspacesHideDefaultContainer"
data-l10n-id="zen-settings-workspaces-hide-default-container-indicator"
preference="zen.workspaces.hide-default-container-indicator"/>
@@ -37,15 +40,10 @@
class="description-deemphasized"
data-l10n-id="zen-tabs-cycle-by-attribute-warning"
hidden="true"/>
<checkbox data-l10n-id="zen-tabs-select-recently-used-on-close"
preference="zen.tabs.select-recently-used-on-close"/>
</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"
class="subcategory"
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
index 57800333445ec7850742145527e04ae8d504b0bb..65361da4791b6418705f364f750f409b1f2bf82b 100644
index 57800333445ec7850742145527e04ae8d504b0bb..a13875436a72f89178455a09c8665b9a1ef240b5 100644
--- a/browser/components/tabbrowser/content/drag-and-drop.js
+++ b/browser/components/tabbrowser/content/drag-and-drop.js
@@ -35,6 +35,9 @@
@@ -39,7 +39,7 @@ index 57800333445ec7850742145527e04ae8d504b0bb..65361da4791b6418705f364f750f409b
event.stopPropagation();
+ if (draggedTab && dropEffect == "move") {
+ 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") {
let duplicatedDraggedTab;
@@ -102,7 +102,36 @@ index 57800333445ec7850742145527e04ae8d504b0bb..65361da4791b6418705f364f750f409b
postTransitionCleanup();
} else {
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 tabGroup = isTab(nextItem) && nextItem.group;
@@ -110,7 +139,7 @@ index 57800333445ec7850742145527e04ae8d504b0bb..65361da4791b6418705f364f750f409b
gBrowser.loadTabs(urls, {
inBackground,
replace,
@@ -621,7 +635,16 @@
@@ -621,7 +631,16 @@
this._expandGroupOnDrop(draggedTab);
}
this._resetTabsAfterDrop(draggedTab.ownerDocument);
@@ -128,7 +157,7 @@ index 57800333445ec7850742145527e04ae8d504b0bb..65361da4791b6418705f364f750f409b
if (
dt.mozUserCancelled ||
dt.dropEffect != "none" ||
@@ -825,7 +848,10 @@
@@ -825,7 +844,10 @@
_getDragTarget(event, { ignoreSides = false } = {}) {
let { target } = event;
while (target) {
@@ -140,7 +169,7 @@ index 57800333445ec7850742145527e04ae8d504b0bb..65361da4791b6418705f364f750f409b
break;
}
target = target.parentNode;
@@ -842,14 +868,17 @@
@@ -842,14 +864,17 @@
return null;
}
}
@@ -160,7 +189,7 @@ index 57800333445ec7850742145527e04ae8d504b0bb..65361da4791b6418705f364f750f409b
!this._tabbrowserTabs.expandOnHover
);
}
@@ -880,7 +909,8 @@
@@ -880,7 +905,8 @@
isTabGroupLabel(draggedTab) &&
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.
if (platform == "win" || platform == "macosx") {
captureListener = function () {
@@ -178,7 +207,7 @@ index 57800333445ec7850742145527e04ae8d504b0bb..65361da4791b6418705f364f750f409b
};
} else {
// Create a panel to use it in setDragImage
@@ -1096,7 +1125,6 @@
@@ -1096,7 +1121,6 @@
);
dragImageOffset = dragImageOffset * scale;
}
@@ -186,7 +215,7 @@ index 57800333445ec7850742145527e04ae8d504b0bb..65361da4791b6418705f364f750f409b
// _dragData.offsetX/Y give the coordinates that the mouse should be
// 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 isMovingInTabStrip = !fromTabList && dropEffect == "move";
let collapseTabGroupDuringDrag =
@@ -195,7 +224,7 @@ index 57800333445ec7850742145527e04ae8d504b0bb..65361da4791b6418705f364f750f409b
tab._dragData = {
offsetX: this._tabbrowserTabs.verticalMode
@@ -1125,7 +1153,7 @@
@@ -1125,7 +1149,7 @@
? event.screenY - window.screenY - tabOffset
: event.screenY - window.screenY,
scrollPos:
@@ -204,7 +233,7 @@ index 57800333445ec7850742145527e04ae8d504b0bb..65361da4791b6418705f364f750f409b
? this._tabbrowserTabs.pinnedTabsContainer.scrollPosition
: this._tabbrowserTabs.arrowScrollbox.scrollPosition,
screenX: event.screenX,
@@ -1152,6 +1180,7 @@
@@ -1152,6 +1176,7 @@
if (collapseTabGroupDuringDrag) {
tab.group.collapsed = true;
@@ -212,7 +241,7 @@ index 57800333445ec7850742145527e04ae8d504b0bb..65361da4791b6418705f364f750f409b
}
}
}
@@ -1176,6 +1205,7 @@
@@ -1176,6 +1201,7 @@
if (tabStripItemElement.hasAttribute("dragtarget")) {
return;
}
@@ -220,7 +249,7 @@ index 57800333445ec7850742145527e04ae8d504b0bb..65361da4791b6418705f364f750f409b
let isPinned = tab.pinned;
let numPinned = gBrowser.pinnedTabCount;
let dragAndDropElements = this._tabbrowserTabs.dragAndDropElements;
@@ -1601,7 +1631,6 @@
@@ -1601,7 +1627,6 @@
for (let item of this._tabbrowserTabs.dragAndDropElements) {
item = elementToMove(item);
@@ -228,7 +257,7 @@ index 57800333445ec7850742145527e04ae8d504b0bb..65361da4791b6418705f364f750f409b
item.removeAttribute("multiselected-move-together");
delete item._moveTogetherSelectedTabsData;
}
@@ -2429,7 +2458,6 @@
@@ -2429,7 +2454,6 @@
for (let item of this._tabbrowserTabs.dragAndDropElements) {
this._resetGroupTarget(item);
item = elementToMove(item);
@@ -236,7 +265,7 @@ index 57800333445ec7850742145527e04ae8d504b0bb..65361da4791b6418705f364f750f409b
}
this._tabbrowserTabs.removeAttribute("movingtab-group");
this._tabbrowserTabs.removeAttribute("movingtab-ungroup");
@@ -2460,17 +2488,14 @@
@@ -2460,17 +2484,14 @@
tab.style.left = "";
tab.style.top = "";
tab.style.maxWidth = "";

View File

@@ -1,5 +1,5 @@
diff --git a/browser/components/tabbrowser/content/tab.js b/browser/components/tabbrowser/content/tab.js
index 6528da245d922e2ccdb59cbf8106055bc34d1e74..1cd3395961a80e3b48582794b5b5365c9b8386b3 100644
index 6528da245d922e2ccdb59cbf8106055bc34d1e74..b5d5ac633c06d7d9c909ec9456a5f3c165a6b925 100644
--- a/browser/components/tabbrowser/content/tab.js
+++ b/browser/components/tabbrowser/content/tab.js
@@ -21,6 +21,7 @@
@@ -52,7 +52,7 @@ index 6528da245d922e2ccdb59cbf8106055bc34d1e74..1cd3395961a80e3b48582794b5b5365c
return;
}
@@ -224,11 +227,21 @@
@@ -224,11 +227,23 @@
}
get visible() {
@@ -64,7 +64,6 @@ index 6528da245d922e2ccdb59cbf8106055bc34d1e74..1cd3395961a80e3b48582794b5b5365c
+ if (!this.isOpen || this.hidden || this.hasAttribute("zen-empty-tab")) {
+ return false;
+ }
+
+ // Selected tabs are always visible
+ if (this.selected || this.multiselected || this.hasAttribute("folder-active")) return true;
+ // Recursively check all parent groups
@@ -75,11 +74,14 @@ index 6528da245d922e2ccdb59cbf8106055bc34d1e74..1cd3395961a80e3b48582794b5b5365c
+ }
+ currentParent = currentParent.group;
+ }
+ if (this.pinned && !this.hasAttribute("zen-essential") && gZenWorkspaces.activeWorkspaceElement?.hasCollapsedPinnedTabs) {
+ return false;
+ }
+ return true;
}
get hidden() {
@@ -307,7 +320,7 @@
@@ -307,7 +322,7 @@
return false;
}
@@ -88,7 +90,7 @@ index 6528da245d922e2ccdb59cbf8106055bc34d1e74..1cd3395961a80e3b48582794b5b5365c
}
get lastAccessed() {
@@ -384,7 +397,18 @@
@@ -384,7 +399,18 @@
}
get group() {
@@ -108,7 +110,7 @@ index 6528da245d922e2ccdb59cbf8106055bc34d1e74..1cd3395961a80e3b48582794b5b5365c
}
get splitview() {
@@ -489,6 +513,8 @@
@@ -489,6 +515,8 @@
this.style.MozUserFocus = "ignore";
} else if (
event.target.classList.contains("tab-close-button") ||
@@ -117,7 +119,7 @@ index 6528da245d922e2ccdb59cbf8106055bc34d1e74..1cd3395961a80e3b48582794b5b5365c
event.target.classList.contains("tab-icon-overlay") ||
event.target.classList.contains("tab-audio-button")
) {
@@ -543,6 +569,10 @@
@@ -543,6 +571,10 @@
this.style.MozUserFocus = "";
}
@@ -128,7 +130,7 @@ index 6528da245d922e2ccdb59cbf8106055bc34d1e74..1cd3395961a80e3b48582794b5b5365c
on_click(event) {
if (event.button != 0) {
return;
@@ -603,6 +633,14 @@
@@ -603,6 +635,14 @@
// (see tabbrowser-tabs 'click' handler).
gBrowser.tabContainer._blockDblClick = true;
}
@@ -143,7 +145,7 @@ index 6528da245d922e2ccdb59cbf8106055bc34d1e74..1cd3395961a80e3b48582794b5b5365c
}
on_dblclick(event) {
@@ -626,6 +664,8 @@
@@ -626,6 +666,8 @@
animate: true,
triggeringEvent: event,
});

View File

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

View File

@@ -0,0 +1,3 @@
# Patches imported from LibreWolf
Firefox sometimes makes changes without considering the impact on forks. This is the case of the patches that are imported from LibreWolf, which are already present in LibreWolf but not yet (or never) present in Firefox. Thanks to LibreWolf for making these patches available and for their work in maintaining them. We will keep these patches as long as they are needed, and we will remove them once they are no longer necessary (for example, when they are merged into Firefox or when the issue they solve is no longer present).

View File

@@ -0,0 +1,12 @@
diff --git a/toolkit/moz.configure b/toolkit/moz.configure
--- a/toolkit/moz.configure
+++ b/toolkit/moz.configure
@@ -28,7 +28,7 @@ project_flag(
project_flag(
env="MOZ_APP_UA_NAME",
- default="",
+ default="Firefox",
nargs=1,
help="Application name in the User Agent string",
)

View File

@@ -0,0 +1,65 @@
diff --git a/toolkit/xre/nsXREDirProvider.cpp b/toolkit/xre/nsXREDirProvider.cpp
index 3cf7073..b1c782a 100644
--- a/toolkit/xre/nsXREDirProvider.cpp
+++ b/toolkit/xre/nsXREDirProvider.cpp
@@ -1283,9 +1283,11 @@ nsresult nsXREDirProvider::AppendFromAppData(nsIFile* aFile, bool aIsDotted) {
// Similar to nsXREDirProvider::AppendProfilePath.
// TODO: Bug 1990407 - Evaluate if refactoring might be required there in the
// future?
- if (gAppData->profile) {
+ // Use aIsDotted for a different purpose here, will probably break in the future
+ if (gAppData->profile && aIsDotted) {
nsAutoCString profile;
profile = gAppData->profile;
+ profile = "."_ns + nsDependentCString(gAppData->profile);
MOZ_TRY(aFile->AppendRelativeNativePath(profile));
} else {
nsAutoCString vendor;
@@ -1295,8 +1297,8 @@ nsresult nsXREDirProvider::AppendFromAppData(nsIFile* aFile, bool aIsDotted) {
ToLowerCase(vendor);
ToLowerCase(appName);
- MOZ_TRY(aFile->AppendRelativeNativePath(aIsDotted ? ("."_ns + vendor)
- : vendor));
+ //MOZ_TRY(aFile->AppendRelativeNativePath(aIsDotted ? ("."_ns + vendor)
+ // : vendor));
MOZ_TRY(aFile->AppendRelativeNativePath(appName));
}
@@ -1435,28 +1437,22 @@ nsresult nsXREDirProvider::GetLegacyOrXDGHomePath(const char* aHomeDir,
return NS_OK;
}
- // If the build was made against a specific profile name, MOZ_APP_PROFILE=
- // then make sure we respect this and dont move to XDG directory
- if (gAppData->profile) {
- MOZ_TRY(NS_NewNativeLocalFile(nsDependentCString(aHomeDir),
- getter_AddRefs(localDir)));
- } else {
- MOZ_TRY(GetLegacyOrXDGConfigHome(aHomeDir, getter_AddRefs(localDir)));
- MOZ_TRY(localDir->Clone(getter_AddRefs(parentDir)));
- }
+ // Since we set gAppData->profile and don't want to force legacy behaviour
+ MOZ_TRY(GetLegacyOrXDGConfigHome(aHomeDir, getter_AddRefs(localDir)));
+ MOZ_TRY(localDir->Clone(getter_AddRefs(parentDir)));
MOZ_TRY(AppendFromAppData(localDir, false));
}
+ // The profile root directory needs to exists at that point.
+ MOZ_TRY(EnsureDirectoryExists(localDir));
+
// If required return the parent directory that matches the profile root
// directory.
if (aFile) {
- parentDir.forget(aFile);
+ localDir.forget(aFile);
}
- // The profile root directory needs to exists at that point.
- MOZ_TRY(EnsureDirectoryExists(localDir));
-
return NS_OK;
}
#endif // defined(MOZ_WIDGET_GTK)

View File

@@ -0,0 +1,29 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
[
{
"type": "phabricator",
"id": "D279007",
"name": "Fix MacOS Crash on Shutdown Firefox 149"
},
{
"type": "local",
"path": "firefox/no_liquid_glass_icon.patch"
},
{
"type": "patch",
"url": "https://codeberg.org/librewolf/source/raw/branch/main/patches/firefox-in-ua.patch",
"dest": "librewolf",
"replaces": {
// They don't correctly export this patch, so we need to replace
// the parameter's help description with the correct one.
"application": "Application"
}
},
{
"type": "patch",
"url": "https://codeberg.org/librewolf/source/raw/branch/main/patches/xdg-dir.patch",
"dest": "librewolf"
}
]

View File

@@ -1,13 +0,0 @@
diff --git a/netwerk/protocol/http/moz.build b/netwerk/protocol/http/moz.build
index d2330003caf35c43d6831fb0d356ece513906f78..76c2faf822ddaf645eb03d93380c58b4e3b510c0 100644
--- a/netwerk/protocol/http/moz.build
+++ b/netwerk/protocol/http/moz.build
@@ -227,7 +227,7 @@ LOCAL_INCLUDES += [
"/netwerk/url-classifier",
]
-DEFINES["MOZ_APP_UA_NAME"] = f'"{CONFIG["MOZ_APP_UA_NAME"]}"'
+DEFINES["MOZ_APP_UA_NAME"] = f'"Firefox"'
if CONFIG["MOZ_AUTH_EXTENSION"]:
LOCAL_INCLUDES += [

View File

@@ -7,7 +7,7 @@ index 0d7a3e505b6bd30548c6dda1504dd343a517b083..54400def5e02e886765fab68c3854a6b
getBrowserInfo: function () {
const { name, vendor, version, appBuildID } = Services.appinfo;
- const info = { name, vendor, version, buildID: appBuildID };
+ const info = { name: 'firefox', vendor, version: AppConstants.ZEN_FIREFOX_VERSION, buildID: appBuildID };
+ const info = { name: 'Firefox', vendor, version: AppConstants.ZEN_FIREFOX_VERSION, buildID: appBuildID };
return Promise.resolve(info);
},

View File

@@ -98,6 +98,12 @@ export class nsZenMenuBar {
</menu>`);
document.getElementById("view-menu").after(spacesMenubar);
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();
});
}
@@ -124,6 +130,9 @@ export class nsZenMenuBar {
}
#hideWindowRestoreMenus() {
if (!Services.prefs.getBoolPref("zen.window-sync.enabled", true)) {
return;
}
const itemsToHide = ["appMenuRecentlyClosedWindows", "historyUndoWindowMenu"];
for (const id of itemsToHide) {
const element = PanelMultiView.getViewNode(document, id);

View File

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

View File

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

View File

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

View File

@@ -309,7 +309,7 @@
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));
opacity: 0;
transition: all 0.2s;

View File

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

View File

@@ -10,8 +10,14 @@
}
#zen-dragover-background {
width: calc(100% - var(--zen-toolbox-padding) * 2 - 5px);
width: calc(100% - var(--zen-toolbox-padding) * 2 - 7px);
left: unset;
right: calc(var(--zen-toolbox-padding) + 3px);
transform: translateY(-4px);
:root:not([zen-single-toolbar="true"]) & {
transform: translateY(calc(-100% - 2px));
}
}
#zen-tabbox-wrapper {

View File

@@ -105,7 +105,7 @@
startTabDrag(event, tab, ...args) {
this.ZenDragAndDropService.onDragStart(1);
gZenCompactModeManager._isTabBeingDragged = true;
super.startTabDrag(event, tab, ...args);
const dt = event.dataTransfer;
if (isTabGroupLabel(tab)) {
@@ -117,9 +117,7 @@
this.originalDragImageArgs = [dragImage, offsetX, offsetY];
dt.setDragImage(...this.originalDragImageArgs);
if (tab.hasAttribute("zen-essential")) {
setTimeout(() => {
tab.style.visibility = "hidden";
}, 0);
tab.style.visibility = "hidden";
}
}
@@ -145,7 +143,7 @@
if (tabClone.hasAttribute("visuallyselected")) {
tabClone.style.transform = "translate(-50%, -50%)";
}
} else if (AppConstants.platform !== "macosx") {
} else if (AppConstants.platform !== "macosx" && !tab.isZenFolder) {
// On windows and linux, we still don't add some extra opaqueness
// for the tab to be more visible. This is a hacky workaround.
// TODO: Make windows and linux DnD use nsZenDragAndDrop::mDragImageOpacity
@@ -674,12 +672,20 @@
if (!isTab(draggedTab)) {
return;
}
const { clientX, clientY } = event;
const { innerWidth, innerHeight } = window;
let { screenX, clientX, screenY, clientY } = event;
if (!screenX && !screenY) {
return;
}
const { innerWidth: winWidth, innerHeight: winHeight } = window;
let allowedMargin = Services.prefs.getIntPref("zen.tabs.dnd-outside-window-margin", 5);
const isOutOfWindow =
clientX < 0 || clientX > innerWidth || clientY < 0 || clientY > innerHeight;
clientX <= allowedMargin ||
clientX >= winWidth - allowedMargin ||
clientY <= allowedMargin ||
clientY >= winHeight - allowedMargin;
if (isOutOfWindow && !this.#isOutOfWindow) {
this.#isOutOfWindow = true;
gZenViewSplitter.onBrowserDragEndToSplit(event, true);
this.#maybeClearVerticalPinnedGridDragOver();
this.clearSpaceSwitchTimer();
this.clearDragOverVisuals();
@@ -703,7 +709,7 @@
this.originalDragImageArgs[1],
this.originalDragImageArgs[2]
);
window.addEventListener("dragover", this.handle_windowDragEnter, {
window.addEventListener("dragenter", this.handle_windowDragEnter, {
once: true,
capture: true,
});
@@ -718,20 +724,22 @@
const dt = event.dataTransfer;
const activeWorkspace = gZenWorkspaces.activeWorkspace;
let draggedTab = dt.mozGetDataAt(TAB_DROP_TYPE, 0);
if (
isTab(draggedTab) &&
!draggedTab.hasAttribute("zen-essential") &&
draggedTab.getAttribute("zen-workspace-id") != activeWorkspace
) {
const movingTabs = draggedTab._dragData?.movingTabs || [draggedTab];
for (let tab of movingTabs) {
tab.setAttribute("zen-workspace-id", activeWorkspace);
if (draggedTab.ownerGlobal === window) {
if (
!draggedTab.hasAttribute("zen-essential") &&
draggedTab.getAttribute("zen-workspace-id") != activeWorkspace
) {
if (isTab(draggedTab)) {
const movingTabs = draggedTab._dragData?.movingTabs || [draggedTab];
for (let tab of movingTabs) {
tab.setAttribute("zen-workspace-id", activeWorkspace);
}
gBrowser.selectedTab = draggedTab;
} else if (isTabGroupLabel(draggedTab)) {
draggedTab = draggedTab.group;
gZenFolders.changeFolderToSpace(draggedTab, activeWorkspace, { hasDndSwitch: true });
}
}
gBrowser.selectedTab = draggedTab;
}
if (isTabGroupLabel(draggedTab)) {
draggedTab = draggedTab.group;
gZenFolders.changeFolderToSpace(draggedTab, activeWorkspace, { hasDndSwitch: true });
}
gZenWorkspaces.updateTabsContainers();
}
@@ -761,7 +769,8 @@
draggedTab.hasAttribute("zen-essential") ||
draggedTab.getAttribute("zen-workspace-id") != gZenWorkspaces.activeWorkspace ||
!dropElement.visible ||
!draggedTab.visible
!draggedTab.visible ||
draggedTab.ownerGlobal !== window
) {
return;
}
@@ -850,21 +859,22 @@
handle_dragend(event) {
const dt = event.dataTransfer;
const draggedTab = dt.mozGetDataAt(TAB_DROP_TYPE, 0);
let ownerGlobal = draggedTab?.ownerGlobal;
draggedTab.style.visibility = "";
let currentEssenialContainer = gZenWorkspaces.getCurrentEssentialsContainer();
let currentEssenialContainer = ownerGlobal.gZenWorkspaces.getCurrentEssentialsContainer();
if (currentEssenialContainer?.essentialsPromo) {
currentEssenialContainer.essentialsPromo.remove();
}
// We also call it here to ensure we clear any highlight if the drop happened
// outside of a valid drop target.
gZenFolders.highlightGroupOnDragOver(null);
ownerGlobal.gZenFolders.highlightGroupOnDragOver(null);
this.ZenDragAndDropService.onDragEnd();
super.handle_dragend(event);
this.#removeDragOverBackground();
gZenPinnedTabManager.removeTabContainersDragoverClass();
ownerGlobal.gZenPinnedTabManager.removeTabContainersDragoverClass();
this.#maybeClearVerticalPinnedGridDragOver();
this.originalDragImageArgs = [];
window.removeEventListener("dragover", this.handle_windowDragEnter, { capture: true });
window.removeEventListener("dragenter", this.handle_windowDragEnter, { capture: true });
this.#isOutOfWindow = false;
if (this._browserDragImageWrapper) {
this._browserDragImageWrapper.remove();
@@ -874,6 +884,10 @@
this._tempDragImageParent.remove();
delete this._tempDragImageParent;
}
delete ownerGlobal.gZenCompactModeManager._isTabBeingDragged;
if (dt.dropEffect !== "move") {
ownerGlobal.gZenCompactModeManager._clearAllHoverStates();
}
}
#applyDragOverBackground(element) {
@@ -922,11 +936,13 @@
let dropElementFromEvent = event.target.closest(dropZoneSelector);
dropElement = dropElementFromEvent || dropElement;
if (!dropElementFromEvent) {
let hoveringPeriphery = !!event.target.closest("#tabbrowser-arrowscrollbox-periphery");
let hoveringPeriphery = !!event.target.closest(
":is(#tabbrowser-arrowscrollbox-periphery, .pinned-tabs-container-separator)"
);
if (event.target.classList.contains("zen-workspace-empty-space") || hoveringPeriphery) {
let lastTab = gBrowser.tabs.at(-1);
dropElement =
(hoveringPeriphery
(hoveringPeriphery && Services.prefs.getBoolPref("zen.view.show-newtab-button-top")
? this._tabbrowserTabs.ariaFocusableItems.at(
gBrowser._numVisiblePinTabsWithoutCollapsed
)
@@ -973,11 +989,11 @@
(possibleFolderElement.collapsed ||
possibleFolderElement.childGroupsAndTabs.length < 2)));
if (
(isTabGroupLabel(draggedTab) &&
draggedTab.group?.isZenFolder &&
(isTab(dropElement) || dropElement.hasAttribute("split-view-group")) &&
isTabGroupLabel(draggedTab) &&
draggedTab.group?.isZenFolder &&
(((isTab(dropElement) || dropElement.hasAttribute("split-view-group")) &&
(!dropElement.pinned || dropElement.hasAttribute("zen-essential"))) ||
showIndicatorUnderNewTabButton
showIndicatorUnderNewTabButton)
) {
dropElement = null;
this.clearDragOverVisuals();
@@ -1275,6 +1291,9 @@
return;
}
// eslint-disable-next-line mozilla/valid-services
Services.zen.playHapticFeedback();
dragData.animDropElementIndex = newIndex;
dragData.dropElement = tabs[Math.min(newIndex, tabs.length - 1)];
dragData.dropBefore = newIndex < tabs.length;

View File

@@ -1038,43 +1038,47 @@ class nsZenFolders extends nsZenDOMOperatedFeature {
const tabFolderWorkingData = new Map();
for (const folderData of data) {
const workingData = {
stateData: folderData,
node: null,
containingTabsFragment: document.createDocumentFragment(),
};
tabFolderWorkingData.set(folderData.id, workingData);
try {
const workingData = {
stateData: folderData,
node: null,
containingTabsFragment: document.createDocumentFragment(),
};
tabFolderWorkingData.set(folderData.id, workingData);
const oldGroup = document.getElementById(folderData.id);
folderData.emptyTabIds.forEach((id) => {
oldGroup?.querySelector(`tab[id="${id}"]`)?.setAttribute("zen-empty-tab", true);
});
if (gBrowser.isTabGroup(oldGroup)) {
if (!folderData.splitViewGroup) {
const folder = this._createFolderNode({
id: folderData.id,
label: folderData.name,
collapsed: folderData.collapsed,
pinned: folderData.pinned,
saveOnWindowClose: folderData.saveOnWindowClose,
workspaceId: folderData.workspaceId,
});
folder.setAttribute("id", folderData.id);
workingData.node = folder;
oldGroup.before(folder);
} else {
workingData.node = oldGroup;
}
while (oldGroup.tabs.length) {
const tab = oldGroup.tabs[0];
if (folderData.workspaceId) {
tab.setAttribute("zen-workspace-id", folderData.workspaceId);
const oldGroup = document.getElementById(folderData.id);
folderData.emptyTabIds.forEach((id) => {
oldGroup?.querySelector(`tab[id="${id}"]`)?.setAttribute("zen-empty-tab", true);
});
if (gBrowser.isTabGroup(oldGroup)) {
if (!folderData.splitViewGroup) {
const folder = this._createFolderNode({
id: folderData.id,
label: folderData.name,
collapsed: folderData.collapsed,
pinned: folderData.pinned,
saveOnWindowClose: folderData.saveOnWindowClose,
workspaceId: folderData.workspaceId,
});
folder.setAttribute("id", folderData.id);
workingData.node = folder;
oldGroup.before(folder);
} else {
workingData.node = oldGroup;
}
while (oldGroup.tabs.length) {
const tab = oldGroup.tabs[0];
if (folderData.workspaceId) {
tab.setAttribute("zen-workspace-id", folderData.workspaceId);
}
workingData.containingTabsFragment.appendChild(tab);
}
if (!folderData.splitViewGroup) {
oldGroup.remove();
}
workingData.containingTabsFragment.appendChild(tab);
}
if (!folderData.splitViewGroup) {
oldGroup.remove();
}
} catch (e) {
console.error("Error restoring Zen Folders session data:", e);
}
}

View File

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

View File

@@ -800,6 +800,10 @@ class nsZenKeyboardShortcutsLoader {
continue;
}
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);
}
@@ -1109,7 +1113,7 @@ class nsZenKeyboardShortcutsVersioner {
if (version < 15) {
// 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(
new KeyShortcut(
"zen-new-unsynced-window",

View File

@@ -11,6 +11,7 @@ ChromeUtils.defineESModuleGetters(lazy, {
PrivateBrowsingUtils: "resource://gre/modules/PrivateBrowsingUtils.sys.mjs",
SessionStore: "resource:///modules/sessionstore/SessionStore.sys.mjs",
gWindowSyncEnabled: "resource:///modules/zen/ZenWindowSync.sys.mjs",
gSyncOnlyPinnedTabs: "resource:///modules/zen/ZenWindowSync.sys.mjs",
DeferredTask: "resource://gre/modules/DeferredTask.sys.mjs",
});
@@ -84,6 +85,7 @@ export class nsZenSessionManager {
compression: "lz4",
backupFile,
});
this.log("Session file path:", this.#file.path);
this.#deferredBackupTask = new lazy.DeferredTask(async () => {
await this.#createBackupsIfNeeded();
}, REGENERATION_DEBOUNCE_RATE_MS);
@@ -150,6 +152,34 @@ export class nsZenSessionManager {
folderIcon: row.getResultByName("folder_icon"),
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;
} catch {
/* ignore errors during migration */
@@ -165,6 +195,7 @@ export class nsZenSessionManager {
async readFile() {
let fileExists = await IOUtils.exists(this.#storeFilePath);
if (!fileExists) {
this.log("Session file does not exist, running migration", this.#storeFilePath);
this._shouldRunMigration = true;
}
this.init();
@@ -181,6 +212,7 @@ export class nsZenSessionManager {
}
this.#sidebar = this.#file.data || {};
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
// to restore them from the database. Note we also do a
// check if we already planned to run migration for optimization.
@@ -189,6 +221,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
* into all windows.
@@ -197,9 +236,6 @@ export class nsZenSessionManager {
* The initial session state read from the session file.
*/
onFileRead(initialState) {
if (!lazy.gWindowSyncEnabled) {
return initialState;
}
// For the first time after migration, we restore the tabs
// That where going to be restored by SessionStore. The sidebar
// object will always be empty after migration because we haven't
@@ -207,6 +243,16 @@ export class nsZenSessionManager {
if (this._shouldRunMigration) {
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,
// firefox would create simply a new empty window, but we want
// to make sure that the sidebar object is properly initialized.
@@ -223,10 +269,7 @@ export class nsZenSessionManager {
}
// When we don't have browser.startup.page set to resume session,
// we only want to restore the pinned tabs into the new windows.
const shouldRestoreOnlyPinned =
Services.prefs.getIntPref("browser.startup.page", 1) !== BROWSER_STARTUP_RESUME_SESSION ||
lazy.PrivateBrowsingUtils.permanentPrivateBrowsing;
if (shouldRestoreOnlyPinned && this.#sidebar?.tabs) {
if (this.#shouldRestoreOnlyPinned && this.#sidebar?.tabs) {
this.log("Restoring only pinned tabs into windows");
const sidebar = this.#sidebar;
sidebar.tabs = (sidebar.tabs || []).filter((tab) => tab.pinned);
@@ -253,9 +296,9 @@ export class nsZenSessionManager {
}
this.#restoreWindowData(winData);
}
} else {
} else if (initialState) {
this.log("Saving windata state after migration");
this.saveState(initialState);
this.saveState(Cu.cloneInto(initialState, {}));
}
delete this._shouldRunMigration;
return initialState;
@@ -276,8 +319,19 @@ export class nsZenSessionManager {
* @param {object} initialState
* The initial session state read from the session file.
*/
// eslint-disable-next-line complexity
#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
// have any yet.
if (!this.#sidebar.spaces?.length) {
@@ -286,6 +340,12 @@ export class nsZenSessionManager {
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
// initial state, for example if the user had 'restore previous
// session' disabled before migration. In that case, we try
@@ -321,9 +381,6 @@ export class nsZenSessionManager {
}
}
}
// Save the state to the sidebar object so that it gets written
// to the session file.
delete this._migrationData;
return initialState;
}
@@ -345,7 +402,7 @@ export class nsZenSessionManager {
saveState(state) {
let windows = state?.windows || [];
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
// browsing mode. We also don't want to save if there are no windows.
return;
@@ -506,10 +563,31 @@ export class nsZenSessionManager {
if (!sidebar) {
return;
}
aWindowData.tabs = sidebar.tabs || [];
aWindowData.splitViewData = sidebar.splitViewData;
// If we should only sync the pinned tabs, we should only edit the unpinned
// tabs in the window data and keep the pinned tabs from the window data,
// as they should be the same as the ones in the sidebar.
if (lazy.gSyncOnlyPinnedTabs) {
let pinnedTabs = (sidebar.tabs || []).filter((tab) => tab.pinned);
let unpinedWindowTabs = (aWindowData.tabs || []).filter((tab) => !tab.pinned);
aWindowData.tabs = [...pinnedTabs, ...unpinedWindowTabs];
// We restore ALL the split view data in the sidebar, if the group doesn't exist in the window,
// it should be a no-op anyways.
aWindowData.splitViewData = [
...(sidebar.splitViewData || []),
...(aWindowData.splitViewData || []),
];
// Same thing with groups, we restore all the groups from the sidebar, if they don't have any
// existing tabs in the window, they should be a no-op.
aWindowData.groups = [...(sidebar.groups || []), ...(aWindowData.groups || [])];
} else {
aWindowData.tabs = sidebar.tabs || [];
aWindowData.splitViewData = sidebar.splitViewData;
aWindowData.groups = sidebar.groups;
}
// Folders are always pinned, so we dont need to check for the pinned state here.
aWindowData.folders = sidebar.folders;
aWindowData.groups = sidebar.groups;
aWindowData.spaces = sidebar.spaces;
}
@@ -525,7 +603,7 @@ export class nsZenSessionManager {
* Whether this new window is being restored from a closed window.
*/
restoreNewWindow(aWindow, SessionStoreInternal, fromClosedWindow = false) {
if (aWindow.gZenWorkspaces?.privateWindowOrDisabled || !lazy.gWindowSyncEnabled) {
if (aWindow.gZenWorkspaces?.privateWindowOrDisabled) {
return;
}
this.log("Restoring new window with Zen session data");
@@ -543,6 +621,11 @@ export class nsZenSessionManager {
this.#restoreWindowData(newWindow);
}
newWindow.tabs = this.#filterUnusedTabs(newWindow.tabs || []);
if (!lazy.gWindowSyncEnabled || lazy.gSyncOnlyPinnedTabs) {
// Don't bring over any unpinned tabs if window sync is disabled or if syncing only pinned tabs.
newWindow.tabs = newWindow.tabs.filter((tab) => tab.pinned);
newWindow.groups = newWindow.groups?.filter((group) => group.pinned);
}
// These are window-specific from the previous window state that
// we don't want to restore into the new window. Otherwise, new

View File

@@ -15,9 +15,16 @@ ChromeUtils.defineESModuleGetters(lazy, {
ZenSessionStore: "resource:///modules/zen/ZenSessionManager.sys.mjs",
TabStateCache: "resource:///modules/sessionstore/TabStateCache.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,
"gSyncOnlyPinnedTabs",
"zen.window-sync.sync-only-pinned-tabs",
true
);
XPCOMUtils.defineLazyPreferenceGetter(lazy, "gShouldLog", "zen.window-sync.log", true);
const OBSERVING = ["browser-window-before-show", "sessionstore-windows-restored"];
@@ -140,7 +147,7 @@ class nsZenWindowSync {
}
init() {
if (!lazy.gWindowSyncEnabled || this.#initialized) {
if (this.#initialized) {
return;
}
this.#initialized = true;
@@ -189,6 +196,10 @@ class nsZenWindowSync {
// to avoid confusing the old private window behavior.
let forcedSync = !aWindow.gZenWorkspaces?.privateWindowOrDisabled;
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") {
forcedSync = true;
} else if (aWindow._zenStartupSyncFlag === "unsynced") {
@@ -236,6 +247,9 @@ class nsZenWindowSync {
if (tab.pinned && !tab._zenPinnedInitialState) {
await this.setPinnedTabState(tab);
}
if (!lazy.gWindowSyncEnabled || (lazy.gSyncOnlyPinnedTabs && !tab.pinned)) {
tab._zenContentsVisible = true;
}
}
});
}
@@ -309,6 +323,9 @@ class nsZenWindowSync {
) {
return;
}
if (!lazy.gWindowSyncEnabled && !UNSYNCED_WINDOW_EVENTS.includes(aEvent.type)) {
return;
}
if (INSTANT_EVENTS.includes(aEvent.type)) {
this.#handleNextEvent(aEvent);
return;
@@ -514,7 +531,11 @@ class nsZenWindowSync {
*/
#moveItemToMatchOriginal(aOriginalItem, aTargetItem, aWindow, { isEssential, isPinned }) {
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;
if (gBrowser.isTabGroup(originalSibling) || gBrowser.isTab(originalSibling)) {
isFirstTab =
@@ -938,6 +959,9 @@ class nsZenWindowSync {
*/
#delegateGenericSyncEvent(aEvent, flags = 0) {
const item = aEvent.target;
if (lazy.gSyncOnlyPinnedTabs && !item.pinned) {
return;
}
this.#syncItemForAllWindows(item, flags);
}
@@ -1074,17 +1098,20 @@ class nsZenWindowSync {
/* Mark: Event Handlers */
on_TabOpen(aEvent) {
on_TabOpen(aEvent, { duringPinning = false } = {}) {
const tab = aEvent.target;
const window = tab.ownerGlobal;
const isUnsyncedWindow = window.gZenWorkspaces.privateWindowOrDisabled;
if (tab.id) {
if (tab.id && !duringPinning) {
// This tab was opened as part of a sync operation.
return;
}
tab._zenContentsVisible = true;
tab.id = this.#newTabSyncId;
if (isUnsyncedWindow) {
if (lazy.gSyncOnlyPinnedTabs && !tab.pinned) {
return;
}
if (isUnsyncedWindow || !lazy.gWindowSyncEnabled) {
return;
}
this.#runOnAllWindows(window, (win) => {
@@ -1101,6 +1128,9 @@ class nsZenWindowSync {
SYNC_FLAG_ICON | SYNC_FLAG_LABEL | SYNC_FLAG_MOVE
);
});
if (duringPinning && tab?.splitView) {
this.on_ZenSplitViewTabsSplit({ target: tab.group });
}
this.#maybeFlushTabState(tab);
}
@@ -1122,7 +1152,8 @@ class nsZenWindowSync {
}
on_TabMove(aEvent) {
return this.#delegateGenericSyncEvent(aEvent, SYNC_FLAG_MOVE);
this.#delegateGenericSyncEvent(aEvent, SYNC_FLAG_MOVE);
return Promise.resolve();
}
on_TabPinned(aEvent) {
@@ -1134,7 +1165,14 @@ class nsZenWindowSync {
if (!tab._zenPinnedInitialState) {
tabStatePromise = this.setPinnedTabState(tab);
}
return Promise.all([tabStatePromise, this.on_TabMove(aEvent)]);
return Promise.all([
tabStatePromise,
this.on_TabMove(aEvent).then(() => {
if (lazy.gSyncOnlyPinnedTabs) {
this.on_TabOpen({ target: tab }, { duringPinning: true });
}
}),
]);
}
on_TabUnpinned(aEvent) {
@@ -1145,7 +1183,11 @@ class nsZenWindowSync {
delete targetTab._zenPinnedInitialState;
}
});
return this.on_TabMove(aEvent);
return this.on_TabMove(aEvent).then(() => {
if (lazy.gSyncOnlyPinnedTabs) {
this.on_TabClose({ target: tab });
}
});
}
on_TabAddedToEssentials(aEvent) {
@@ -1168,6 +1210,9 @@ class nsZenWindowSync {
}
on_focus(aEvent) {
if (typeof aEvent.target !== "object") {
return;
}
const { ownerGlobal: window } = aEvent.target;
if (
!window?.gBrowser ||
@@ -1333,4 +1378,6 @@ class nsZenWindowSync {
// eslint-disable-next-line mozilla/valid-lazy
export const gWindowSyncEnabled = lazy.gWindowSyncEnabled;
// eslint-disable-next-line mozilla/valid-lazy
export const gSyncOnlyPinnedTabs = lazy.gSyncOnlyPinnedTabs;
export const ZenWindowSync = new nsZenWindowSync();

View File

@@ -1386,10 +1386,10 @@ class nsZenViewSplitter extends nsZenDOMOperatedFeature {
new nsSplitLeafNode(tabs[i], 50),
new nsSplitLeafNode(tabs[i + 1], 50),
];
rootNode.addChild(columnNode);
rootNode.addChild(columnNode, false);
}
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,45 +2093,53 @@ class nsZenViewSplitter extends nsZenDOMOperatedFeature {
this._sessionRestoring = true;
for (const groupData of data) {
const group = document.getElementById(groupData.groupId);
if (!gBrowser.isTabGroup(group)) {
continue;
}
// Backwards compatibility
group.setAttribute("split-view-group", "true");
if (!groupData?.layoutTree) {
this.splitTabs(group.tabs, group.gridType);
delete this._sessionRestoring;
return;
}
const deserializeNode = (nodeData) => {
if (nodeData.type === "leaf") {
const tab = document.getElementById(nodeData.tabId);
if (!tab) {
return null;
}
return new nsSplitLeafNode(tab, nodeData.sizeInParent);
try {
const group = document.getElementById(groupData.groupId);
if (!gBrowser.isTabGroup(group)) {
continue;
}
const splitter = new nsSplitNode(nodeData.direction, nodeData.sizeInParent);
splitter._children = [];
for (const childData of nodeData.children) {
const childNode = deserializeNode(childData);
if (childNode) {
childNode.parent = splitter;
splitter._children.push(childNode);
}
// Backwards compatibility
group.setAttribute("split-view-group", "true");
if (!groupData?.layoutTree) {
this.splitTabs(group.tabs, group.gridType);
delete this._sessionRestoring;
return;
}
return splitter;
};
const deserializeNode = (nodeData) => {
if (nodeData.type === "leaf") {
const tab = document.getElementById(nodeData.tabId);
if (!tab) {
return null;
}
return new nsSplitLeafNode(tab, nodeData.sizeInParent);
}
const layout = deserializeNode(groupData.layoutTree);
const splitData = this.splitTabs(group.tabs, groupData.gridType, -1);
splitData.layoutTree = layout;
const splitter = new nsSplitNode(nodeData.direction, nodeData.sizeInParent);
splitter._children = [];
for (const childData of nodeData.children) {
const childNode = deserializeNode(childData);
if (childNode) {
childNode.parent = splitter;
splitter._children.push(childNode);
}
}
return splitter;
};
const layout = deserializeNode(groupData.layoutTree);
const splitData = this.splitTabs(group.tabs, groupData.gridType, -1);
if (splitData) {
splitData.layoutTree = layout;
} else {
gBrowser.removeTabGroup(group);
}
} catch (e) {
console.error("Error restoring split view session data:", e);
}
}
delete this._sessionRestoring;

View File

@@ -76,6 +76,17 @@ class nsZenPinnedTabManager extends nsZenDOMOperatedFeature {
this._zenClickEventListener = this._onTabClick.bind(this);
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) {
@@ -130,6 +141,7 @@ class nsZenPinnedTabManager extends nsZenDOMOperatedFeature {
tab.removeEventListener("click", tab._zenClickEventListener);
delete tab._zenClickEventListener;
}
this.resetPinChangedUrl(tab);
break;
default:
console.warn("ZenPinnedTabManager: Unhandled tab event", action);
@@ -162,7 +174,7 @@ class nsZenPinnedTabManager extends nsZenDOMOperatedFeature {
this._resetTabToStoredState(tab);
}
async replacePinnedUrlWithCurrent(tab = undefined) {
replacePinnedUrlWithCurrent(tab = undefined) {
tab ??= TabContextMenu.contextTab;
if (!tab || !tab.pinned) {
return;
@@ -547,13 +559,50 @@ class nsZenPinnedTabManager extends nsZenDOMOperatedFeature {
}
// eslint-disable-next-line complexity
moveToAnotherTabContainerIfNecessary(event, movingTabs) {
if (!this.enabled) {
return false;
moveToAnotherTabContainerIfNecessary(event, draggedTab, movingTabs, dropIndex) {
let newIndex = dropIndex;
let fromDifferentWindow = false;
movingTabs = Array.from(movingTabs || draggedTab)
.reverse()
.map((tab) => {
if (!gBrowser.isTab(tab)) {
return 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]
);
}
movingTabs = movingTabs.map((tab) => {
return tab.ownerGlobal !== window ? gBrowser.adoptTab(tab) : tab;
});
try {
const pinnedTabsTarget = event.target.closest(
":is(.zen-current-workspace-indicator, .zen-workspace-pinned-tabs-section)"
@@ -566,8 +615,8 @@ class nsZenPinnedTabManager extends nsZenDOMOperatedFeature {
}
movingTabs = movingTabs.filter((tab) =>
gBrowser.isTabGroupLabel(tab)
? tab.group?.isZenFolder && !tabsTarget && !essentialTabsTarget
gBrowser.isTabGroupLabel(tab) && tab.group?.isZenFolder
? !tabsTarget && !essentialTabsTarget
: true
);
@@ -575,9 +624,9 @@ class nsZenPinnedTabManager extends nsZenDOMOperatedFeature {
// Remove group labels from the moving tabs and replace it
// with the sub tabs
for (let i = 0; i < movingTabs.length; i++) {
const draggedTab = movingTabs[i];
if (gBrowser.isTabGroupLabel(draggedTab)) {
const group = draggedTab.group;
const tab = movingTabs[i];
if (gBrowser.isTabGroupLabel(tab)) {
const group = tab.group;
// remove label and add sub tabs to moving tabs
if (group) {
movingTabs.splice(i, 1, ...group.tabs);
@@ -588,32 +637,32 @@ class nsZenPinnedTabManager extends nsZenDOMOperatedFeature {
let isVertical = this.expandedSidebarMode;
let moved = false;
let hasActuallyMoved;
for (const draggedTab of movingTabs) {
for (const tab of movingTabs) {
let isRegularTabs = false;
// Check for essentials container
if (essentialTabsTarget) {
if (!draggedTab.hasAttribute("zen-essential") && !draggedTab?.group) {
if (!tab.hasAttribute("zen-essential") && !tab?.group?.hasAttribute("split-view-group")) {
moved = true;
isVertical = false;
hasActuallyMoved = this.addToEssentials(draggedTab);
hasActuallyMoved = this.addToEssentials(tab);
}
}
// Check for pinned tabs container
else if (pinnedTabsTarget) {
if (!draggedTab.pinned) {
gBrowser.pinTab(draggedTab);
} else if (draggedTab.hasAttribute("zen-essential")) {
this.removeEssentials(draggedTab, false);
if (!tab.pinned) {
gBrowser.pinTab(tab);
} else if (tab.hasAttribute("zen-essential")) {
this.removeEssentials(tab, false);
moved = true;
}
}
// Check for normal tabs container
else if (tabsTarget || event.target.id === "zen-tabs-wrapper") {
if (draggedTab.pinned && !draggedTab.hasAttribute("zen-essential")) {
gBrowser.unpinTab(draggedTab);
if (tab.pinned && !tab.hasAttribute("zen-essential")) {
gBrowser.unpinTab(tab);
isRegularTabs = true;
} else if (draggedTab.hasAttribute("zen-essential")) {
this.removeEssentials(draggedTab);
} else if (tab.hasAttribute("zen-essential")) {
this.removeEssentials(tab);
moved = true;
isRegularTabs = true;
}
@@ -654,7 +703,7 @@ class nsZenPinnedTabManager extends nsZenDOMOperatedFeature {
elementIndex++;
}
gBrowser.moveTabTo(draggedTab, {
gBrowser.moveTabTo(tab, {
elementIndex,
forceUngrouped: targetElem?.group?.collapsed !== false,
});

View File

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

View File

@@ -682,6 +682,13 @@ async function testFileAccessWindowsOnly() {
let tests = [];
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({
desc: "per-user extensions dir",
ok: true,

View File

@@ -22,6 +22,13 @@ add_setup(async function setup() {
const xdgConfigHome = Services.env.get("XDG_CONFIG_HOME");
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
sanityChecks();
});

View File

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

View File

@@ -12,12 +12,17 @@ support-files = [
"browser_content_sandbox_utils.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 = [
"XDG_CONFIG_HOME=/tmp/.xdg_config_home_test",
"HOME=/tmp/.xdg_mozLegacyHome_test",
"MOZ_LEGACY_HOME=1",
]
profile-path = "/tmp/.xdg_mozLegacyHome_test/.mozilla/firefox/xdg_mozLegacyHome_profile"
["browser_content_sandbox_fs_xdg_mozLegacyHome.js"]
run-if = ["os == 'linux'"]

View File

@@ -11,11 +11,15 @@ support-files = [
"browser_content_sandbox_utils.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 = [
"XDG_CONFIG_HOME=/tmp/.xdg_config_home_test",
"MOZ_LEGACY_HOME=0",
]
profile-path = "/tmp/.xdg_config_home_test/mozilla/firefox/xdg_config_home_profile"
["browser_content_sandbox_fs_xdg_xdgConfigHome.js"]
run-if = [

View File

@@ -1348,7 +1348,8 @@ export class nsZenThemePicker extends nsZenMultiWindowFeature {
}
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) {

View File

@@ -6,6 +6,12 @@
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
* and user interactions but it also contains some logic to manage
@@ -801,7 +807,7 @@ class nsZenWorkspaces {
chromeFlags & Ci.nsIWebBrowserChrome.CHROME_MENUBAR;
return this._shouldHaveWorkspaces;
}
return this._shouldHaveWorkspaces;
return this._shouldHaveWorkspaces && !document.documentElement.hasAttribute("taskbartab");
}
get isPrivateWindow() {
@@ -888,6 +894,13 @@ class nsZenWorkspaces {
return Promise.resolve();
}
const spacesFromStore = aWinData.spaces || [];
if (
!this.privateWindowOrDisabled &&
spacesFromStore.length === 0 &&
lazy.ZenSessionStore._migrationData
) {
spacesFromStore.push(...lazy.ZenSessionStore._migrationData.spaces);
}
this._workspaceCache = spacesFromStore.length
? [...spacesFromStore]
: [this.#createWorkspaceData("Space", undefined)];
@@ -1031,11 +1044,17 @@ class nsZenWorkspaces {
delete this._initialTab;
}
if (gZenVerticalTabsManager._canReplaceNewTab && showed) {
BrowserCommands.openTab();
} else if (!showed) {
gBrowser.selectedBrowser.focus();
}
// 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) {
BrowserCommands.openTab();
} else if (!showed) {
gBrowser.selectedBrowser.focus();
}
});
});
if (
!gZenVerticalTabsManager._canReplaceNewTab &&

View File

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