[gnome-shell/wip/gtk-notification: 19/22] notificationDaemon: Implement the new GTK+ notifications API
- From: Jasper St. Pierre <jstpierre src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-shell/wip/gtk-notification: 19/22] notificationDaemon: Implement the new GTK+ notifications API
- Date: Mon, 14 Oct 2013 13:55:14 +0000 (UTC)
commit a16815515f89b6d4cd010ea5a4c3d69e46938f0b
Author: Jasper St. Pierre <jstpierre mecheye net>
Date: Sun Oct 13 13:04:02 2013 -0400
notificationDaemon: Implement the new GTK+ notifications API
The new API is designed to support features like persistence and uses
the new org.freedesktop.Application specification for activating
actions on notifications. While we won't add support for persistence
yet, implement the new notification spec with parity of the old one.
js/ui/notificationDaemon.js | 167 +++++++++++++++++++++++++++++++++++++++++++
1 files changed, 167 insertions(+), 0 deletions(-)
---
diff --git a/js/ui/notificationDaemon.js b/js/ui/notificationDaemon.js
index c267545..a899b13 100644
--- a/js/ui/notificationDaemon.js
+++ b/js/ui/notificationDaemon.js
@@ -675,10 +675,177 @@ const FdoNotificationDaemonSource = new Lang.Class({
}
});
+
+const GtkNotificationDaemonNotification = new Lang.Class({
+ Name: 'GtkNotificationDaemonNotification',
+ Extends: MessageTray.Notification,
+
+ _init: function(source, notification) {
+ let { title: title, body: body, gicon: gicon, actions: actions, defaultAction: defaultAction } =
notification;
+ this.parent(source, title.unpack(), body.unpack(), { gicon: gicon });
+
+ this._defaultAction = defaultAction ? defaultAction.unpack() : null;
+
+ if (actions)
+ actions.deep_unpack().forEach(Lang.bind(this, function([title, actionId, target]) {
+ this.addButton(title, Lang.bind(this, function() {
+ this._activateAction(actionId, target);
+ }));
+ }));
+ },
+
+ _activateAction: function(namespacedActionId, target) {
+ if (namespacedActionId.startsWith('app.')) {
+ let actionId = namespacedActionId.slice('app.'.length);
+ this.source.activateAction(actionId, target);
+ }
+ },
+
+ _onClicked: function() {
+ if (this._defaultAction)
+ this._activateAction(this._defaultAction);
+ else
+ this.source.open();
+ this.parent();
+ },
+});
+
+const FdoApplicationIface = <interface name="org.freedesktop.Application">
+<method name="ActivateAction">
+ <arg type="s" direction="in" />
+ <arg type="av" direction="in" />
+ <arg type="a{sv}" direction="in" />
+</method>
+<method name="Activate">
+ <arg type="a{sv}" direction="in" />
+</method>
+</interface>;
+const FdoApplicationProxy = Gio.DBusProxy.makeProxyWrapper(FdoApplicationIface);
+
+function objectPathFromAppId(appId) {
+ return '/' + appId.replace(/\./g, '/');
+}
+
+function getPlatformData() {
+ let startupId = GLib.Variant.new('s', '_TIME' + global.get_current_time());
+ return { "desktop-startup-id": startupId };
+}
+
+const GtkNotificationDaemonAppSource = new Lang.Class({
+ Name: 'GtkNotificationDaemonAppSource',
+ Extends: MessageTray.Source,
+
+ _init: function(appId) {
+ this._appId = appId;
+ this._objectPath = objectPathFromAppId(appId);
+
+ this._app = Shell.AppSystem.get_default().lookup_app(appId + '.desktop');
+ this._notifications = {};
+
+ this.parent(this._app.get_name());
+ },
+
+ createIcon: function(size) {
+ return this._app.create_icon_texture(size);
+ },
+
+ _createPolicy: function() {
+ return new MessageTray.NotificationApplicationPolicy(this._appId);
+ },
+
+ _createApp: function() {
+ return new FdoApplicationProxy(Gio.DBus.session, this._appId, this._objectPath);
+ },
+
+ activateAction: function(actionId, target) {
+ let app = this._createApp();
+ app.ActivateActionRemote(actionId, target, getPlatformData());
+ },
+
+ open: function() {
+ let app = this._createApp();
+ app.ActivateRemote(getPlatformData());
+ },
+
+ addNotification: function(notificationId, notificationParams) {
+ if (this._notifications[notificationId])
+ this._notifications[notificationId].destroy(MessageTray.NotificationDestroyedReason.EXPIRED);
+
+ let notification = new GtkNotificationDaemonNotification(this, notificationParams);
+ notification.connect('destroy', Lang.bind(this, function() {
+ delete this._notifications[notificationId];
+ }));
+ this._notifications[notificationId] = notification;
+
+ this.notify(notification);
+ },
+
+ removeNotification: function(notificationId) {
+ if (this._notifications[notificationId])
+
this._notifications[notificationId].destroy(MessageTray.NotificationDestroyedReason.SOURCE_CLOSED);
+ },
+});
+
+const GtkNotificationsIface = <interface name="org.gtk.Notifications">
+<method name="AddNotification">
+ <arg type="s" direction="in" />
+ <arg type="s" direction="in" />
+ <arg type="a{sv}" direction="in" />
+</method>
+<method name="RemoveNotification">
+ <arg type="s" direction="in" />
+ <arg type="s" direction="in" />
+</method>
+</interface>;
+
+const GtkNotificationDaemon = new Lang.Class({
+ Name: 'GtkNotificationDaemon',
+
+ _init: function() {
+ this._sources = {};
+
+ this._dbusImpl = Gio.DBusExportedObject.wrapJSObject(GtkNotificationsIface, this);
+ this._dbusImpl.export(Gio.DBus.session, '/org/gtk/Notifications');
+
+ Gio.DBus.session.own_name('org.gtk.Notifications', Gio.BusNameOwnerFlags.REPLACE, null, null);
+ },
+
+ _ensureAppSource: function(appId) {
+ if (this._sources[appId])
+ return this._sources[appId];
+
+ let source = new GtkNotificationDaemonAppSource(appId);
+ source.connect('destroy', Lang.bind(this, function() {
+ delete this._sources[appId];
+ }));
+ Main.messageTray.add(source);
+ this._sources[appId] = source;
+ return source;
+ },
+
+ AddNotificationAsync: function(params, invocation) {
+ let [appId, notificationId, notification] = params;
+ let source = this._ensureAppSource(appId);
+ source.addNotification(notificationId, notification);
+
+ invocation.return_value(null);
+ },
+
+ RemoveNotificationAsync: function(params, invocation) {
+ let [appId, notificationId] = params;
+ let source = this._sources[appId];
+ if (source)
+ source.removeNotification(notificationId);
+
+ invocation.return_value(null);
+ },
+});
+
const NotificationDaemon = new Lang.Class({
Name: 'NotificationDaemon',
_init: function() {
this._fdoNotificationDaemon = new FdoNotificationDaemon();
+ this._gtkNotificationDaemon = new GtkNotificationDaemon();
},
});
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]