Skip to content

Conversation

@AdrianVovk
Copy link
Collaborator

@AdrianVovk AdrianVovk commented Sep 25, 2025

Implements the portal proposed in #1698

Links to other MRs:

@Mikenux
Copy link

Mikenux commented Sep 26, 2025

About the naming...

Why SaveHint instead of Save, given that it's Save on the SaveRestore interface? Or SaveState?

@AdrianVovk
Copy link
Collaborator Author

Why SaveHint instead of Save

I renamed it to make it a bit more clear

given that it's Save on the SaveRestore interface

Sorry, where? It's SaveHint in all the dbus interfaces here

@Mikenux
Copy link

Mikenux commented Sep 27, 2025

Sorry, where? It's SaveHint in all the dbus interfaces here

Sorry, mistake.

I renamed it to make it a bit more clear

Relative to? If you are looking for something meaningful, I think SaveState or SaveAppState are better options. Same for the interface name.

@AdrianVovk
Copy link
Collaborator Author

Relative to? If you are looking for something meaningful, I think SaveState or SaveAppState are better options. Same for the interface name

Whoops didn't finish typing my comment. SaveHint makes it a bit more clear that it's just a hint and that the app shouldn't be using it as the primary source for deciding to save state. If it was just Save it might seem like the portal will emit the signal regularly or whatever. Anyway, not the most important thing in the world, but that's why I renamed it

@AdrianVovk
Copy link
Collaborator Author

CC @davidedmundson and @technobaboo as the two folks from other desktops who I've interacted with in the discussion

This is the real API I ended up implementing. PTAL and let me know if there's some blocker to getting something like this working in your desktop, or you see something missing, or etc.

For your reference, here's GNOME's implementation of this portal's backend: https://gitlab.gnome.org/GNOME/gnome-session/-/blob/avovk/session-save-portal/gnome-session/gsm-session-save.c

@technobaboo
Copy link

wait how does the app get the instance ID and know to restore its data using that ID? afaik there's no standard key name for it or such in the registration map it gets as a return arg for registering

@AdrianVovk
Copy link
Collaborator Author

how does the app get the instance ID and know to restore its data using that ID

It's there - it's the first arg called instance-id. And it knows to restore data using that ID via the second arg, restore-reason

I'm guessing you might have been looking at org.freedesktop.impl.portal.SaveRestore, which I don't document as thoroughly because I can link to the portal frontend dbus API instead. Check the docs for org.freedesktop.portal.SaveRestore, which should be more complete w.r.t. known keys in the various vardicts

@technobaboo
Copy link

okay that's nice to know, so if it's required why isn't it an argument instead of inside the map?

@davidedmundson
Copy link
Contributor

davidedmundson commented Oct 7, 2025

What's the goal of:

[session: Communicate close reason to impl]

to allow identify crash exits vs clean application shutdowns? Do any other portal impls gain anything from this? If not, we would be better off with a bespoke signal just on the session restore before Close.

Copy link
Collaborator

@swick swick left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just looked through the PR to understand what is being proposed here and found a bunch of things.

Comment on lines 215 to 217
else
xdp_dbus_impl_session_call_close_sync (session->impl_session,
NULL, &error);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
else
xdp_dbus_impl_session_call_close_sync (session->impl_session,
NULL, &error);
else
{
xdp_dbus_impl_session_call_close_sync (session->impl_session,
NULL, &error);
}

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same issue in multiple places

{
XdpDbusImplSaveRestore *impl_proxy = XDP_DBUS_IMPL_SAVE_RESTORE (source_object);
g_autofree RegisterData *data = user_data;
g_autoptr (GError) error = NULL;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In xdp and flatpak for some reason the autoptr style is g_autoptr(GError).

This lets the impl differentiate between a session that's closing
because the app voluntarily called `Close()`, or because the app
disconnected from the bus / some other reason.
3 seconds of receiving this signal. The app may be transparently restarted
by the system at a later date.
-->
<signal name="Quit">
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm so I'm not really sure that this is actually necessary...

Instead of asking the app to quit, we can just put it in a cgroup freezer. This removes it from the run queue. We could then adjust the memory limits on the cgroup, which as far as I understand will force the app's memory out to swap and out of RAM. At that point, is there really any point to actually shutting down the app? We can leave the app "running", just frozen in a cgroup freezer and swapped out to disk. If the goal is to free up resources like memory and CPU, we've achieved that.

We can use something like SaveHint to ask the app to save its state just in case it somehow gets killed while in the freezer.

Alternatively, apps should just save their state immediately before quitting in response to something like SIGTERM. Then we could handle this simply by sending SIGTERM to the apps, rather than having them subscribe to this signal.

#define XDP_TYPE_SAVE_RESTORE (xdp_save_restore_get_type ())
G_DECLARE_FINAL_TYPE (XdpSaveRestore,
xdp_save_restore,
XDP, SAVE_RESTORE,
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm so the USB portal names itself XdpUsb, but apparently most every other portal doesn't have an Xdp prefix. And apparently that was intentional

So, IDK am I supposed to rename this portal to just SaveRestore?

Perhaps if we want to maintain a separation, we could have a Portal prefix, so that all the portals are PortalAccounts, PortalSaveRestore, PortalUsb, etc and the utility classes/functions can keep XdpSession, XdpContext, etc


G_DEFINE_TYPE (XdpSaveRestoreSession,
xdp_save_restore_session,
xdp_session_get_type ())
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

XDP_TYPE_SESSION?

{
XdpSaveRestoreSession *save_restore_session = XDP_SAVE_RESTORE_SESSION (session);

save_restore_session->closed = TRUE;
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think a couple of the session implementations do nothing but keep track of this closed variable.

Maybe that should move up into the XdpSession object?

On the other hand, this class separation actually lets us check that the caller is giving us a session path to a session of a type we expect. So we'd need to have a subclass anyway. Or at the very least some sort of accounting of what portal created any given session

XdpDbusImplSaveRestore *impl = XDP_DBUS_IMPL_SAVE_RESTORE (source_object);
g_autoptr(RegisterData) data = user_data;
g_autoptr(GError) error = NULL;
g_autoptr(GVariant) out_restore = NULL;
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I renamed this to registration

g_autoptr(GError) error = NULL;

impl_config = xdp_portal_config_find (config, SAVE_RESTORE_DBUS_IMPL_IFACE);
if (impl_config != NULL)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is backwards.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants