Skip to content
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

Handle screensaver independent of X11 #1848

Open
cschramm opened this issue Sep 8, 2022 · 7 comments · May be fixed by #1896 or #1897
Open

Handle screensaver independent of X11 #1848

cschramm opened this issue Sep 8, 2022 · 7 comments · May be fixed by #1896 or #1897

Comments

@cschramm
Copy link
Member

cschramm commented Sep 8, 2022

I think we could use GTK+ power, namely gtk_application_inhibit with GTK_APPLICATION_INHIBIT_IDLE and gtk_application_uninhibit. To my understanding it would save us from the X11 interaction as GTK+ will route it to either its X11 backend or its Wayland backend where it's a noop and since 3.99.0 it even implements the idle-inhibit Wayland protocol (https://gitlab.gnome.org/GNOME/gtk/-/commit/5af7d6bff3d2920aca118a36f13b23cbb68c1641#a64185fe139cee5b6c20bff1d9e5e985a228410f) that should get it working in Wayland as well.

Originally posted by @cschramm in #1461 (comment)

@infirit
Copy link
Contributor

infirit commented Sep 8, 2022

Yes we can use that. I remember trying it on KDE once but for some reason it didn't work for me then. But now it's fine. It does depend on a freedesktop portal, not sure we should add that as a dep?

Horrible testscript below.

from gi.repository import Gtk, GLib, Gio


class InhibitApp(Gtk.Application):
    def __init__(self):
        super().__init__(
            application_id="org.blueman.Inhibit",
            flags=Gio.ApplicationFlags.FLAGS_NONE
        )
    
        self.hold()
        GLib.timeout_add_seconds(5, self.start_inhibit)

    def do_startup(self):
        Gtk.Application.do_startup(self)


    def start_inhibit(self):
        self.inhibit(None, Gtk.ApplicationInhibitFlags.IDLE, "Games")

app = InhibitApp()
app.run()

@infirit
Copy link
Contributor

infirit commented Oct 12, 2022

xdg-deaktop-portal provides a pkgconfig file so we can just add it to the runtime deps. Then it's up to the individual desktop/user to make sure to make sure they provide the required implementations.

@infirit infirit linked a pull request Oct 16, 2022 that will close this issue
@cschramm cschramm linked a pull request Oct 17, 2022 that will close this issue
@cschramm
Copy link
Member Author

cschramm commented Oct 23, 2022

I quickly tested this on MATE and checked the X implementation:

What it does is use a session manager if one is available, specifically interfaces org.gnome.SessionManager and org.xfce.Session.Manager. Otherwise, it uses the Inhibit portal.

MATE actually provides the org.gnome.SessionManager interface that GTK looks for, so it tries to use that. I tried your call in #1896. First thing I got is Warning: g_variant_new_string: assertion 'string != NULL' failed from the g_variant_new as dbus->application_id is NULL so that string [Invalid UTF-8] gets transferred. Not sure if that's related (it probably is as the purpose of that argument is most probably to keep checking if the application is still alive), but the screensaver's idle timeout does jump in.

I then tried the portal fallback manually with xdg-desktop-portal-gtk set up and

Gio.bus_get_sync(Gio.BusType.SESSION).call_sync(
    "org.freedesktop.portal.Desktop",
    "/org/freedesktop/portal/desktop",
    "org.freedesktop.portal.Inhibit",
    "Inhibit",
    GLib.Variant("(sua{sv})", ("", 8, {"reason": GLib.Variant("s", "")})),
    None,
    Gio.DBusCallFlags.NONE,
    -1
)

That seems to have worked. At least my screensaver does not show up at all anymore now and even if I invoke it manually, it is black. 🙈

@cschramm
Copy link
Member Author

Strike that. Tried again after restart and the portal way did not prevent the screensaver this time. But... I fixed my application_id and now the session manager way does prevent the screensaver as long as the application is running, so the intended way between GTK and MATE does work.

If things do not work for you, I'd expect an issue with xdg-desktop-portal-kde.

@cschramm
Copy link
Member Author

Cinnamon implements org.gnome.SessionManager as well, so I guess most things are covered even without the portal. KDE and LXQt fall back to their portal implementations.

@cschramm
Copy link
Member Author

cschramm commented Oct 23, 2022

From a quick glance, ...

The LXQt portal does not implement inhibit at all. It uses xdg-screensaver, so I guess the xset s off implementation in xdg-screensaver should work for it while GTK inhibit probably does not... 😒

The GTK portal's inhibit implementation looks pointless for this, as it basically just delegates to org.gnome.SessionManager which GTK would handle preferred anyway.

The KDE portal's inhibit implementation, well, looks like it should do something useful and is in place since 5.10. It delegates to the power manager.

@infirit
Copy link
Contributor

infirit commented Oct 23, 2022

The KDE portal's inhibit implementation, well, looks like it should do something useful and is in place since 5.10. It delegates to the power manager.

It doesn't actually prevent the screen going dark. I do see it show up in the inhibitors list.

Experiment calling directly into the portal #1914.

It's clear to me now the whole portal inhibition is broken on anything but gnome (and those that implement gnome's session manager).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
2 participants