Repository navigation
✨ Remember Workspace State Per Window #917
Description
Activity
@Code-DJ would you be able to look at this?
As this is a View-related problem, I'd suggest looking into using SceneStorage instead of storing this state in the NSWindow instance.
Reacted by Austin Condiff- changed the title
[-]✨ Remember Sidebar Width Per Window[/-][+]✨ Remember Workspace State Per Window[/+]on Jan 10, 2023 @Code-DJ would you be able to look at this?
Yes I can take a stab at it. I assume, right now, Workspace = Open Folder, so all the settings need to saved by an identifier = "path of the folder".
Note: I am new to Apple API - so Wouter01 pointing to SceneStorage already helps.
@Code-DJ would you be able to look at this?
Yes I can take a stab at it. I assume, right now, Workspace = Open Folder, so all the settings need to saved by an identifier = "path of the folder".
Note: I am new to Apple API - so Wouter01 pointing to SceneStorage already helps.
That's indeed a good idea. I'd split it up in a few SceneStorage variables. For example, You could save the workspace navigator state as
@SceneStorage("navigatorFolder\(url.path())") var isOpened: Bool. This way, if another SceneStorage variable will depend on the URL, there won't be conflictsThat is a good question, should we use the path as the workspace identifier? What if the user renames a parent directory? What if we decide later down the road (like VS Code) that we want to support multiple folders per workspace.
This can be a later discussion and we can use the path as the identifier for the time being but I did want to point that out.
That is a good question, should we use the path as the workspace identifier? What if the user renames a parent directory? What if we decide later down the road (like VS Code) that we want to support multiple folders per workspace.
This can be a later discussion and we can use the path as the identifier for the time being but I did want to point that out.
We can assume the user doesn't rename it. If he/she does, the window frames will be reset, but it's not a huge deal. I think the project won't even appear in the recent items list anymore. You don't really have another way of doing it.
I'd guess if you want multiple folders in a workspace, you'd need to create a workspace with the parent folder of both.
Reacted by Code-DJHere are my thoughts:
- The key for
SceneStoragewill be the "path to the workspace folder" - Is there still uncertainty about this? - save all settings in
Dictionary<String, Any>inWorkspaceDocument. - add two new methods to
WorkspaceDocument-writeToSceneStorage,readFromSceneStorageneed better names, this will allow views e.g.InspectorSidebarto read on init and write on change. - restore values from
SceneStorageinWorkspaceDocument.initWorkspaceState. - save the dictionary to
SceneStoragein a new methodWorkspaceDocument.saveWorkspaceState. - call
WorkspaceDocument.saveWorkspaceStatefromWorkspaceDocument.write.
In addition to the above, do we need to periodically save state (in case the user keeps CodeEdit open for days)?
- The key for
Is it somehow possible to bind everything to this state? The state should be saved when anything changes.
It looks like SceneStorage automatically does the saving and restoring of the state - I am not sure when it does that - for details see the link below.
Based on this, it appears we don't need to do any of
initWorkspaceStateandsaveWorkspaceStatestuff I mentioned above.If we prefix the dictionary variable with
@SceneStorage(url) var viewState = Dictionary<String, Any>(), it may just work. @Wouter01 any thoughts?Taken from SceneStorage Example
struct DevTechieSceneStorageExample: View { @SceneStorage("name") var name = "" @SceneStorage("email") var email = "" var body: some View { NavigationStack { Form { Section(header: Text("Personal Information")) { TextField("Enter name", text: $name) TextField("Enter email", text: $email) } } .navigationTitle("DevTechie") } } }
Maybe we save on window/app close then?
Reacted by Code-DJ@austincondiff I didn't realize this was ready for me. Can you assign it to me. Thanks!
Reacted by Austin CondiffHere are my thoughts:
-
The key for
SceneStoragewill be the "path to the workspace folder" - Is there still uncertainty about this? -
save all settings in
Dictionary<String, Any>inWorkspaceDocument. -
add two new methods to
WorkspaceDocument-writeToSceneStorage,readFromSceneStorageneed better names, this will allow views e.g.InspectorSidebarto read on init and write on change. -
restore values from
SceneStorageinWorkspaceDocument.initWorkspaceState. -
save the dictionary to
SceneStoragein a new methodWorkspaceDocument.saveWorkspaceState. -
call
WorkspaceDocument.saveWorkspaceStatefromWorkspaceDocument.write.
In addition to the above, do we need to periodically save state (in case the user keeps CodeEdit open for days)?
Apologies for the late response, I must've missed your mention. Regarding SceneStorage, it's meant to be used in SwiftUI views only. On second thought, this may not play well with the current state of the app. I don't know if there's an appkit alternative, or if you had figured it out already?
What I can tell though, in my test build with the SwiftUI lifecycle, lots of this is done automatically, liking saving the sidebar and inspector width. Other things, like the state of the file navigator, won't be saved automatically, as these are done in AppKit. Maybe it's worth a try looking into those first?
Reacted by Code-DJ and Austin Condiff-
Is it somehow possible to bind everything to this state? The state should be saved when anything changes.
You can see SceneStorage as a variant of AppStorage, except it's done for a window instance instead of the whole app. SceneStorage will load the precious data in automatically, and will save new data automatically. No need to worry about when to save it.
Reacted by Austin Condiff and Qian Qian "Qubik"Important to notice:
If the Scene is explicitly destroyed (e.g. the switcher snapshot is destroyed on iPadOS or the window is closed on macOS), the data is also destroyed.
from: https://developer.apple.com/documentation/swiftui/scenestorage
Is this issue worth keeping around? Here is the current state...
The following IS retained:
- Workspace window size and position
- Editor tab order and active tab
- Editor layout
- Navigator Area, Inspector Area, and Utility Area open/closed state
The following IS NOT retained:
- Navigator Area, Inspector Area, and Utility Area size
- Navigator Area, Inspector Area, and Utility Area active tab
Metadata
Metadata
Assignees
Labels
Type
Projects
- StatusShow more project fields👀 In Review
Describe the solution you'd like
We need to persist workspace state per window after the user quits and opens CodeEdit again.
We will need to also remember
Related