mirror of
https://github.com/zen-browser/desktop.git
synced 2026-02-07 12:27:14 +00:00
Compare commits
63 Commits
1.18.1b
...
chore/7402
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4869e25df3 | ||
|
|
cc4b51529e | ||
|
|
c9474cecc0 | ||
|
|
531be839c9 | ||
|
|
226486b973 | ||
|
|
5a137c95e5 | ||
|
|
e6154ceb99 | ||
|
|
1ea5d2fa6f | ||
|
|
97d5ebc21e | ||
|
|
442ec2a5d1 | ||
|
|
43ae672b44 | ||
|
|
84a54c9dbb | ||
|
|
6c53c3bf37 | ||
|
|
66686ab7f8 | ||
|
|
0c684a9bdb | ||
|
|
26dabffb96 | ||
|
|
ead077d16e | ||
|
|
a72fa3f79e | ||
|
|
33846dbce0 | ||
|
|
32fffaabe7 | ||
|
|
bf96b512cb | ||
|
|
32a42e797c | ||
|
|
29b8555c66 | ||
|
|
ab7698b16f | ||
|
|
cd0ef01fa1 | ||
|
|
41d97ddd21 | ||
|
|
a4386de00d | ||
|
|
28a2e8697a | ||
|
|
2ae623b15c | ||
|
|
8e7ce1c12b | ||
|
|
b5efe62739 | ||
|
|
e34ed3e882 | ||
|
|
658e35ebde | ||
|
|
1176f5ac8b | ||
|
|
4de01a9bc9 | ||
|
|
35a9a9ea2a | ||
|
|
e78e2488ff | ||
|
|
1c23ad92b3 | ||
|
|
32ba6ef81b | ||
|
|
a8559f84c1 | ||
|
|
0e07f65bc0 | ||
|
|
4046dd01a1 | ||
|
|
e51592898e | ||
|
|
9afbd1befd | ||
|
|
ccc1e998da | ||
|
|
3a51b36a05 | ||
|
|
e05cb0e0dc | ||
|
|
a892721306 | ||
|
|
950f6dfb66 | ||
|
|
9b6937650d | ||
|
|
2c63376782 | ||
|
|
f5356dbcb6 | ||
|
|
45ecacfb04 | ||
|
|
4327684f9f | ||
|
|
8997a24996 | ||
|
|
5a6a565b0f | ||
|
|
d39fff2e4a | ||
|
|
ab12e72cc5 | ||
|
|
8a2e015048 | ||
|
|
83de087b0b | ||
|
|
5dea28a3cb | ||
|
|
956841a76e | ||
|
|
3f03ffb27b |
17
.github/workflows/sync-upstream.yml
vendored
17
.github/workflows/sync-upstream.yml
vendored
@@ -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'
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -1 +1 @@
|
||||
783b222b1b93fb9e8c52eb57558ef7f07bca6e7e
|
||||
b1e00b74d3791a5a7bbd6ba3d32b69b60471e73b
|
||||
262
docs/issue-metrics/2026_2026-01-01..2026-01-31.md
Normal file
262
docs/issue-metrics/2026_2026-01-01..2026-01-31.md
Normal 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 Windows 11 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 doesn’t close automatically after creating a new tab in Compact Mode | https://github.com/zen-browser/desktop/issues/12036 | 2 days, 6:04:10 | None |
|
||||
| The extension items in the context menu multiplying with every right click | https://github.com/zen-browser/desktop/issues/12035 | 3:50:26 | None |
|
||||
| Disabling zen.window-sync.enabled breaks "Open previous windows and tabs" | https://github.com/zen-browser/desktop/issues/12034 | 4:38:30 | 6:11:16 |
|
||||
| Tab cannot be grabbed and taken into a different Zen browser instance | https://github.com/zen-browser/desktop/issues/12032 | 0:11:57 | 1:21:44 |
|
||||
| Window sync with zoom | https://github.com/zen-browser/desktop/issues/12031 | 3:33:29 | 1 day, 17:09:02 |
|
||||
| New Window doesn't work with window sync disabled. | https://github.com/zen-browser/desktop/issues/12030 | None | 1:21:07 |
|
||||
| Move to space not listed in context menu | https://github.com/zen-browser/desktop/issues/12029 | 1:28:17 | 1:28:17 |
|
||||
| All my workspaces and tabs just gone after update, wtf ? :) | https://github.com/zen-browser/desktop/issues/12028 | 0:31:31 | 1:41:41 |
|
||||
| Global menu show but unresponsive. | https://github.com/zen-browser/desktop/issues/12024 | 0:06:03 | 6 days, 1:49:53 |
|
||||
| Debian 13 | Passkey doesn't show QR code | https://github.com/zen-browser/desktop/issues/12022 | 10:08:54 | None |
|
||||
| Performance: Swiping across spaces with multiple tabs open is laggy | https://github.com/zen-browser/desktop/issues/12020 | 0:09:27 | 0:09:27 |
|
||||
| Move to Space | https://github.com/zen-browser/desktop/issues/12019 | 0:08:00 | 0:08:00 |
|
||||
| [UI Error] Zen Browser Settings UI Error | https://github.com/zen-browser/desktop/issues/12014 | 0:41:54 | 6:44:05 |
|
||||
| Full-Screen PIP Mode Retains Dimmed State Indefinitely Due to Hover and System Inactivity | https://github.com/zen-browser/desktop/issues/12013 | None | None |
|
||||
| "Check for Updates" Not Working | https://github.com/zen-browser/desktop/issues/12012 | 1:54:04 | 1:54:09 |
|
||||
| Website lolalytics.com not working properly after updating to 1.18.1b | https://github.com/zen-browser/desktop/issues/12011 | 10:35:46 | 11:32:35 |
|
||||
| No "Open a new Blank Window" action when right-clicking zen on taskbar | https://github.com/zen-browser/desktop/issues/12010 | 9:50:45 | None |
|
||||
| Inconsistant capitalization in application menu | https://github.com/zen-browser/desktop/issues/12009 | None | 0:15:37 |
|
||||
| Disable window/tab sync by default | https://github.com/zen-browser/desktop/issues/12008 | 0:03:34 | 17:22:46 |
|
||||
| Sync not working + pinned tabs do not resert url | https://github.com/zen-browser/desktop/issues/12006 | 0:15:54 | 7:59:09 |
|
||||
| Some UI elements not renderring correctly | https://github.com/zen-browser/desktop/issues/12005 | 3:40:46 | 4:36:15 |
|
||||
| installer prolbem | https://github.com/zen-browser/desktop/issues/12004 | 2:13:28 | 2:13:28 |
|
||||
| Issues with Sidebar Dragging Exiting Full-Screen & Legacy Ctrl+Tab Behavior | https://github.com/zen-browser/desktop/issues/12003 | 4:33:38 | None |
|
||||
| Cannot Rename “New Folder” in the Sidebar | https://github.com/zen-browser/desktop/issues/12002 | 0:58:42 | 1:48:21 |
|
||||
| Custom font doesn't work | https://github.com/zen-browser/desktop/issues/12001 | 1 day, 8:53:16 | 1 day, 8:53:16 |
|
||||
| Windows accent coloring issue with zen | https://github.com/zen-browser/desktop/issues/12000 | 1:11:28 | 1:11:28 |
|
||||
| Disabling zen.window-sync.enabled breaks new zen instances | https://github.com/zen-browser/desktop/issues/11999 | 4:34:06 | 22:44:50 |
|
||||
| Pinned tabs don't scale: hundreds of pins freeze browser | https://github.com/zen-browser/desktop/issues/11997 | 6:50:35 | 1 day, 13:33:03 |
|
||||
| All tabs are gone (also pinned) when updating to 1.18b | https://github.com/zen-browser/desktop/issues/11994 | 4:42:08 | None |
|
||||
| "blank window" at startup | https://github.com/zen-browser/desktop/issues/11993 | 0:02:32 | 0:52:40 |
|
||||
| Crashing when playing WASMGC game | https://github.com/zen-browser/desktop/issues/11990 | 0:31:55 | None |
|
||||
| Pinned Tabs disappearing/invisible | https://github.com/zen-browser/desktop/issues/11989 | 11:31:45 | 11:31:45 |
|
||||
| Zen process opens but the window doesn't | https://github.com/zen-browser/desktop/issues/11985 | 0:22:24 | None |
|
||||
| Zen has recently got really inconsistent performance (especially after the last few updates). | https://github.com/zen-browser/desktop/issues/11982 | 0:52:04 | None |
|
||||
| Twitch.tv Video Streams Not Loading | https://github.com/zen-browser/desktop/issues/11980 | 0:19:27 | None |
|
||||
| Page rendering is blank white | https://github.com/zen-browser/desktop/issues/11979 | 15:04:14 | 15:04:14 |
|
||||
| Zen is unusable on Cosmic Desktop Environment (unable to remove a checkbox that spawns and hinders using the browser) | https://github.com/zen-browser/desktop/issues/11978 | 0:42:40 | 17:46:00 |
|
||||
| Searching with # is not searching bookmarks by tag or title | https://github.com/zen-browser/desktop/issues/11976 | 1:54:07 | 11:45:13 |
|
||||
| Conflict Between Browser Page Search Shortcut and Confluence Search | https://github.com/zen-browser/desktop/issues/11975 | None | None |
|
||||
| Updater repeatedly reinstalls latest twilight build despite no version change. | https://github.com/zen-browser/desktop/issues/11974 | 0:19:47 | 6:53:06 |
|
||||
| Randomly Control button stop functioning | https://github.com/zen-browser/desktop/issues/11972 | None | None |
|
||||
| Low refresh rate on Zen Windows version after OS update | https://github.com/zen-browser/desktop/issues/11967 | 21:19:01 | None |
|
||||
| Switching workspaces to a split view will cause the area surround the view to turn black for a second | https://github.com/zen-browser/desktop/issues/11965 | 17:19:30 | None |
|
||||
| [Bug] Previous session permanently lost after closing and reopening Zen Browser | https://github.com/zen-browser/desktop/issues/11964 | 4:00:54 | 4:01:24 |
|
||||
| Closing a normal zen window when an incognito zen browser is opened, removes all the tabs across all my workspaces. | https://github.com/zen-browser/desktop/issues/11963 | 2:10:13 | 2:10:13 |
|
||||
| Only sidebar layout -- Always show bookmarks tool bar + window buttons | https://github.com/zen-browser/desktop/issues/11962 | 0:06:53 | 3:10:47 |
|
||||
| Zen randomly crashes on macOS | https://github.com/zen-browser/desktop/issues/11958 | 3:36:36 | None |
|
||||
| Essentials and pinned tabs don't load automatically on open | https://github.com/zen-browser/desktop/issues/11957 | 12:57:52 | 12:57:52 |
|
||||
| Readme reports Firefox 147.0.1 for Release but latest release 1.17.15b (2025-12-20) is 146.0.1 | https://github.com/zen-browser/desktop/issues/11952 | 8:47:04 | 8:47:03 |
|
||||
| Non-default container indicator not showing in workspace | https://github.com/zen-browser/desktop/issues/11951 | 0:13:01 | None |
|
||||
| Zen not displaying websites on Intel HD graphics 2000 | https://github.com/zen-browser/desktop/issues/11950 | None | None |
|
||||
| Private window tabs are mirrored in the main (non-private) window | https://github.com/zen-browser/desktop/issues/11949 | 2:34:54 | 4:47:55 |
|
||||
| Media session metadata (title/artist/cover) does not update on site without page refresh | https://github.com/zen-browser/desktop/issues/11948 | 6:32:56 | 1 day, 6:51:54 |
|
||||
| Nvidia overlay "Plugin-container is preventing the desktop capture" | https://github.com/zen-browser/desktop/issues/11947 | None | None |
|
||||
| Login to self-hosted Bitwarden fails after initialization in multi-account setting | https://github.com/zen-browser/desktop/issues/11946 | 1 day, 14:57:08 | None |
|
||||
| Accessing any URL under bitbucket.org returns 404 | https://github.com/zen-browser/desktop/issues/11944 | 2:26:35 | 1 day, 20:58:15 |
|
||||
| Acrylic turns grey | https://github.com/zen-browser/desktop/issues/11937 | 0:01:44 | None |
|
||||
| lang change | https://github.com/zen-browser/desktop/issues/11934 | 2:27:46 | 3:29:15 |
|
||||
| MX Master 3 Forward/Back mouse buttons don't work if zen.workspaces.swipe-actions is false | https://github.com/zen-browser/desktop/issues/11923 | 1:53:09 | 1:53:09 |
|
||||
| Tabs UI bug | https://github.com/zen-browser/desktop/issues/11922 | None | None |
|
||||
| Positioning of titlebar window control buttons | https://github.com/zen-browser/desktop/issues/11918 | 11:28:41 | 11:28:41 |
|
||||
| Zen won't follow XDG base directories | https://github.com/zen-browser/desktop/issues/11917 | 12:43:08 | None |
|
||||
| Titlebar expands on hover even if Titlebar setting is Disabled from "Configure Toolbar" in Sidebar only mode of look and feel. | https://github.com/zen-browser/desktop/issues/11915 | None | None |
|
||||
| Multiple window sessions result in same tabs open in all windows | https://github.com/zen-browser/desktop/issues/11914 | 1 day, 1:41:36 | 1 day, 1:41:36 |
|
||||
| Misplaced Tab (Placed a tab above the new tab button but below the line that separates the pinned tabs) | https://github.com/zen-browser/desktop/issues/11911 | None | 4:09:21 |
|
||||
| Sidebar width inconsistency | https://github.com/zen-browser/desktop/issues/11909 | None | None |
|
||||
| Cannot expand / fullscreen twitter videos | https://github.com/zen-browser/desktop/issues/11908 | 2 days, 5:35:23 | 2 days, 5:35:23 |
|
||||
| Menu shows unsecure connections as secure | https://github.com/zen-browser/desktop/issues/11905 | 2:21:24 | 3:35:25 |
|
||||
| Top Toolbar appearing when using shortcut "Toggle Sidebar's Width" | https://github.com/zen-browser/desktop/issues/11903 | 5:08:25 | 5:08:25 |
|
||||
| Only shows default icons for Google Messages for web | https://github.com/zen-browser/desktop/issues/11902 | None | 2:39:30 |
|
||||
| The default section disappear from dot list at the below of the tab when swiching spaces | https://github.com/zen-browser/desktop/issues/11901 | 0:50:18 | None |
|
||||
| Context menu partially hidden when right-clicking on a Bookmarks folder in the toolbar | https://github.com/zen-browser/desktop/issues/11898 | None | None |
|
||||
| Refined Github(extension): Issues interface with notification header flickers / flashes | https://github.com/zen-browser/desktop/issues/11896 | None | None |
|
||||
| Glance should work only for links | https://github.com/zen-browser/desktop/issues/11895 | None | 7:53:12 |
|
||||
| Auto Unload Does Not And Has Never Unloaded a Single Tab Ever. | https://github.com/zen-browser/desktop/issues/11894 | None | 6:58:48 |
|
||||
| Visual Bug: Line through sidebar and settings page | https://github.com/zen-browser/desktop/issues/11893 | None | 12:24:36 |
|
||||
| 1password integration - not working | https://github.com/zen-browser/desktop/issues/11892 | 2:39:46 | 13:40:23 |
|
||||
| Hardware acceleration worse on Zen vs others (CachyOS - NVIDIA - Wayland) | https://github.com/zen-browser/desktop/issues/11890 | 2:18:58 | 8:44:12 |
|
||||
| Some tabs (inside a folder) are not drawn in the sidebar | https://github.com/zen-browser/desktop/issues/11888 | 18:13:05 | 18:13:05 |
|
||||
| (macos) (twilight) pinning splitview tabs in folders causes addl tab group labels on restart/update | https://github.com/zen-browser/desktop/issues/11887 | None | 23:27:16 |
|
||||
| How can I achieve window transparency on Windows (so that I can see through to the windows or desktop behind it)?/如何实现Windows下窗口透明化(可以看到后面的窗口或桌面) | https://github.com/zen-browser/desktop/issues/11885 | 11:12:00 | 11:12:00 |
|
||||
| Form validation checkbox message is white text on white background | https://github.com/zen-browser/desktop/issues/11884 | None | None |
|
||||
| Fullscreen with F11 doesn't work as intended | https://github.com/zen-browser/desktop/issues/11883 | 6:30:42 | 6:30:46 |
|
||||
| PiP window stays open empty and buttons don’t 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 doesn’t 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`
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 =
|
||||
|
||||
@@ -23,4 +23,4 @@ zen-menubar-appearance-dark =
|
||||
.label = Dark
|
||||
|
||||
zen-menubar-new-unsynced-window =
|
||||
.label = New Blank Window
|
||||
.label = New blank window
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -19,4 +19,4 @@ zen-menubar-appearance-light =
|
||||
zen-menubar-appearance-dark =
|
||||
.label = כהה
|
||||
zen-menubar-new-unsynced-window =
|
||||
.label = New Blank Window
|
||||
.label = חלון ריק חדש
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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!
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -19,4 +19,4 @@ zen-menubar-appearance-light =
|
||||
zen-menubar-appearance-dark =
|
||||
.label = 다크
|
||||
zen-menubar-new-unsynced-window =
|
||||
.label = New Blank Window
|
||||
.label = 새 빈 창
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 = Новое пустое окно
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 = 開新初始視窗
|
||||
|
||||
@@ -19,4 +19,4 @@ zen-menubar-appearance-light =
|
||||
zen-menubar-appearance-dark =
|
||||
.label = 暗色
|
||||
zen-menubar-new-unsynced-window =
|
||||
.label = 新的初始視窗
|
||||
.label = 開新初始視窗
|
||||
|
||||
@@ -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 = 排序工作區
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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()
|
||||
99
scripts/update_external_patches.py
Normal file
99
scripts/update_external_patches.py
Normal 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()
|
||||
@@ -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({
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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 = "";
|
||||
|
||||
@@ -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,
|
||||
});
|
||||
|
||||
@@ -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;
|
||||
|
||||
3
src/external-patches/librewolf/README.md
Normal file
3
src/external-patches/librewolf/README.md
Normal 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).
|
||||
12
src/external-patches/librewolf/firefox-in-ua.patch
Normal file
12
src/external-patches/librewolf/firefox-in-ua.patch
Normal 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",
|
||||
)
|
||||
65
src/external-patches/librewolf/xdg-dir.patch
Normal file
65
src/external-patches/librewolf/xdg-dir.patch
Normal 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)
|
||||
|
||||
29
src/external-patches/manifest.json
Normal file
29
src/external-patches/manifest.json
Normal 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"
|
||||
}
|
||||
]
|
||||
@@ -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 += [
|
||||
@@ -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);
|
||||
},
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
) {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -743,6 +743,10 @@ window.gZenCompactModeManager = {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this._isTabBeingDragged) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.hoverableElements[i].keepHoverDuration) {
|
||||
this.flashElement(
|
||||
target,
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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`);
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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,
|
||||
});
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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();
|
||||
});
|
||||
|
||||
@@ -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'"]
|
||||
|
||||
@@ -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'"]
|
||||
|
||||
@@ -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 = [
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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 &&
|
||||
|
||||
@@ -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"
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user