1/* 2 * Copyright 2019 Michael Gratton <mike@vee.net> 3 * 4 * This software is licensed under the GNU Lesser General Public License 5 * (version 2.1 or later). See the COPYING file in this distribution. 6 */ 7 8/** 9 * A simple, high-level interface for the Unity Launcher API. 10 * 11 * See https://wiki.ubuntu.com/Unity/LauncherAPI for documentation. 12 */ 13public class UnityLauncherEntry : Geary.BaseObject { 14 15 16 private const string DBUS_NAME = "com.canonical.Unity.LauncherEntry"; 17 18 19 [DBus (name = "com.canonical.Unity.LauncherEntry")] 20 private class Entry : Geary.BaseObject { 21 22 23 public signal void update (string app_uri, 24 HashTable<string,Variant> properties); 25 26 } 27 28 private string app_uri; 29 private Entry entry = new Entry(); 30 private GLib.DBusConnection connection; 31 private uint object_id; 32 private uint watch_id; 33 34 // Launcher entry properties 35 private int64 count = 0; 36 private bool count_visible = false; 37 38 39 /** 40 * Constructions a new launcher entry for the given DBus connection. 41 * 42 * The given path is used as the path of the DBus object that 43 * interacts with the Uniti API, and should be bus-unique. The 44 * given desktop identifier must match the name of the desktop 45 * file for the application. 46 */ 47 public UnityLauncherEntry(GLib.DBusConnection connection, 48 string dbus_path, 49 string desktop_id) 50 throws GLib.Error { 51 this.app_uri = "application://%s".printf(desktop_id); 52 this.connection = connection; 53 this.object_id = connection.register_object(dbus_path, this.entry); 54 this.watch_id = GLib.Bus.watch_name_on_connection( 55 connection, 56 DBUS_NAME, 57 NONE, 58 on_name_appeared, 59 null 60 ); 61 62 update_all(); 63 } 64 65 ~UnityLauncherEntry() { 66 GLib.Bus.unwatch_name(this.watch_id); 67 this.connection.unregister_object(this.object_id); 68 } 69 70 /** Sets and shows the count for the application. */ 71 public void set_count(int64 count) { 72 var props = new_properties(); 73 if (this.count != count) { 74 this.count = count; 75 put_count(props); 76 } 77 if (!this.count_visible) { 78 this.count_visible = true; 79 put_count_visible(props); 80 } 81 send(props); 82 } 83 84 /** Clears and hides any count for the application. */ 85 public void clear_count() { 86 var props = new_properties(); 87 if (this.count != 0) { 88 this.count = 0; 89 put_count(props); 90 } 91 if (this.count_visible) { 92 this.count_visible = false; 93 put_count_visible(props); 94 } 95 send(props); 96 } 97 98 private void update_all() { 99 var props = new_properties(); 100 if (this.count != 0) { 101 put_count(props); 102 } 103 if (!this.count_visible) { 104 put_count_visible(props); 105 } 106 send(props); 107 } 108 109 private void send(GLib.HashTable<string,GLib.Variant> properties) { 110 if (properties.size() > 0) { 111 this.entry.update(this.app_uri, properties); 112 } 113 } 114 115 private GLib.HashTable<string,GLib.Variant> new_properties() { 116 return new GLib.HashTable<string,GLib.Variant>(str_hash, str_equal); 117 } 118 119 private void put_count(GLib.HashTable<string,GLib.Variant> properties) { 120 properties.insert( 121 "count", new GLib.Variant.int64(this.count) 122 ); 123 } 124 125 private void put_count_visible(GLib.HashTable<string,GLib.Variant> properties) { 126 properties.insert( 127 "count-visible", 128 new GLib.Variant.boolean(this.count_visible) 129 ); 130 } 131 132 private void on_name_appeared() { 133 update_all(); 134 } 135 136} 137