Skip to content

Desktop entry save/restore state

The idea is simple: Ensure applications can be saved/restored correctly in any situation such as:

  • Restoring open apps when a desktop is restarted
  • Starting/killing applications for KDE activities so each activity has all the opened apps for that activity in the same places with the same documents open, etc.
  • Switching between multiple desktops so each desktop restores the apps in the states they were in last time the desktop was used
  • Killing unfocused foreground apps that take up too many resources and have them perfectly restored when the user opens them again in recents (for linux phones, just like with iOS/Android)
  • Tying applications to spatial anchors for augmented reality so applications appear to persist even when killed to save on resources (which is being implemented in https://stardustxr.org/).

This is accomplished by adding in the SaveState method to the org.freedesktop.Application interface that a session manager or other process can call to request an application save its state and associate it with the given app_state_id. The application should wait until its state is saved to return an error or success.

The session ID passed in is a UID that can be used to restore that saved state later. The application should restore its state when the APP_STATE_ID environment variable and/or app-state-id platform-data is given to it.

So it's easier to understand, here's the steps taken from multiple different perspectives:

  • app is freshly launched:
    1. user does stuff on app
    2. app receives com.freedesktop.Application:SaveState method from d-bus with an app state ID
    3. app asks wayland session-restore protocol for id
    4. app serializes its state (including the wayland session ID)
    5. app stores its serialized state in a file somewhere associated with the app state id
    6. app sends the method return for SaveState with an error if it failed
    7. session manager nukes app from orbit (maybe, if it wants to)
  • app is restored:
    1. app sees that APP_STATE_ID is set with id
    2. app finds state file associated with id
    3. app deserializes that file and restores state, making wayland toplevels
    4. app gets wayland session ID from deserialized state and restores state to its newly made toplevels
  • session is quit:
    1. session manager gets all d-bus objects implementing com.freedesktop.Application
    2. session manager calls SaveState on each one with a timeout (if the method is present) passing in a UID it associates with its cmdline and user (or equivalent to open it)
    3. session manager kills all apps
  • session is restored:
    1. session manager loads file(s) with previous session
    2. session manager launches previous apps passing in the APP_STATE_ID or equivalent platform-data when possible

Before these points come up let me address them:

  • This solves the problem of windowing system independent state and needing different state for different launch circumstances.
  • Why bother with the app state ID? because there are many situations where you need to restore different states at different times and remember older states:
    • Say a GNOME shell session is started, apps launched, and quit. Then the user opens up a Plasma desktop. The application's state would be different, especially if that state includes something like the wayland session-management protocol which is incredibly compositor-specific. Users have a different workflow on different desktops and do not expect their open apps on 1 DE to seamlessly transfer to another.
    • Say you're running an augmented reality compositor and you save 2 instances of a mail app: one at the coffee shop that has a work email open and another at your house that has a personal email open. When you go home you expect to see the state showing the personal email and at the coffee shop see the state of a work email. This isn't possible if the application just saves its last state.
    • If the user has opened multiple instances of an app in recents (for linux mobile desktops) they might want to keep them separate so they can decide to open the same app with a different state.
  • This does use an environment variable which will be propagated to any child processes, but that's why the session manager generates a unique identifier: since it's launching the apps and the IDs are not susceptible to collision in practice any children will find they do not have the proper state to restore. If there's a better way I'd like to hear it, but command-line arguments are not easy to implement into many existing apps for this case.
  • This spec is complimentary to efforts such as wayland/wayland-protocols!18. The given spec is not only wayland-specific but does not allow a session manager to specify what session ID it wants the app to use in the multiple desktop case where the same session ID will not translate across compositors. With the general XDG spec change, the application can store its wayland session_id inside its state that it saves to ensure it restores the wayland toplevels correctly only on the correct compositor.
  • This spec is not tied to any windowing system because under many toolkits the application gets its state back from the OS before any windowing system is even connected to. The application will need to know the current document and screen it has open before it can create toplevels that can be restored by the wayland protocol for example.
  • This does indeed require the application/toolkit to save and restore its state, however there is no better option I can see and this is extremely similar to how other platforms save/restore state (though they generally will pass bytes to the OS instead of letting the app save its state in sessions)

I can make a prototype of this any time you want, since I have already made something similar with Stardust XR that works very reliably.

Edited by Nova (technobaboo)

Merge request reports