From 60046aaa4fab3e7b3c996bef22f7530376d21321 Mon Sep 17 00:00:00 2001 From: Marina Zhurakhinskaya Date: Mon, 15 Feb 2010 12:27:28 -0500 Subject: [PATCH] Switch to the corresponding app when the notification icon is clicked This adds some meaningful functionality to the notification icons in the tray and in the notification pop-up and allows to switch to the application that sent the notification. We get the application from the notification context and set it on the source for the notification. --- js/ui/messageTray.js | 6 +++++ js/ui/notificationDaemon.js | 54 +++++++++++++++++++++++++++++++++++++ 2 files changed, 60 insertions(+) diff --git a/js/ui/messageTray.js b/js/ui/messageTray.js index b85ca6e42..85cc66b67 100644 --- a/js/ui/messageTray.js +++ b/js/ui/messageTray.js @@ -85,12 +85,18 @@ Notification.prototype = { } let icon = this.source.createIcon(ICON_SIZE); + icon.reactive = true; this.actor.add(icon, { row: 0, col: 0, x_expand: false, y_expand: false, y_fill: false }); + icon.connect('button-release-event', Lang.bind(this, + function () { + this.source.clicked(); + })); + // The first line should have the title, followed by the // banner text, but ellipsized if they won't both fit. We can't // make St.Table or St.BoxLayout do this the way we want (don't diff --git a/js/ui/notificationDaemon.js b/js/ui/notificationDaemon.js index b94b4c439..de747141e 100644 --- a/js/ui/notificationDaemon.js +++ b/js/ui/notificationDaemon.js @@ -12,6 +12,26 @@ const Params = imports.misc.params; let nextNotificationId = 1; +// Should really be defined in dbus.js +const BusIface = { + name: 'org.freedesktop.DBus', + methods: [{ name: 'GetConnectionUnixProcessID', + inSignature: 's', + outSignature: 'i' }] +} + +const Bus = function () { + this._init(); +} + +Bus.prototype = { + _init: function() { + DBus.session.proxifyObject(this, 'org.freedesktop.DBus', '/org/freedesktop/DBus'); + } +} + +DBus.proxifyPrototype(Bus.prototype, BusIface); + const NotificationDaemonIface = { name: 'org.freedesktop.Notifications', methods: [{ name: 'Notify', @@ -119,6 +139,13 @@ NotificationDaemon.prototype = { source.destroy(); this._emitNotificationClosed(id, NotificationClosedReason.DISMISSED); })); + + let sender = DBus.getCurrentMessageContext().sender; + let busProxy = new Bus(); + busProxy.GetConnectionUnixProcessIDRemote(sender, function (result, excp) { + let app = Shell.WindowTracker.get_default().get_app_from_pid(result); + source.setApp(app); + }); } summary = GLib.markup_escape_text(summary, -1); @@ -200,6 +227,9 @@ Source.prototype = { this._icon = icon; this._iconData = hints.icon_data; this._urgency = hints.urgency; + + this.app = null; + this._openAppRequested = false; }, createIcon: function(size) { @@ -231,5 +261,29 @@ Source.prototype = { } return textureCache.load_icon_name(stockIcon, size); } + }, + + clicked: function() { + this.openApp(); + MessageTray.Source.prototype.clicked.call(this); + }, + + setApp: function(app) { + this.app = app; + if (this._openAppRequested) + this.openApp(); + }, + + openApp: function() { + if (this.app == null) { + this._openAppRequested = true; + return; + } + let windows = this.app.get_windows(); + if (windows.length > 0) { + let mostRecentWindow = windows[0]; + Main.activateWindow(mostRecentWindow); + } + this._openAppRequested = false; } };