[geary/mjog/575-drop-libunity: 1/2] Add minimal Unity Launcher API implementation



commit 7a05541ea061530f5747b752e01a02049c2b71fd
Author: Michael Gratton <mike vee net>
Date:   Wed Nov 27 17:17:16 2019 +1100

    Add minimal Unity Launcher API implementation
    
    Hook it up to NotificationPlugin.

 src/client/plugin/notification-badge/meson.build   |   5 +-
 .../notification-badge/notification-badge.vala     |  37 ++++--
 .../notification-badge/unity-launcher-entry.vala   | 136 +++++++++++++++++++++
 3 files changed, 170 insertions(+), 8 deletions(-)
---
diff --git a/src/client/plugin/notification-badge/meson.build 
b/src/client/plugin/notification-badge/meson.build
index f15870f0..111660a2 100644
--- a/src/client/plugin/notification-badge/meson.build
+++ b/src/client/plugin/notification-badge/meson.build
@@ -5,7 +5,10 @@ if libunity.found()
   badge_dependencies = plugin_dependencies
   badge_dependencies += libunity
 
-  plugin_src = join_paths(plugin_name + '.vala')
+  plugin_src = files(
+    plugin_name + '.vala',
+    'unity-launcher-entry.vala'
+  )
   plugin_data = join_paths(plugin_name + '.plugin')
   plugin_dest = join_paths(plugins_dir, plugin_name)
 
diff --git a/src/client/plugin/notification-badge/notification-badge.vala 
b/src/client/plugin/notification-badge/notification-badge.vala
index 8285ec58..5119b36f 100644
--- a/src/client/plugin/notification-badge/notification-badge.vala
+++ b/src/client/plugin/notification-badge/notification-badge.vala
@@ -27,12 +27,30 @@ public class Plugin.NotificationBadge : Notification {
         get; construct set;
     }
 
-    private Unity.LauncherEntry? entry = null;
+    private UnityLauncherEntry? entry = null;
+
 
     public override void activate() {
-        this.entry = Unity.LauncherEntry.get_for_desktop_id(
-            Application.Client.APP_ID + ".desktop"
-        );
+        var connection = this.application.get_dbus_connection();
+        var path = this.application.get_dbus_object_path();
+        try {
+            if (connection == null || path == null) {
+                throw new GLib.IOError.NOT_CONNECTED(
+                    "Application does not have a DBus connection or path"
+                );
+            }
+            this.entry = new UnityLauncherEntry(
+                connection,
+                path + "/plugin/notificationbadge",
+                Application.Client.APP_ID + ".desktop"
+            );
+        } catch (GLib.Error error) {
+            warning(
+                "Failed to register Unity Launcher Entry: %s",
+                error.message
+            );
+        }
+
         this.context.notify["total-new-messages"].connect(on_total_changed);
         update_count();
     }
@@ -43,9 +61,14 @@ public class Plugin.NotificationBadge : Notification {
     }
 
     private void update_count() {
-        int count = this.context.total_new_messages;
-        this.entry.count = count;
-        this.entry.count_visible = (count > 0);
+        if (this.entry != null) {
+            int count = this.context.total_new_messages;
+            if (count > 0) {
+                this.entry.set_count(count);
+            } else {
+                this.entry.clear_count();
+            }
+        }
     }
 
     private void on_total_changed() {
diff --git a/src/client/plugin/notification-badge/unity-launcher-entry.vala 
b/src/client/plugin/notification-badge/unity-launcher-entry.vala
new file mode 100644
index 00000000..b01356f0
--- /dev/null
+++ b/src/client/plugin/notification-badge/unity-launcher-entry.vala
@@ -0,0 +1,136 @@
+/*
+ * Copyright 2019 Michael Gratton <mike vee net>
+ *
+ * This software is licensed under the GNU Lesser General Public License
+ * (version 2.1 or later). See the COPYING file in this distribution.
+ */
+
+/**
+ * A simple, high-level interface for the Unity Launcher API.
+ *
+ * See https://wiki.ubuntu.com/Unity/LauncherAPI for documentation.
+ */
+public class UnityLauncherEntry : Geary.BaseObject {
+
+
+    private const string DBUS_NAME = "com.canonical.Unity.LauncherEntry";
+
+
+    [DBus (name = "com.canonical.Unity.LauncherEntry")]
+    private class Entry : Geary.BaseObject {
+
+
+        public signal void update (string app_uri,
+                                   HashTable<string,Variant> properties);
+
+    }
+
+    private string app_uri;
+    private Entry entry = new Entry();
+    private GLib.DBusConnection connection;
+    private uint object_id;
+    private uint watch_id;
+
+    // Launcher entry properties
+    private int64 count = 0;
+    private bool count_visible = false;
+
+
+    /**
+     * Constructions a new launcher entry for the given DBus connection.
+     *
+     * The given path is used as the path of the DBus object that
+     * interacts with the Uniti API, and should be bus-unique. The
+     * given desktop identifier must match the name of the desktop
+     * file for the application.
+     */
+    public UnityLauncherEntry(GLib.DBusConnection connection,
+                              string dbus_path,
+                              string desktop_id)
+        throws GLib.Error {
+        this.app_uri = "application://%s".printf(desktop_id);
+        this.connection = connection;
+        this.object_id = connection.register_object(dbus_path, this.entry);
+        this.watch_id = GLib.Bus.watch_name_on_connection(
+            connection,
+            DBUS_NAME,
+            NONE,
+            on_name_appeared,
+            null
+        );
+
+        update_all();
+    }
+
+    ~UnityLauncherEntry() {
+        GLib.Bus.unwatch_name(this.watch_id);
+        this.connection.unregister_object(this.object_id);
+    }
+
+    /** Sets and shows the count for the application. */
+    public void set_count(int64 count) {
+        var props = new_properties();
+        if (this.count != count) {
+            this.count = count;
+            put_count(props);
+        }
+        if (!this.count_visible) {
+            this.count_visible = true;
+            put_count_visible(props);
+        }
+        send(props);
+    }
+
+    /** Clears and hides any count for the application. */
+    public void clear_count() {
+        var props = new_properties();
+        if (this.count != 0) {
+            this.count = 0;
+            put_count(props);
+        }
+        if (this.count_visible) {
+            this.count_visible = false;
+            put_count_visible(props);
+        }
+        send(props);
+    }
+
+    private void update_all() {
+        var props = new_properties();
+        if (this.count != 0) {
+            put_count(props);
+        }
+        if (!this.count_visible) {
+            put_count_visible(props);
+        }
+        send(props);
+    }
+
+    private void send(GLib.HashTable<string,GLib.Variant> properties) {
+        if (properties.size() > 0) {
+            this.entry.update(this.app_uri, properties);
+        }
+    }
+
+    private GLib.HashTable<string,GLib.Variant> new_properties() {
+        return new GLib.HashTable<string,GLib.Variant>(str_hash, str_equal);
+    }
+
+    private void put_count(GLib.HashTable<string,GLib.Variant> properties) {
+        properties.insert(
+            "count", new GLib.Variant.int64(this.count)
+        );
+    }
+
+    private void put_count_visible(GLib.HashTable<string,GLib.Variant> properties) {
+        properties.insert(
+            "count-visible",
+            new GLib.Variant.boolean(this.count_visible)
+        );
+    }
+
+    private void on_name_appeared() {
+        update_all();
+    }
+
+}


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