mirror of
https://github.com/zoriya/astal.git
synced 2026-06-02 02:05:09 +00:00
136 lines
4.0 KiB
Vala
136 lines
4.0 KiB
Vala
namespace AstalTray {
|
|
[DBus (name="org.kde.StatusNotifierWatcher")]
|
|
internal interface IWatcher : Object {
|
|
public abstract string[] RegisteredStatusNotifierItems { owned get; }
|
|
public abstract int ProtocolVersion { owned get; }
|
|
|
|
public abstract void RegisterStatusNotifierItem(string service, BusName sender) throws DBusError, IOError;
|
|
public abstract void RegisterStatusNotifierHost(string service) throws DBusError, IOError;
|
|
|
|
public signal void StatusNotifierItemRegistered(string service);
|
|
public signal void StatusNotifierItemUnregistered(string service);
|
|
public signal void StatusNotifierHostRegistered();
|
|
public signal void StatusNotifierHostUnregistered();
|
|
}
|
|
|
|
public Tray get_default() {
|
|
return Tray.get_default();
|
|
}
|
|
|
|
public class Tray : Object {
|
|
private static Tray? instance;
|
|
public static unowned Tray get_default() {
|
|
if (instance == null)
|
|
instance = new Tray();
|
|
|
|
return instance;
|
|
}
|
|
|
|
private StatusNotifierWatcher watcher;
|
|
private IWatcher proxy;
|
|
|
|
private HashTable<string, TrayItem> _items =
|
|
new HashTable<string, TrayItem>(str_hash, str_equal);
|
|
|
|
public List<weak TrayItem> items { owned get { return _items.get_values(); }}
|
|
|
|
public signal void item_added(string service) {
|
|
notify_property("items");
|
|
}
|
|
|
|
public signal void item_removed(string service) {
|
|
notify_property("items");
|
|
}
|
|
|
|
construct {
|
|
try {
|
|
Bus.own_name(
|
|
BusType.SESSION,
|
|
"org.kde.StatusNotifierWatcher",
|
|
BusNameOwnerFlags.NONE,
|
|
start_watcher,
|
|
() => {
|
|
if (proxy != null) {
|
|
proxy = null;
|
|
}
|
|
},
|
|
start_host
|
|
);
|
|
} catch (Error err) {
|
|
critical(err.message);
|
|
}
|
|
|
|
}
|
|
|
|
private void start_watcher(DBusConnection conn) {
|
|
try {
|
|
watcher = new StatusNotifierWatcher();
|
|
conn.register_object("/StatusNotifierWatcher", watcher);
|
|
watcher.StatusNotifierItemRegistered.connect(on_item_register);
|
|
watcher.StatusNotifierItemUnregistered.connect(on_item_unregister);
|
|
} catch (Error err) {
|
|
critical(err.message);
|
|
}
|
|
}
|
|
|
|
private void start_host() {
|
|
if (proxy != null)
|
|
return;
|
|
|
|
try {
|
|
proxy = Bus.get_proxy_sync(BusType.SESSION,
|
|
"org.kde.StatusNotifierWatcher",
|
|
"/StatusNotifierWatcher");
|
|
|
|
proxy.StatusNotifierItemRegistered.connect(on_item_register);
|
|
proxy.StatusNotifierItemUnregistered.connect(on_item_unregister);
|
|
|
|
proxy.notify["g-name-owner"].connect(() => {
|
|
_items.foreach((service, _) => {
|
|
item_removed(service);
|
|
});
|
|
|
|
_items.remove_all();
|
|
|
|
if(proxy != null) {
|
|
foreach (string item in proxy.RegisteredStatusNotifierItems) {
|
|
on_item_register(item);
|
|
}
|
|
} else {
|
|
foreach (string item in watcher.RegisteredStatusNotifierItems) {
|
|
on_item_register(item);
|
|
}
|
|
}
|
|
});
|
|
|
|
foreach (string item in proxy.RegisteredStatusNotifierItems) {
|
|
on_item_register(item);
|
|
}
|
|
} catch (Error err) {
|
|
critical("cannot get proxy: %s", err.message);
|
|
}
|
|
}
|
|
|
|
private void on_item_register(string service) {
|
|
if (_items.contains(service))
|
|
return;
|
|
|
|
var parts = service.split("/", 2);
|
|
TrayItem item = new TrayItem(parts[0], "/" + parts[1]);
|
|
item.ready.connect(() => {
|
|
_items.set(service, item);
|
|
item_added(service);
|
|
});
|
|
}
|
|
|
|
private void on_item_unregister(string service) {
|
|
_items.remove(service);
|
|
item_removed(service);
|
|
}
|
|
|
|
public TrayItem get_item(string service) {
|
|
return _items.get(service);
|
|
}
|
|
}
|
|
}
|