From 59e7974c42dc08411c9af2a3a644a582c2116f46 Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Wed, 9 Aug 2023 11:58:23 +0200 Subject: [PATCH] Send session IdleHint to logind once screen saver blanks If systemd or elogind support is enabled, set the session IdleHint when the screen saver activates (blanks). Note that this approach is not perfect, as it does not include xscreensaver's authentication dialog. It is therefore possible that the system enters the suspend mode while the user is typing its password in xscreensaver's authentication dialog. However, the window of opportunity is pretty small. Thanks to Michael "mjt0k" Tokarev and damjan from #systemd for help with setting the idle hint. --- driver/Makefile.in | 2 +- driver/xscreensaver.c | 50 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+), 1 deletion(-) diff --git a/driver/Makefile.in b/driver/Makefile.in index 6eca4c31..ad15a603 100644 --- a/driver/Makefile.in +++ b/driver/Makefile.in @@ -104,7 +104,7 @@ DAEMON_DEFS = -DDEFAULT_PATH_PREFIX='"@HACKDIR@"' -DAD_DIR='"$(AD_DIR)"' DAEMON_SRCS = xscreensaver.c blurb.c atoms.c clientmsg.c xinput.c prefs.c DAEMON_OBJS = xscreensaver.o blurb.o atoms.o clientmsg.o xinput.o prefs.o \ $(UTILS_BIN)/xmu.o -DAEMON_LIBS = $(LIBS_PRE) $(XINPUT_LIBS) -lX11 $(LIBS_POST) +DAEMON_LIBS = $(LIBS_PRE) $(XINPUT_LIBS) -lX11 @SYSTEMD_LIBS@ $(LIBS_POST) GFX_DEFS = -DLOCALEDIR=\"$(localedir)\" GFX_SRCS = xscreensaver-gfx.c screens.c windows.c subprocs.c \ diff --git a/driver/xscreensaver.c b/driver/xscreensaver.c index b67c4b32..3a0bf6c1 100644 --- a/driver/xscreensaver.c +++ b/driver/xscreensaver.c @@ -229,6 +229,10 @@ # error The XInput2 extension is required #endif +# if defined(HAVE_LIBSYSTEMD) || defined(HAVE_LIBELOGIND) +#include +#endif + #include #include #include @@ -1000,6 +1004,45 @@ ensure_no_screensaver_running (Display *dpy) print_x11_error_p = op; } +# if defined(HAVE_LIBSYSTEMD) || defined(HAVE_LIBELOGIND) +static void set_idle_hint(int idle) { + sd_bus *bus = NULL; + sd_bus_error error = SD_BUS_ERROR_NULL; + int res; + + /* Connect to the system bus */ + res = sd_bus_open_system(&bus); + if (res < 0) { + static Bool once; + if (!once) { + once = True; + fprintf(stderr, "Failed to connect to system bus: %s\n", strerror(-res)); + } + return; + } + + /* Issue the method call and store the respons message in m */ + res = sd_bus_call_method(bus, + "org.freedesktop.login1", /* service to contact */ + "/org/freedesktop/login1/session/auto", /* object path */ + "org.freedesktop.login1.Session", /* interface name */ + "SetIdleHint", /* method name */ + &error, /* object to return error in */ + NULL, /* return message on success */ + "b", /* input signature */ + idle); /* first argument */ + if (res < 0) { + static Bool once; + if (!once) { + once = True; + fprintf(stderr, "Failed to issue method call: %s\n", error.message); + } + } + + sd_bus_error_free(&error); + sd_bus_unref(bus); +} +# endif /* HAVE_LIBSYSTEMD || HAVE_LIBELOGIND */ /* Store a property on the root window indicating that xscreensaver is running, and whether it is blanked or locked. This property is read @@ -1082,6 +1125,13 @@ store_saver_status (Display *dpy, free (status); if (dataP) XFree (dataP); + +# if defined(HAVE_LIBSYSTEMD) || defined(HAVE_LIBELOGIND) + if (verbose_p) + fprintf (stderr, "setting idle hint: %d\n", blanked_p); + + set_idle_hint(blanked_p); +# endif /* HAVE_LIBSYSTEMD || HAVE_LIBELOGIND */ }