5442266f28
If the finish function isn't specified, promisify will now try to use the async name without '_async'/'_begin' suffix (if any) and '_finish' appended. Everything except IBus uses a variation of that pattern, so there's quite a bit of boilerplate we get to remove… Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/2174>
162 lines
4.8 KiB
JavaScript
162 lines
4.8 KiB
JavaScript
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
|
/* exported NotificationDaemon */
|
|
|
|
const { Gio, GLib } = imports.gi;
|
|
|
|
const { loadInterfaceXML } = imports.misc.fileUtils;
|
|
const { ServiceImplementation } = imports.dbusService;
|
|
|
|
const NotificationsIface = loadInterfaceXML('org.freedesktop.Notifications');
|
|
const NotificationsProxy = Gio.DBusProxy.makeProxyWrapper(NotificationsIface);
|
|
|
|
Gio._promisify(Gio.DBusConnection.prototype, 'call');
|
|
|
|
var NotificationDaemon = class extends ServiceImplementation {
|
|
constructor() {
|
|
super(NotificationsIface, '/org/freedesktop/Notifications');
|
|
|
|
this._autoShutdown = false;
|
|
|
|
this._activeNotifications = new Map();
|
|
|
|
this._proxy = new NotificationsProxy(Gio.DBus.session,
|
|
'org.gnome.Shell',
|
|
'/org/freedesktop/Notifications',
|
|
(proxy, error) => {
|
|
if (error)
|
|
log(error.message);
|
|
});
|
|
|
|
this._proxy.connectSignal('ActionInvoked',
|
|
(proxy, sender, params) => {
|
|
const [id] = params;
|
|
this._emitSignal(
|
|
this._activeNotifications.get(id),
|
|
'ActionInvoked',
|
|
new GLib.Variant('(us)', params));
|
|
});
|
|
this._proxy.connectSignal('NotificationClosed',
|
|
(proxy, sender, params) => {
|
|
const [id] = params;
|
|
this._emitSignal(
|
|
this._activeNotifications.get(id),
|
|
'NotificationClosed',
|
|
new GLib.Variant('(uu)', params));
|
|
this._activeNotifications.delete(id);
|
|
});
|
|
}
|
|
|
|
_emitSignal(sender, signalName, params) {
|
|
if (!sender)
|
|
return;
|
|
this._dbusImpl.get_connection()?.emit_signal(
|
|
sender,
|
|
this._dbusImpl.get_object_path(),
|
|
'org.freedesktop.Notifications',
|
|
signalName,
|
|
params);
|
|
}
|
|
|
|
_untrackSender(sender) {
|
|
super._untrackSender(sender);
|
|
|
|
this._activeNotifications.forEach((value, key) => {
|
|
if (value === sender)
|
|
this._activeNotifications.delete(key);
|
|
});
|
|
}
|
|
|
|
_checkNotificationId(invocation, id) {
|
|
if (id === 0)
|
|
return true;
|
|
|
|
if (!this._activeNotifications.has(id))
|
|
return true;
|
|
|
|
if (this._activeNotifications.get(id) === invocation.get_sender())
|
|
return true;
|
|
|
|
const error = new GLib.Error(Gio.DBusError,
|
|
Gio.DBusError.INVALID_ARGS, 'Invalid notification ID');
|
|
this._handleError(invocation, error);
|
|
return false;
|
|
}
|
|
|
|
register() {
|
|
Gio.DBus.session.own_name(
|
|
'org.freedesktop.Notifications',
|
|
Gio.BusNameOwnerFlags.REPLACE,
|
|
null, null);
|
|
}
|
|
|
|
async NotifyAsync(params, invocation) {
|
|
const sender = invocation.get_sender();
|
|
const pid = await this._getSenderPid(sender);
|
|
const replaceId = params[1];
|
|
const hints = params[6];
|
|
|
|
if (!this._checkNotificationId(invocation, replaceId))
|
|
return;
|
|
|
|
params[6] = {
|
|
...hints,
|
|
'sender-pid': new GLib.Variant('u', pid),
|
|
};
|
|
|
|
this._proxy.NotifyRemote(...params, (res, error) => {
|
|
if (this._handleError(invocation, error))
|
|
return;
|
|
|
|
const [id] = res;
|
|
this._activeNotifications.set(id, sender);
|
|
invocation.return_value(new GLib.Variant('(u)', res));
|
|
});
|
|
}
|
|
|
|
CloseNotificationAsync(params, invocation) {
|
|
const [id] = params;
|
|
if (!this._checkNotificationId(invocation, id))
|
|
return;
|
|
|
|
this._proxy.CloseNotificationRemote(...params, (res, error) => {
|
|
if (this._handleError(invocation, error))
|
|
return;
|
|
|
|
invocation.return_value(null);
|
|
});
|
|
}
|
|
|
|
GetCapabilitiesAsync(params, invocation) {
|
|
this._proxy.GetCapabilitiesRemote(...params, (res, error) => {
|
|
if (this._handleError(invocation, error))
|
|
return;
|
|
|
|
invocation.return_value(new GLib.Variant('(as)', res));
|
|
});
|
|
}
|
|
|
|
GetServerInformationAsync(params, invocation) {
|
|
this._proxy.GetServerInformationRemote(...params, (res, error) => {
|
|
if (this._handleError(invocation, error))
|
|
return;
|
|
|
|
invocation.return_value(new GLib.Variant('(ssss)', res));
|
|
});
|
|
}
|
|
|
|
async _getSenderPid(sender) {
|
|
const res = await Gio.DBus.session.call(
|
|
'org.freedesktop.DBus',
|
|
'/',
|
|
'org.freedesktop.DBus',
|
|
'GetConnectionUnixProcessID',
|
|
new GLib.Variant('(s)', [sender]),
|
|
new GLib.VariantType('(u)'),
|
|
Gio.DBusCallFlags.NONE,
|
|
-1,
|
|
null);
|
|
const [pid] = res.deepUnpack();
|
|
return pid;
|
|
}
|
|
};
|