aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPřemysl Eric Janouch <p@janouch.name>2020-10-02 08:23:31 +0200
committerPřemysl Eric Janouch <p@janouch.name>2021-07-05 21:58:43 +0200
commit4b0f2d1cdf480c9d516532361b13476083cbbec0 (patch)
tree83dc91e47fff554b62a37f830ee10bbdd1bf331f
parent8f350388ee2f6115bf4e1117c4968b2d51b73121 (diff)
downloadwdmtg-4b0f2d1cdf480c9d516532361b13476083cbbec0.tar.gz
wdmtg-4b0f2d1cdf480c9d516532361b13476083cbbec0.tar.xz
wdmtg-4b0f2d1cdf480c9d516532361b13476083cbbec0.zip
WIP: Track suspension/hibernationHEADmaster
WIP: should check for changes in the IDLETIME counter, as well as in the SERVERTIME counter. - xorg-server/Xext/sync.c - always uses XSyncCounterNeverDecreases even though os/utils.c works even without CLOCK_MONOTONIC (not present or retrieval fails) - what am I actually trying to use this knowledge for? - I expect the IDLETIME counter to keep running monotonically, otherwise I'd need to account for any change - it doesn't look like it is changed by anything other than input devices - actually Xext/saver.c does something but it doesn't look like it'd mess up anything (hw/xfree86/common/xf86Events.c upon VT switching bumps idle timers) - hw/xfree86/common/xf86PM.c also appears to bump the idle timer, when the computer is resumed from suspend :/ - I expect the SERVERTIME counter to either jump or not - exactly what will happen: really should not jump but might - so far it looks like the suspend check is useful in cases that: - an automated (or external) suspend comes before we declare user idleness: we can mark that period as idle - I've written misc/toys/x11-timers.c: read out the timers in a loop - everything behaves as expected, there's just an interesting delay between the monotonic timer starting to run and the system continuing to function WIP: somehow write the above part down in the source as a comment WIP: need to: a/ take a delay lock, b/ register for PrepareForSleep/PrepareForShutdown signals
-rw-r--r--wdmtg.c58
1 files changed, 58 insertions, 0 deletions
diff --git a/wdmtg.c b/wdmtg.c
index a6cae89..5a6aa63 100644
--- a/wdmtg.c
+++ b/wdmtg.c
@@ -131,6 +131,10 @@ struct {
xcb_sync_alarm_t idle_alarm_inactive; // User is inactive
xcb_sync_alarm_t idle_alarm_active; // User is active
+
+ // Suspension tracking
+
+ GDBusProxy *dbus; // logind DBus proxy
} gen;
// --- XCB helpers -------------------------------------------------------------
@@ -481,6 +485,45 @@ generator_thread(void)
}
static void
+generator_delay_sleep(void)
+{
+ GError *error = NULL;
+ GUnixFDList *lock_fd = NULL;
+
+ // TODO: see what event loop GDBusProxy uses, if any
+ // - we really don't want to receive events in the main thread
+ // - "[signals] are emitted in the thread-default main context of
+ // the thread where the instance was constructed"
+ // - so apparently we need to construct it in generator_thread()
+ // - in the end we can wait for the generator to send back the first
+ // event, so we can set a metadata variable
+ // - but more importantly, we do not need this to work
+
+ // TODO: see about the "low-level" API
+ // - still need to subscribe for signals from the worker thread,
+ // as it gets delivered to the thread that invokes it
+
+ // TODO: have a look at
+ // https://stackoverflow.com/questions/56788812/
+ // https://developer.gnome.org/glib/stable/glib-The-Main-Event-Loop.html#g-main-context-push-thread-default
+
+ // NOTE: try to avoid libdbus, signals are a lot more hardcore there
+
+ GVariant *v = g_dbus_proxy_call_with_unix_fd_list_sync(gen.dbus, "Inhibit",
+ g_variant_new("(ssss)", "shutdown:sleep", PROJECT_NAME,
+ "Activity tracking", "delay"), G_DBUS_CALL_FLAGS_NONE, 1000,
+ NULL, &lock_fd, NULL, &error);
+
+ if (error) {
+ // TODO: log a message
+ } else {
+ // TODO: check and save the file descriptor in gen
+ g_variant_unref(v);
+ g_object_unref(lock_fd);
+ }
+}
+
+static void
generator_init(void)
{
int which_screen = -1, xcb_error;
@@ -557,6 +600,20 @@ generator_init(void)
(void) xcb_flush(gen.X);
// TODO: how are XCB errors handled? What if the last xcb_flush() fails?
+
+ // We don't require DBus to function but it's a nice-to-have
+ GError *error = NULL;
+ gen.dbus = g_dbus_proxy_new_for_bus_sync(G_BUS_TYPE_SYSTEM,
+ G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START, NULL, "org.freedesktop.login1",
+ "/org/freedesktop/login1", "org.freedesktop.login1.Manager", NULL,
+ &error);
+ if (!gen.dbus) {
+ g_printerr("DBus connection failed: %s", error->message);
+ g_error_free(error);
+ } else {
+ generator_delay_sleep();
+ // TODO: register for PrepareForSleep and PrepareForShutdown signals
+ }
}
static void
@@ -572,6 +629,7 @@ generator_cleanup(void)
g_thread_join(gen.thread);
free(gen.current_title);
xcb_disconnect(gen.X);
+ g_clear_object(&gen.dbus);
}
// --- Main --------------------------------------------------------------------