1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
|
[DBus (name = "org.freedesktop.Notifications")]
internal interface AstalNotifd.IDaemon : DBusProxy {
public abstract bool ignore_timeout { get; set; }
public abstract bool dont_disturb { get; set; }
public abstract uint[] notification_ids() throws DBusError, IOError;
public abstract string get_notification_json(uint id) throws DBusError, IOError;
public signal void notified(uint id, bool replaced);
public signal void resolved(uint id, ClosedReason reason);
public signal void prop_changed(string prop);
public abstract void emit_resolved(uint id, ClosedReason reason);
public abstract void emit_action_invoked(uint id, string action);
}
internal class AstalNotifd.DaemonProxy : Object {
private HashTable<uint, Notification> notifs =
new HashTable<uint, Notification>((i) => i, (a, b) => a == b);
public List<weak Notification> notifications {
owned get { return notifs.get_values(); }
}
public bool ignore_timeout {
get { return proxy.ignore_timeout; }
set { proxy.ignore_timeout = value; }
}
public bool dont_disturb {
get { return proxy.dont_disturb; }
set { proxy.dont_disturb = value; }
}
public Notification get_notification(uint id) {
return notifs.get(id);
}
public signal void notified(uint id, bool replaced);
public signal void resolved(uint id, ClosedReason reason);
private IDaemon proxy;
private List<ulong> ids = new List<ulong>();
public void stop() {
foreach (var id in ids) {
SignalHandler.disconnect(proxy, id);
}
}
public bool start() {
try {
var bus = Bus.get_sync(BusType.SESSION, null);
var variant = bus.call_sync(
"org.freedesktop.Notifications",
"/org/freedesktop/Notifications",
"org.freedesktop.Notifications",
"GetServerInformation",
null,
null,
DBusCallFlags.NONE,
-1,
null);
var name = variant.get_child_value(0).get_string();
var vendor = variant.get_child_value(1).get_string();
var version = variant.get_child_value(2).get_string();
var running = name == Daemon.name
&& vendor == Daemon.vendor
&& version == Daemon.version;
if (running) {
setup_proxy();
return true;
} else {
critical("cannot get proxy: %s is already running", name);
}
} catch (Error err) {
critical("cannot get proxy: %s", err.message);
}
return false;
}
private void setup_proxy() throws Error {
proxy = Bus.get_proxy_sync(
BusType.SESSION,
"org.freedesktop.Notifications",
"/org/freedesktop/Notifications"
);
foreach (var id in proxy.notification_ids())
add_notification(id);
ids.append(proxy.prop_changed.connect((prop) => {
if (prop == "dont-disturb") {
proxy.set_cached_property("DontDisturb", null);
notify_property(prop);
}
if (prop == "ignore-timeout") {
proxy.set_cached_property("IgnoreTimeout", null);
notify_property(prop);
}
}));
ids.append(proxy.notified.connect((id, replaced) => {
add_notification(id);
notified(id, replaced);
notify_property("notifications");
}));
ids.append(proxy.resolved.connect((id, reason) => {
notifs.remove(id);
resolved(id, reason);
notify_property("notifications");
}));
}
private void add_notification(uint id) {
try {
var n = Notification.from_json_string(proxy.get_notification_json(id));
proxy.resolved.connect((id, reason) => n.resolved(reason));
n.dismissed.connect(() => proxy.emit_resolved(id, ClosedReason.DISMISSED_BY_USER));
n.invoked.connect((action) => proxy.emit_action_invoked(id, action));
notifs.set(id, n);
} catch (Error err) {
critical(err.message);
}
}
}
|