[gnome-shell/wip/new-notifications: 565/569] system tray elsewhere



commit a4091adbf249c06476f6949b2ba56dba8c431101
Author: Jasper St. Pierre <jstpierre mecheye net>
Date:   Wed May 28 15:41:46 2014 -0400

    system tray elsewhere

 data/theme/gnome-shell.css  |   18 +++++++++
 js/ui/messageTray.js        |   86 +++++++++++++++++++++++++++++++++++++----
 js/ui/notificationDaemon.js |   90 +++++-------------------------------------
 3 files changed, 107 insertions(+), 87 deletions(-)
---
diff --git a/data/theme/gnome-shell.css b/data/theme/gnome-shell.css
index bee1687..d76ab53 100644
--- a/data/theme/gnome-shell.css
+++ b/data/theme/gnome-shell.css
@@ -1495,6 +1495,24 @@ StScrollBar StButton#vhandle:active {
     background: #2e3436 url(message-tray-background.png);
     background-repeat: repeat;
     height: 72px;
+
+    padding-right: 8px;
+}
+
+.system-tray-icons {
+    border-radius: 8px;
+    border: 1px solid #4c4c4c;
+}
+
+.system-tray-icon-button {
+    padding: 8px;
+
+    width: 22px;
+    height: 22px;
+}
+
+.system-tray-icon-button:hover {
+    background: 1px solid #4c4c4c;
 }
 
 .message-tray-summary {
diff --git a/js/ui/messageTray.js b/js/ui/messageTray.js
index 5f5c16a..41a08e1 100644
--- a/js/ui/messageTray.js
+++ b/js/ui/messageTray.js
@@ -1070,7 +1070,7 @@ const Source = new Lang.Class({
     },
 
     get isClearable() {
-        return !this.trayIcon && !this.isChat;
+        return !this.isChat;
     },
 
     countUpdated: function() {
@@ -1631,6 +1631,71 @@ const MessageTrayIndicator = new Lang.Class({
     },
 });
 
+const SystemTrayIconButton = new Lang.Class({
+    Name: 'SystemTrayIconButton',
+
+    _init: function(trayIcon) {
+        this._trayIcon = trayIcon;
+
+        this.actor = new St.Button({ style_class: 'system-tray-icon-button',
+                                     track_hover: true,
+                                     can_focus: true,
+                                     reactive: true });
+        this.actor.connect('clicked', Lang.bind(this, this._onClicked));
+        this.actor.set_child(this._trayIcon);
+
+        this._trayIcon.connect('destroy', Lang.bind(this, function() {
+            this.actor.set_child(null);
+            this.actor.destroy();
+        }));
+    },
+
+    _onClicked: function() {
+        let event = Clutter.get_current_event();
+
+        let id = global.stage.connect('deactivate', Lang.bind(this, function() {
+            global.stage.disconnect(id);
+            this._trayIcon.click(event);
+        }));
+
+        this.emit('clicked');
+
+        Main.overview.hide();
+        return true;
+    },
+});
+Signals.addSignalMethods(SystemTrayIconButton.prototype);
+
+const SystemTraySection = new Lang.Class({
+    Name: 'SystemTraySection',
+
+    _init: function(tray) {
+        this._tray = tray;
+
+        this.actor = new St.BoxLayout({ style_class: 'system-tray-icons',
+                                        y_align: Clutter.ActorAlign.CENTER,
+                                        y_expand: true });
+
+        this._trayManager = new Shell.TrayManager();
+        this._trayManager.connect('tray-icon-added', Lang.bind(this, this._onTrayIconAdded));
+        this._trayManager.connect('tray-icon-removed', Lang.bind(this, this._onTrayIconRemoved));
+
+        this._trayManager.manage_screen(global.screen, this.actor);
+    },
+
+    _onTrayIconAdded: function(manager, trayIcon) {
+        let button = new SystemTrayIconButton(trayIcon);
+        button.connect('clicked', Lang.bind(this, function() {
+            this._tray.close();
+        }));
+        this.actor.add_child(button.actor);
+    },
+
+    _onTrayIconRemoved: function(manager, trayIcon) {
+        trayIcon.destroy();
+    },
+});
+
 const MessageTray = new Lang.Class({
     Name: 'MessageTray',
 
@@ -1683,13 +1748,18 @@ const MessageTray = new Lang.Class({
             return Clutter.EVENT_PROPAGATE;
         }));
         global.focus_manager.add_group(this.actor);
-        this._summary = new St.BoxLayout({ style_class: 'message-tray-summary',
-                                           reactive: true,
-                                           x_align: Clutter.ActorAlign.END,
-                                           x_expand: true,
-                                           y_align: Clutter.ActorAlign.CENTER,
-                                           y_expand: true });
-        this.actor.add_actor(this._summary);
+
+        this._summaryGroup = new St.BoxLayout({ x_align: Clutter.ActorAlign.END,
+                                                x_expand: true,
+                                                y_align: Clutter.ActorAlign.CENTER,
+                                                y_expand: true });
+        this.actor.add_child(this._summaryGroup);
+
+        this._summary = new St.BoxLayout({ style_class: 'message-tray-summary' });
+        this._summaryGroup.add_child(this._summary);
+
+        this._systemTray = new SystemTraySection(this);
+        this._summaryGroup.add_child(this._systemTray.actor);
 
         this._summaryMotionId = 0;
 
diff --git a/js/ui/notificationDaemon.js b/js/ui/notificationDaemon.js
index 9b2d29c..ed8006c 100644
--- a/js/ui/notificationDaemon.js
+++ b/js/ui/notificationDaemon.js
@@ -105,16 +105,10 @@ const FdoNotificationDaemon = new Lang.Class({
 
         this._nextNotificationId = 1;
 
-        this._trayManager = new Shell.TrayManager();
-        this._trayIconAddedId = this._trayManager.connect('tray-icon-added', Lang.bind(this, 
this._onTrayIconAdded));
-        this._trayIconRemovedId = this._trayManager.connect('tray-icon-removed', Lang.bind(this, 
this._onTrayIconRemoved));
-
         Shell.WindowTracker.get_default().connect('notify::focus-app',
             Lang.bind(this, this._onFocusAppChanged));
         Main.overview.connect('hidden',
             Lang.bind(this, this._onFocusAppChanged));
-
-        this._trayManager.manage_screen(global.screen, Main.messageTray.actor);
     },
 
     _imageForNotificationData: function(hints) {
@@ -155,28 +149,23 @@ const FdoNotificationDaemon = new Lang.Class({
         return null;
     },
 
-    _lookupSource: function(title, pid, trayIcon) {
+    _lookupSource: function(title, pid) {
         for (let i = 0; i < this._sources.length; i++) {
             let source = this._sources[i];
-            if (source.pid == pid &&
-                (source.initialTitle == title || source.trayIcon || trayIcon))
+            if (source.pid == pid && source.initialTitle == title)
                 return source;
         }
         return null;
     },
 
     // Returns the source associated with ndata.notification if it is set.
-    // If the existing or requested source is associated with a tray icon
-    // and passed in pid matches a pid of an existing source, the title
-    // match is ignored to enable representing a tray icon and notifications
-    // from the same application with a single source.
     //
     // If no existing source is found, a new source is created as long as
     // pid is provided.
     //
     // Either a pid or ndata.notification is needed to retrieve or
     // create a source.
-    _getSource: function(title, pid, ndata, sender, trayIcon) {
+    _getSource: function(title, pid, ndata, sender) {
         if (!pid && !(ndata && ndata.notification))
             return null;
 
@@ -187,13 +176,13 @@ const FdoNotificationDaemon = new Lang.Class({
         if (ndata && ndata.notification)
             return ndata.notification.source;
 
-        let source = this._lookupSource(title, pid, trayIcon);
+        let source = this._lookupSource(title, pid);
         if (source) {
             source.setTitle(title);
             return source;
         }
 
-        let source = new FdoNotificationDaemonSource(title, pid, sender, trayIcon, ndata ? 
ndata.hints['desktop-entry'] : null);
+        let source = new FdoNotificationDaemonSource(title, pid, sender, ndata ? 
ndata.hints['desktop-entry'] : null);
 
         this._sources.push(source);
         source.connect('destroy', Lang.bind(this, function() {
@@ -485,26 +474,15 @@ const FdoNotificationDaemon = new Lang.Class({
         this._dbusImpl.emit_signal('ActionInvoked',
                                    GLib.Variant.new('(us)', [id, action]));
     },
-
-    _onTrayIconAdded: function(o, icon) {
-        let source = this._getSource(icon.title || icon.wm_class || C_("program", "Unknown"), icon.pid, 
null, null, icon);
-    },
-
-    _onTrayIconRemoved: function(o, icon) {
-        let source = this._lookupSource(null, icon.pid, true);
-        if (source)
-            source.destroy();
-    }
 });
 
 const FdoNotificationDaemonSource = new Lang.Class({
     Name: 'FdoNotificationDaemonSource',
     Extends: MessageTray.Source,
 
-    _init: function(title, pid, sender, trayIcon, appId) {
+    _init: function(title, pid, sender, appId) {
         // Need to set the app before chaining up, so
         // methods called from the parent constructor can find it
-        this.trayIcon = trayIcon;
         this.pid = pid;
         this.app = this._getApp(appId);
 
@@ -524,12 +502,6 @@ const FdoNotificationDaemonSource = new Lang.Class({
                                                               Lang.bind(this, this._onNameVanished));
         else
             this._nameWatcherId = 0;
-
-        if (this.trayIcon) {
-            // Try again finding the app, using the WM_CLASS from the tray icon
-            this._setSummaryIcon(this.trayIcon);
-            this.useNotificationIcon = false;
-        }
     },
 
     _createPolicy: function() {
@@ -545,17 +517,15 @@ const FdoNotificationDaemonSource = new Lang.Class({
         // Destroy the notification source when its sender is removed from DBus.
         // Only do so if this.app is set to avoid removing "notify-send" sources, senders
         // of which аre removed from DBus immediately.
-        // Sender being removed from DBus would normally result in a tray icon being removed,
-        // so allow the code path that handles the tray icon being removed to handle that case.
-        if (!this.trayIcon && this.app)
+        if (this.app)
             this.destroy();
     },
 
     processNotification: function(notification, gicon) {
         if (gicon)
             this._gicon = gicon;
-        if (!this.trayIcon)
-            this.iconUpdated();
+
+        this.iconUpdated();
 
         let tracker = Shell.WindowTracker.get_default();
         if (this.app && tracker.focus_app == this.app)
@@ -564,29 +534,6 @@ const FdoNotificationDaemonSource = new Lang.Class({
             this.notify(notification);
     },
 
-    handleSummaryClick: function(button) {
-        if (!this.trayIcon)
-            return false;
-
-        let event = Clutter.get_current_event();
-
-        // Left clicks are passed through only where there aren't unacknowledged
-        // notifications, so it possible to open them in summary mode; right
-        // clicks are always forwarded, as the right click menu is not useful for
-        // tray icons
-        if (button == 1 &&
-            this.notifications.length > 0)
-            return false;
-
-        let id = global.stage.connect('deactivate', Lang.bind(this, function () {
-            global.stage.disconnect(id);
-            this.trayIcon.click(event);
-        }));
-
-        Main.overview.hide();
-        return true;
-    },
-
     _getApp: function(appId) {
         let app;
 
@@ -594,16 +541,6 @@ const FdoNotificationDaemonSource = new Lang.Class({
         if (app != null)
             return app;
 
-        if (this.trayIcon) {
-            app = Shell.AppSystem.get_default().lookup_startup_wmclass(this.trayIcon.wm_class);
-            if (app != null)
-                return app;
-
-            app = Shell.AppSystem.get_default().lookup_desktop_wmclass(this.trayIcon.wm_class);
-            if (app != null)
-                return app;
-        }
-
         if (appId) {
             app = Shell.AppSystem.get_default().lookup_app(appId + '.desktop');
             if (app != null)
@@ -629,8 +566,7 @@ const FdoNotificationDaemonSource = new Lang.Class({
     },
 
     _lastNotificationRemoved: function() {
-        if (!this.trayIcon)
-            this.destroy();
+        this.destroy();
     },
 
     openApp: function() {
@@ -651,11 +587,7 @@ const FdoNotificationDaemonSource = new Lang.Class({
     },
 
     createIcon: function(size) {
-        if (this.trayIcon) {
-            return new Clutter.Clone({ width: size,
-                                       height: size,
-                                       source: this.trayIcon });
-        } else if (this.app) {
+        if (this.app) {
             return this.app.create_icon_texture(size);
         } else if (this._gicon) {
             return new St.Icon({ gicon: this._gicon,


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]