[gnome-break-timer] Use idle monitor code from libgnome-desktop



commit 0d37bd71f9f407238002af2f8adb11d0fdaaa850
Author: Dylan McCall <dylan dylanmccall ca>
Date:   Mon Nov 23 15:22:21 2020 -0800

    Use idle monitor code from libgnome-desktop
    
    In addition, add some code which polls Mutter for idle time while the
    user is active, solving an issue where the user is forced to take a
    break while watching a video.

 build-aux/flatpak/org.gnome.BreakTimer.json        |  60 +++++++-----
 meson.build                                        |   2 +
 src/common/IMutterIdleMonitor.vala                 |  31 -------
 src/common/meson.build                             |   1 -
 .../activity/MutterActivityMonitorBackend.vala     | 101 ++++++++++-----------
 src/daemon/meson.build                             |   3 +-
 6 files changed, 86 insertions(+), 112 deletions(-)
---
diff --git a/build-aux/flatpak/org.gnome.BreakTimer.json b/build-aux/flatpak/org.gnome.BreakTimer.json
index 5bc68e7..74d6334 100644
--- a/build-aux/flatpak/org.gnome.BreakTimer.json
+++ b/build-aux/flatpak/org.gnome.BreakTimer.json
@@ -19,55 +19,67 @@
         "cflags" : "-O2 -g",
         "cxxflags" : "-O2 -g",
         "env" : {
-            "V" : "1"
+            "V" : "1",
+            "LANG" : "fr_FR"
         }
     },
     "modules" : [
         {
-            "name": "libcanberra",
-            "sources": [
+            "name" : "libcanberra",
+            "sources" : [
                 {
-                    "type": "archive",
-                    "url": "http://0pointer.de/lennart/projects/libcanberra/libcanberra-0.30.tar.xz";,
-                    "sha256": "c2b671e67e0c288a69fc33dc1b6f1b534d07882c2aceed37004bf48c601afa72"
+                    "type" : "archive",
+                    "url" : "http://0pointer.de/lennart/projects/libcanberra/libcanberra-0.30.tar.xz";,
+                    "sha256" : "c2b671e67e0c288a69fc33dc1b6f1b534d07882c2aceed37004bf48c601afa72"
                 }
             ],
-            "config-opts": [
+            "config-opts" : [
                 "--disable-alsa",
                 "--disable-null",
                 "--disable-oss"
             ]
         },
         {
-            "name": "gsound",
-            "sources": [
+            "name" : "gsound",
+            "sources" : [
                 {
-                    "type": "git",
-                    "url": "https://gitlab.gnome.org/GNOME/gsound.git";,
-                    "branch": "master"
+                    "type" : "git",
+                    "url" : "https://gitlab.gnome.org/GNOME/gsound.git";,
+                    "branch" : "master"
                 }
             ]
         },
         {
-            "name": "intltool",
-            "sources": [
+            "name" : "intltool",
+            "sources" : [
                 {
-                    "type": "archive",
-                    "url": "https://launchpad.net/intltool/trunk/0.51.0/+download/intltool-0.51.0.tar.gz";,
-                    "sha256": "67c74d94196b153b774ab9f89b2fa6c6ba79352407037c8c14d5aeb334e959cd"
+                    "type" : "archive",
+                    "url" : "https://launchpad.net/intltool/trunk/0.51.0/+download/intltool-0.51.0.tar.gz";,
+                    "sha256" : "67c74d94196b153b774ab9f89b2fa6c6ba79352407037c8c14d5aeb334e959cd"
                 }
             ],
-            "cleanup": [
+            "cleanup" : [
                 "*"
             ]
         },
         {
-            "name": "sound-theme-freedesktop",
-            "sources": [
+            "name" : "sound-theme-freedesktop",
+            "sources" : [
                 {
-                    "type": "archive",
-                    "url": "http://people.freedesktop.org/~mccann/dist/sound-theme-freedesktop-0.8.tar.bz2";,
-                    "sha256": "cb518b20eef05ec2e82dda1fa89a292c1760dc023aba91b8aa69bafac85e8a14"
+                    "type" : "archive",
+                    "url" : "http://people.freedesktop.org/~mccann/dist/sound-theme-freedesktop-0.8.tar.bz2";,
+                    "sha256" : "cb518b20eef05ec2e82dda1fa89a292c1760dc023aba91b8aa69bafac85e8a14"
+                }
+            ]
+        },
+        {
+            "name" : "libgnome-desktop",
+            "buildsystem" : "meson",
+            "sources" : [
+                {
+                    "type" : "git",
+                    "url" : "https://gitlab.gnome.org/GNOME/gnome-desktop.git";,
+                    "tag" : "3.38.1"
                 }
             ]
         },
@@ -75,7 +87,7 @@
             "name" : "gnome-break-timer",
             "buildsystem" : "meson",
             "builddir" : true,
-            "run-tests": true,
+            "run-tests" : true,
             "sources" : [
                 {
                     "type" : "git",
diff --git a/meson.build b/meson.build
index 3da6539..d7209f0 100644
--- a/meson.build
+++ b/meson.build
@@ -13,6 +13,7 @@ cairo_dep = dependency('cairo')
 gio_dep = dependency('gio-2.0')
 gio_unix_dep = dependency('gio-unix-2.0')
 glib_dep = dependency('glib-2.0')
+gnome_desktop_dep = dependency('gnome-desktop-3.0')
 gobject_dep = dependency('gobject-2.0')
 gsound_dep = dependency('gsound')
 gtk_dep = dependency('gtk+-3.0')
@@ -57,6 +58,7 @@ build_conf.set_quoted('DAEMON_OBJECT_PATH', daemon_object_path)
 build_conf.set_quoted('DAEMON_BREAK_OBJECT_BASE_PATH', daemon_break_object_base_path)
 
 add_project_arguments(['-DGETTEXT_PACKAGE="' + gettext_package + '"'], language: 'c')
+add_project_arguments(['-DGNOME_DESKTOP_USE_UNSTABLE_API=1'], language: 'c')
 add_project_arguments(['--vapidir', src_dir], language: 'vala')
 
 run_script_conf = configuration_data()
diff --git a/src/common/meson.build b/src/common/meson.build
index ad251bd..015c838 100644
--- a/src/common/meson.build
+++ b/src/common/meson.build
@@ -3,7 +3,6 @@ common_lib_sources = files(
     'IBreakTimer.vala',
     'IFreedesktopApplication.vala',
     'IGnomeScreenSaver.vala',
-    'IMutterIdleMonitor.vala',
     'IPortalBackground.vala',
     'IPortalRequest.vala',
     'ISessionStatus.vala',
diff --git a/src/daemon/activity/MutterActivityMonitorBackend.vala 
b/src/daemon/activity/MutterActivityMonitorBackend.vala
index c0045c4..e4136c2 100644
--- a/src/daemon/activity/MutterActivityMonitorBackend.vala
+++ b/src/daemon/activity/MutterActivityMonitorBackend.vala
@@ -21,91 +21,82 @@ using BreakTimer.Daemon.Util;
 namespace BreakTimer.Daemon.Activity {
 
 public class MutterActivityMonitorBackend : ActivityMonitorBackend, GLib.Initable {
-    private GLib.DBusConnection dbus_connection;
-
-    private IMutterIdleMonitor? mutter_idle_monitor;
+    private Gnome.IdleMonitor? gnome_idle_monitor;
     private uint32 idle_watch_id;
     private uint32 user_active_watch_id;
 
     private uint64 last_idle_time_ms;
     private int64 last_idle_time_update_time_ms;
     private bool user_is_active;
+    private uint active_idle_poll_source_id;
 
     private const uint IDLE_WATCH_INTERVAL_MS = 1 * TimeUnit.MILLISECONDS_IN_SECONDS;
 
     public MutterActivityMonitorBackend () {
         this.user_is_active = false;
+        this.active_idle_poll_source_id = 0;
     }
 
-    ~MutterActivityMonitorBackend() {
-        if (this.mutter_idle_monitor != null && this.idle_watch_id > 0) {
-            this.mutter_idle_monitor.remove_watch (this.idle_watch_id);
+    ~MutterActivityMonitorBackend () {
+        if (this.gnome_idle_monitor != null && this.idle_watch_id > 0) {
+            this.gnome_idle_monitor.remove_watch (this.idle_watch_id);
         }
     }
 
     public override bool init (GLib.Cancellable? cancellable) throws GLib.Error {
-        this.dbus_connection = GLib.Bus.get_sync (GLib.BusType.SESSION, cancellable);
-        GLib.Bus.watch_name_on_connection (
-            this.dbus_connection,
-            "org.gnome.Mutter.IdleMonitor",
-            GLib.BusNameWatcherFlags.NONE,
-            this.mutter_idle_monitor_appeared,
-            this.mutter_idle_monitor_disappeared
+        this.gnome_idle_monitor = new Gnome.IdleMonitor ();
+        this.gnome_idle_monitor.init (cancellable);
+        this.idle_watch_id = this.gnome_idle_monitor.add_idle_watch (
+            IDLE_WATCH_INTERVAL_MS, this.idle_watch_cb
         );
         return true;
     }
 
-    private void mutter_idle_monitor_appeared () {
-        try {
-            this.mutter_idle_monitor = GLib.Bus.get_proxy_sync (
-                GLib.BusType.SESSION,
-                "org.gnome.Mutter.IdleMonitor",
-                "/org/gnome/Mutter/IdleMonitor/Core"
-            );
-            this.mutter_idle_monitor.watch_fired.connect (this.mutter_idle_monitor_watch_fired_cb);
-            this.idle_watch_id = this.mutter_idle_monitor.add_idle_watch (IDLE_WATCH_INTERVAL_MS);
-            this.update_last_idle_time();
-        } catch (GLib.IOError error) {
-            this.mutter_idle_monitor = null;
-            GLib.warning ("Error connecting to mutter idle monitor service: %s", error.message);
-        } catch (GLib.DBusError error) {
-            this.mutter_idle_monitor = null;
-            GLib.warning ("Error adding mutter idle watch: %s", error.message);
-        }
+    private void idle_watch_cb () {
+        this.update_idle_time ();
+        this.user_is_active = false;
+        this.stop_active_idle_poll ();
+        this.user_active_watch_id = this.gnome_idle_monitor.add_user_active_watch (
+            this.user_active_watch_cb
+        );
     }
 
-    private void mutter_idle_monitor_disappeared () {
-        GLib.warning ("Mutter idle monitor disappeared");
-        this.mutter_idle_monitor = null;
-        this.idle_watch_id = 0;
+    private void user_active_watch_cb () {
+        this.user_active_watch_id = 0;
+        this.update_idle_time ();
+        this.start_active_idle_poll ();
     }
 
-    private void mutter_idle_monitor_watch_fired_cb (uint32 id) {
-        if (id == this.idle_watch_id) {
-            this.user_is_active = false;
-            this.update_last_idle_time();
-            try {
-                this.user_active_watch_id = this.mutter_idle_monitor.add_user_active_watch ();
-            } catch (GLib.IOError error) {
-                GLib.warning ("Error connecting to mutter idle monitor service: %s", error.message);
-            } catch (GLib.DBusError error) {
-                GLib.warning ("Error adding mutter user active watch: %s", error.message);
-            }
-        } else if (id == this.user_active_watch_id) {
-            this.user_is_active = true;
-            this.user_active_watch_id = 0;
+    private void start_active_idle_poll () {
+        // In some cases, such as applications triggering fake events to
+        // suppress the screensaver, the active watch fires but idle time
+        // does not reset. As we are not the screensaver, we would like to
+        // treat these cases like idle time, so we will need to poll manually
+        // as long as Mutter is reporting that the user as active.
+        // TODO: Track this issue in Mutter and remove this code when possible.
+        if (this.active_idle_poll_source_id == 0) {
+            this.active_idle_poll_source_id = GLib.Timeout.add_seconds (
+                IDLE_WATCH_INTERVAL_MS / TimeUnit.MILLISECONDS_IN_SECONDS, this.active_idle_poll_cb
+            );
         }
     }
 
-    private void update_last_idle_time() {
-        try {
-            this.last_idle_time_ms = this.mutter_idle_monitor.get_idletime ();
-        } catch (GLib.IOError error) {
-            GLib.warning ("Error connecting to mutter idle monitor service: %s", error.message);
-        } catch (GLib.DBusError error) {
-            GLib.warning ("Error getting mutter idletime: %s", error.message);
+    private void stop_active_idle_poll () {
+        if (this.active_idle_poll_source_id != 0) {
+            GLib.Source.remove (this.active_idle_poll_source_id);
+            this.active_idle_poll_source_id = 0;
         }
+    }
+
+    private bool active_idle_poll_cb () {
+        this.update_idle_time ();
+        return GLib.Source.CONTINUE;
+    }
+
+    private void update_idle_time () {
+        this.last_idle_time_ms = this.gnome_idle_monitor.get_idletime ();
         this.last_idle_time_update_time_ms = TimeUnit.get_monotonic_time_ms ();
+        this.user_is_active = (this.last_idle_time_ms < IDLE_WATCH_INTERVAL_MS);
     }
 
     protected override uint64 time_since_last_event_ms () {
diff --git a/src/daemon/meson.build b/src/daemon/meson.build
index 220b65d..075b255 100644
--- a/src/daemon/meson.build
+++ b/src/daemon/meson.build
@@ -33,9 +33,10 @@ daemon_lib_dependencies = [
     config_lib_dep,
     gio_dep,
     gio_unix_dep,
+    gnome_desktop_dep,
+    gsound_dep,
     gtk_dep,
     json_glib_dep,
-    gsound_dep,
     libnotify_dep,
     m_dep,
     posix_dep,


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