summaryrefslogtreecommitdiff
path: root/lib/notifd/notifd.vala
blob: c9628620e93b4be7bc359f9494ffe7e60c8d23d3 (plain)
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
132
133
134
135
136
137
138
139
140
namespace AstalNotifd {
    public Notifd get_default() {
        return Notifd.get_default();
    }
}

public class AstalNotifd.Notifd : Object {
    private static Notifd _instance;
    public static Notifd get_default() {
        if (_instance == null)
            _instance = new Notifd();

        return _instance;
    }

    private Daemon daemon;
    private DaemonProxy proxy;

    public signal void active(ActiveType type);

    public bool ignore_timeout {
        get {
            return proxy != null ? proxy.ignore_timeout : daemon.ignore_timeout;
        }
        set {
            if (proxy != null)
                proxy.ignore_timeout = value;
            else
                daemon.ignore_timeout = value;
        }
    }

    public bool dont_disturb {
        get {
            return proxy != null ? proxy.dont_disturb : daemon.dont_disturb;
        }
        set {
            if (proxy != null)
                proxy.dont_disturb = value;
            else
                daemon.dont_disturb = value;
        }
    }

    public List<weak Notification> notifications {
        owned get { return proxy != null ? proxy.notifications : daemon.notifications; }
    }

    public uint[] notification_ids() throws Error {
        return proxy != null ? proxy.notification_ids() : daemon.notification_ids();
    }

    public Notification get_notification(uint id) {
        return proxy != null ? proxy.get_notification(id) : daemon.get_notification(id);
    }

    public string get_notification_json(uint id) {
        return get_notification(id).to_json_string();
    }

    public signal void notified(uint id, bool replaced);
    public signal void resolved(uint id, ClosedReason reason);

    construct {
        // hack to make it synchronous
        MainLoop? loop = null;

        if (!MainContext.default().is_owner()) {
            loop = new MainLoop();
        }

        bool done = false;

        Bus.own_name(
            BusType.SESSION,
            "org.freedesktop.Notifications",
            BusNameOwnerFlags.NONE,
            acquire_daemon,
            on_daemon_acquired,
            make_proxy
        );

        active.connect(() => {
            done = true;
            if (loop != null && loop.is_running()) {
                loop.quit();
            }
        });

        if (loop != null) {
            loop.run();
        } else {
            while (!done) {
                MainContext.default().iteration(false);
            }
        }
    }

    private void acquire_daemon(DBusConnection conn) {
        daemon = new Daemon().register(conn);
    }

    private void on_daemon_acquired() {
        if (proxy != null) {
            proxy.stop();
            proxy = null;
        }
        daemon.notified.connect((id, replaced) => notified(id, replaced));
        daemon.resolved.connect((id, reason) => resolved(id, reason));
        daemon.notify.connect((prop) => {
            if (get_class().find_property(prop.name) != null) {
                notify_property(prop.name);
            }
        });
        active(ActiveType.DAEMON);
    }

    private void make_proxy() {
        proxy = new DaemonProxy();

        if (proxy.start()) {
            active(ActiveType.PROXY);
        } else {
            return;
        }

        proxy.notified.connect((id, replaced) => notified(id, replaced));
        proxy.resolved.connect((id, reason) => resolved(id, reason));
        proxy.notify.connect((prop) => {
            if (get_class().find_property(prop.name) != null) {
                notify_property(prop.name);
            }
        });
    }
}

public enum AstalNotifd.ActiveType {
    DAEMON,
    PROXY,
}