-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
gh-8460: Workspaces sync [2.0] #12531
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: dev
Are you sure you want to change the base?
Changes from 27 commits
a97293b
02870f1
d5c932e
e1497d8
072c998
095cc1c
03ae282
43b221f
f3fe62a
f67ce1c
7e43e74
883f513
d0b6efc
b3ae110
7c0ce26
a28c057
2138903
83051fb
689a2ab
8148035
f449897
bf1dd6c
43d200d
603e585
092b8e4
1d8584b
73d846d
05b1188
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| diff --git a/browser/components/preferences/sync.js b/browser/components/preferences/sync.js | ||
| index dc89a9c41a0dbd44054ede0025d333773f0ae908..7fd91bd704b3b187277e4c8b076f990cb56ea8dc 100644 | ||
| --- a/browser/components/preferences/sync.js | ||
| +++ b/browser/components/preferences/sync.js | ||
| @@ -40,6 +40,7 @@ Preferences.addAll([ | ||
| { id: "services.sync.engine.creditcards", type: "bool" }, | ||
| { id: "services.sync.engine.addons", type: "bool" }, | ||
| { id: "services.sync.engine.prefs", type: "bool" }, | ||
| + { id: "services.sync.engine.workspaces", type: "bool" }, | ||
| ]); | ||
|
|
||
| /** | ||
| @@ -512,6 +513,7 @@ const SYNC_ENGINE_SETTINGS = [ | ||
| }, | ||
| { id: "syncAddons", pref: "services.sync.engine.addons", type: "addons" }, | ||
| { id: "syncSettings", pref: "services.sync.engine.prefs", type: "settings" }, | ||
| + { id: "syncWorkspaces", pref: "services.sync.engine.workspaces", type: "workspaces" }, | ||
| ]; | ||
|
|
||
| SYNC_ENGINE_SETTINGS.forEach(({ id, pref }) => { |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,15 @@ | ||
| diff --git a/services/sync/modules/service.sys.mjs b/services/sync/modules/service.sys.mjs | ||
| index c873293871ffaba305bc1bf41730d79c13546b85..0e0171cec13dfcbb296ec7bf03628370ce2fa93f 100644 | ||
| --- a/services/sync/modules/service.sys.mjs | ||
| +++ b/services/sync/modules/service.sys.mjs | ||
| @@ -99,6 +99,10 @@ function getEngineModules() { | ||
| whenTrue: "ExtensionStorageEngineKinto", | ||
| whenFalse: "ExtensionStorageEngineBridge", | ||
| }; | ||
| + result.Workspaces = { | ||
| + module: "resource:///modules/zen/ZenWorkspacesSync.sys.mjs", | ||
| + symbol: "ZenWorkspacesEngine", | ||
| + }; | ||
| return result; | ||
| } | ||
|
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,30 @@ | ||
| diff --git a/toolkit/components/contextualidentity/ContextualIdentityService.sys.mjs b/toolkit/components/contextualidentity/ContextualIdentityService.sys.mjs | ||
| index 5702ff28cc22206f5ce16584dac8a78d816562ce..1cd7f0fd222f5b6d2a98d7b5b76c22063d81894f 100644 | ||
| --- a/toolkit/components/contextualidentity/ContextualIdentityService.sys.mjs | ||
| +++ b/toolkit/components/contextualidentity/ContextualIdentityService.sys.mjs | ||
| @@ -270,11 +270,22 @@ _ContextualIdentityService.prototype = { | ||
| }); | ||
| }, | ||
|
|
||
| - create(name, icon, color) { | ||
| + create(name, icon, color, id = null) { | ||
| this.ensureDataReady(); | ||
|
|
||
| - // Retrieve the next userContextId available. | ||
| - let userContextId = ++this._lastUserContextId; | ||
| + let userContextId; | ||
| + if ( | ||
| + id !== null && | ||
| + !this._identities.some(identity => identity.userContextId === id) | ||
| + ) { | ||
| + userContextId = id; | ||
| + this._lastUserContextId = Math.max( | ||
| + this._lastUserContextId, | ||
| + userContextId | ||
| + ); | ||
| + } else { | ||
| + userContextId = ++this._lastUserContextId; | ||
| + } | ||
|
|
||
| // Throw an error if the next userContextId available is invalid (the one associated to | ||
| // MAX_USER_CONTEXT_ID is already reserved to "userContextIdInternal.webextStorageLocal", which |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -467,9 +467,6 @@ class nsZenLiveFoldersManager { | |
| }); | ||
| // createLazyBrowser can't be pinned by default | ||
| this.window.gBrowser.pinTab(tab); | ||
| if (userContextId) { | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why? |
||
| tab.setAttribute("zenDefaultUserContextId", "true"); | ||
| } | ||
| if (item.icon) { | ||
| this.window.gBrowser.setIcon(tab, item.icon); | ||
| if (tab.linkedBrowser) { | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -19,4 +19,5 @@ DIRS += [ | |
| "sessionstore", | ||
| "share", | ||
| "spaces", | ||
| "sync" | ||
| ] | ||
|
kristijanribaric marked this conversation as resolved.
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -10,6 +10,7 @@ const lazy = {}; | |
| ChromeUtils.defineESModuleGetters(lazy, { | ||
| ZenLiveFoldersManager: | ||
| "resource:///modules/zen/ZenLiveFoldersManager.sys.mjs", | ||
| ZenSyncStore: "resource:///modules/zen/ZenSyncManager.sys.mjs", | ||
| PrivateBrowsingUtils: "resource://gre/modules/PrivateBrowsingUtils.sys.mjs", | ||
| SessionStore: "resource:///modules/sessionstore/SessionStore.sys.mjs", | ||
| SessionStartup: "resource:///modules/sessionstore/SessionStartup.sys.mjs", | ||
|
|
@@ -312,6 +313,7 @@ export class nsZenSessionManager { | |
| } | ||
| } | ||
| delete this._dataFromFile; | ||
| lazy.ZenSyncStore.seedSnapshot(this.#sidebar); | ||
| } | ||
|
|
||
| get #shouldRestoreOnlyPinned() { | ||
|
|
@@ -609,6 +611,7 @@ export class nsZenSessionManager { | |
| } | ||
| ); | ||
| this.#collectWindowData(windows); | ||
| lazy.ZenSyncStore.noteSidebarDataChanged(this.#sidebar); | ||
| // This would save the data to disk asynchronously or when quitting the app. | ||
|
kristijanribaric marked this conversation as resolved.
|
||
| let sidebar = this.#sidebarWithoutCloning; | ||
| this.#file.data = sidebar; | ||
|
|
@@ -724,6 +727,7 @@ export class nsZenSessionManager { | |
|
|
||
| sidebarData.lastCollected = Date.now(); | ||
| this.#collectTabsData(sidebarData, aStateWindows); | ||
|
|
||
| this.#sidebar = sidebarData; | ||
| } | ||
|
|
||
|
|
@@ -933,6 +937,43 @@ export class nsZenSessionManager { | |
| } | ||
| return Cu.cloneInto(sidebar.spaces, {}); | ||
| } | ||
|
|
||
| /** | ||
| * Returns a deep clone of the full sidebar object (spaces, tabs, folders, etc.). | ||
| * Used by the ZenWorkspacesSync engine to build the sync payload. | ||
| * | ||
| * @returns {object} A deep clone of the sidebar data. | ||
| */ | ||
| getSidebarData() { | ||
| const sidebar = this.#sidebar; | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Has this been fixed? @kristijanribaric I see you are still doing the JSON thingy |
||
| if (!sidebar) { | ||
| return {}; | ||
| } | ||
| return sidebar; | ||
| } | ||
|
|
||
| replaceSidebarData(sidebar, soon = true) { | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Just call
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I kept this separate intentionally.
Here I only want a raw replace-and-persist helper for sync apply, because incoming sync already produced the sidebar state I want to write. Calling So |
||
| this.#sidebar = sidebar || {}; | ||
| this.#file.data = this.#sidebarWithoutCloning; | ||
| if (soon) { | ||
| this.#file.saveSoon(); | ||
| } else { | ||
| this.#file._save(); | ||
| } | ||
| } | ||
|
|
||
| getCurrentSidebarData() { | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This should just be
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @kristijanribaric in case you missed it ^ |
||
| const state = lazy.SessionStore.getCurrentState(true); | ||
| let windows = state?.windows || []; | ||
| windows = windows.filter(win => this.#isWindowSaveable(win)); | ||
| if (!windows.length) { | ||
| return this.getSidebarData(); | ||
| } | ||
|
|
||
| const sidebarData = { lastCollected: Date.now() }; | ||
| this.#collectTabsData(sidebarData, windows); | ||
| return JSON.parse(JSON.stringify(sidebarData)); | ||
| } | ||
| } | ||
|
|
||
| export const ZenSessionStore = new nsZenSessionManager(); | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not needed