[gnome-flashback] idle-monitor: take idle inhibition into account



commit d12bba68fd88ff203eb4f5894be5104c1387bfd3
Author: Alberts Muktupāvels <alberts muktupavels gmail com>
Date:   Tue May 24 23:25:59 2022 +0300

    idle-monitor: take idle inhibition into account
    
    Take idle inhibitions into account for when to fire idle watches as
    requested by OS components.
    
    This should stop gnome-session and gnome-settings-daemon considering
    the session idle when they have been inhibited for longer than their
    timeout, for example to avoid the screensaver activating, or the
    computer suspending after watching a film.
    
    Based on mutter commits:
    https://gitlab.gnome.org/GNOME/mutter/-/commit/4af00ae296b484fa088b
    https://gitlab.gnome.org/GNOME/mutter/-/commit/2319cd9c4014fcc0c248
    https://gitlab.gnome.org/GNOME/mutter/-/commit/81ee8886ceb64fecff74

 daemons/idle-monitor/meta-idle-monitor.c | 128 ++++++++++++++++++++++++++++---
 dbus/org.gnome.SessionManager.xml        |   2 +
 2 files changed, 121 insertions(+), 9 deletions(-)
---
diff --git a/daemons/idle-monitor/meta-idle-monitor.c b/daemons/idle-monitor/meta-idle-monitor.c
index feb0322..0d03417 100644
--- a/daemons/idle-monitor/meta-idle-monitor.c
+++ b/daemons/idle-monitor/meta-idle-monitor.c
@@ -28,15 +28,21 @@
 
 #include <string.h>
 
+#include "dbus/gf-session-manager-gen.h"
 #include "meta-idle-monitor.h"
 
+#define GSM_INHIBITOR_FLAG_IDLE 1 << 3
+
 struct _MetaIdleMonitor
 {
-  GObject       parent;
+  GObject              parent;
+
+  GHashTable          *watches;
 
-  GHashTable   *watches;
+  guint64              last_event_time;
 
-  guint64       last_event_time;
+  GfSessionManagerGen *session_manager;
+  gboolean             inhibited;
 };
 
 typedef struct
@@ -54,6 +60,89 @@ G_STATIC_ASSERT(sizeof(unsigned long) == sizeof(gpointer));
 
 G_DEFINE_TYPE (MetaIdleMonitor, meta_idle_monitor, G_TYPE_OBJECT)
 
+static void
+update_inhibited_watch (gpointer key,
+                        gpointer value,
+                        gpointer user_data)
+{
+  MetaIdleMonitor *self;
+  MetaIdleMonitorWatch *watch;
+
+  self = user_data;
+  watch = value;
+
+  if (watch->timeout_source == NULL)
+    return;
+
+  if (self->inhibited)
+    {
+      g_source_set_ready_time (watch->timeout_source, -1);
+    }
+  else
+    {
+      g_source_set_ready_time (watch->timeout_source,
+                               self->last_event_time +
+                               watch->timeout_msec * 1000);
+    }
+}
+
+static void
+inhibited_actions_changed_cb (GfSessionManagerGen *session_manager,
+                              GParamSpec          *pspec,
+                              MetaIdleMonitor     *self)
+{
+  guint actions;
+
+  actions = gf_session_manager_gen_get_inhibited_actions (session_manager);
+
+  if ((actions & GSM_INHIBITOR_FLAG_IDLE) != GSM_INHIBITOR_FLAG_IDLE)
+    {
+      self->last_event_time = g_get_monotonic_time ();
+      self->inhibited = FALSE;
+    }
+  else
+    {
+      self->inhibited = TRUE;
+    }
+
+  g_hash_table_foreach (self->watches,
+                        update_inhibited_watch,
+                        self);
+}
+
+static void
+session_manager_ready_cb (GObject      *source_object,
+                          GAsyncResult *res,
+                          gpointer      user_data)
+{
+  GError *error;
+  GfSessionManagerGen *session_manager;
+  MetaIdleMonitor *self;
+
+  error = NULL;
+  session_manager = gf_session_manager_gen_proxy_new_for_bus_finish (res,
+                                                                     &error);
+
+  if (error != NULL)
+    {
+      if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
+        g_warning ("Failed to get session manager proxy: %s", error->message);
+
+      g_error_free (error);
+      return;
+    }
+
+  self = META_IDLE_MONITOR (user_data);
+  self->session_manager = session_manager;
+
+  g_signal_connect (self->session_manager,
+                    "notify::inhibited-actions",
+                    G_CALLBACK (inhibited_actions_changed_cb),
+                    self);
+
+  inhibited_actions_changed_cb (self->session_manager, NULL, self);
+}
+
 static void
 meta_idle_monitor_watch_fire (MetaIdleMonitorWatch *watch)
 {
@@ -100,6 +189,7 @@ meta_idle_monitor_dispose (GObject *object)
   MetaIdleMonitor *monitor = META_IDLE_MONITOR (object);
 
   g_clear_pointer (&monitor->watches, g_hash_table_destroy);
+  g_clear_object (&monitor->session_manager);
 
   G_OBJECT_CLASS (meta_idle_monitor_parent_class)->dispose (object);
 }
@@ -117,6 +207,15 @@ meta_idle_monitor_init (MetaIdleMonitor *monitor)
 {
   monitor->watches = g_hash_table_new_full (NULL, NULL, NULL, free_watch);
   monitor->last_event_time = g_get_monotonic_time ();
+
+  gf_session_manager_gen_proxy_new_for_bus (G_BUS_TYPE_SESSION,
+                                            G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS |
+                                            G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START,
+                                            "org.gnome.SessionManager",
+                                            "/org/gnome/SessionManager",
+                                            NULL,
+                                            session_manager_ready_cb,
+                                            monitor);
 }
 
 static guint32
@@ -180,9 +279,13 @@ make_watch (MetaIdleMonitor           *monitor,
       source = g_source_new (&idle_monitor_source_funcs, sizeof (GSource));
 
       g_source_set_callback (source, NULL, watch, NULL);
-      g_source_set_ready_time (source,
-                               monitor->last_event_time +
-                               timeout_msec * 1000);
+
+      if (!monitor->inhibited)
+        {
+          g_source_set_ready_time (source,
+                                   monitor->last_event_time +
+                                   timeout_msec * 1000);
+        }
 
       g_source_attach (source, NULL);
       g_source_unref (source);
@@ -332,9 +435,16 @@ meta_idle_monitor_reset_idletime (MetaIdleMonitor *self)
         }
       else
         {
-          g_source_set_ready_time (watch->timeout_source,
-                                   self->last_event_time +
-                                   watch->timeout_msec * 1000);
+          if (self->inhibited)
+            {
+              g_source_set_ready_time (watch->timeout_source, -1);
+            }
+          else
+            {
+              g_source_set_ready_time (watch->timeout_source,
+                                       self->last_event_time +
+                                       watch->timeout_msec * 1000);
+            }
         }
     }
 
diff --git a/dbus/org.gnome.SessionManager.xml b/dbus/org.gnome.SessionManager.xml
index 9576bb8..5b20e5a 100644
--- a/dbus/org.gnome.SessionManager.xml
+++ b/dbus/org.gnome.SessionManager.xml
@@ -24,5 +24,7 @@
       <arg name="running" direction="out" type="b" />
     </method>
 
+    <property name="InhibitedActions" type="u" access="read" />
+
   </interface>
 </node>


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]