daa7ed
From 946db74f6a0c750c950e5da7957480abb7cecfec Mon Sep 17 00:00:00 2001
daa7ed
From: =?UTF-8?q?Florian=20M=C3=BCllner?= <fmuellner@gnome.org>
daa7ed
Date: Fri, 16 Nov 2018 23:08:34 +0100
daa7ed
Subject: [PATCH 1/6] Remove compatibility with older shell versions
daa7ed
daa7ed
By now this is completely untested code we are somewhat dragging
daa7ed
along. Those versions are better covered by old extension versions,
daa7ed
and the simpler code will make it easier to move forward.
daa7ed
---
daa7ed
 extensions/top-icons/extension.js | 135 ++++--------------------------
daa7ed
 1 file changed, 16 insertions(+), 119 deletions(-)
daa7ed
daa7ed
diff --git a/extensions/top-icons/extension.js b/extensions/top-icons/extension.js
daa7ed
index 7312a26..c4c5084 100644
daa7ed
--- a/extensions/top-icons/extension.js
daa7ed
+++ b/extensions/top-icons/extension.js
daa7ed
@@ -1,69 +1,41 @@
daa7ed
 // -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
daa7ed
 
daa7ed
-const Clutter = imports.gi.Clutter;
daa7ed
 const Shell = imports.gi.Shell;
daa7ed
 const St = imports.gi.St;
daa7ed
 const Main = imports.ui.main;
daa7ed
-const GLib = imports.gi.GLib;
daa7ed
-const Lang = imports.lang;
daa7ed
-const Panel = imports.ui.panel;
daa7ed
 const PanelMenu = imports.ui.panelMenu;
daa7ed
 const Meta = imports.gi.Meta;
daa7ed
 const Mainloop = imports.mainloop;
daa7ed
-const NotificationDaemon = imports.ui.notificationDaemon;
daa7ed
 const System = imports.system;
daa7ed
 
daa7ed
-let trayAddedId = 0;
daa7ed
-let trayRemovedId = 0;
daa7ed
-let getSource = null;
daa7ed
 let icons = [];
daa7ed
-let notificationDaemon = null;
daa7ed
 let sysTray = null;
daa7ed
 
daa7ed
 const PANEL_ICON_SIZE = 24;
daa7ed
 
daa7ed
+const STANDARD_TRAY_ICON_IMPLEMENTATIONS = [
daa7ed
+    'bluetooth-applet',
daa7ed
+    'gnome-sound-applet',
daa7ed
+    'nm-applet',
daa7ed
+    'gnome-power-manager',
daa7ed
+    'keyboard',
daa7ed
+    'a11y-keyboard',
daa7ed
+    'kbd-scrolllock',
daa7ed
+    'kbd-numlock',
daa7ed
+    'kbd-capslock',
daa7ed
+    'ibus-ui-gtk'
daa7ed
+];
daa7ed
+
daa7ed
 function init() {
daa7ed
-    if (Main.legacyTray) {
daa7ed
-        notificationDaemon = Main.legacyTray;
daa7ed
-        NotificationDaemon.STANDARD_TRAY_ICON_IMPLEMENTATIONS = imports.ui.legacyTray.STANDARD_TRAY_ICON_IMPLEMENTATIONS;
daa7ed
-    }
daa7ed
-    else if (Main.notificationDaemon._fdoNotificationDaemon &&
daa7ed
-             Main.notificationDaemon._fdoNotificationDaemon._trayManager) {
daa7ed
-        notificationDaemon = Main.notificationDaemon._fdoNotificationDaemon;
daa7ed
-        getSource = Lang.bind(notificationDaemon, NotificationDaemon.FdoNotificationDaemon.prototype._getSource);
daa7ed
-    }
daa7ed
-    else if (Main.notificationDaemon._trayManager) {
daa7ed
-        notificationDaemon = Main.notificationDaemon;
daa7ed
-        getSource = Lang.bind(notificationDaemon, NotificationDaemon.NotificationDaemon.prototype._getSource);
daa7ed
-    }
daa7ed
-    else {
daa7ed
-        NotificationDaemon.STANDARD_TRAY_ICON_IMPLEMENTATIONS = {
daa7ed
-            'bluetooth-applet': 1, 'gnome-sound-applet': 1, 'nm-applet': 1,
daa7ed
-            'gnome-power-manager': 1, 'keyboard': 1, 'a11y-keyboard': 1,
daa7ed
-            'kbd-scrolllock': 1, 'kbd-numlock': 1, 'kbd-capslock': 1, 'ibus-ui-gtk': 1
daa7ed
-        };
daa7ed
-    }
daa7ed
 }
daa7ed
 
daa7ed
 function enable() {
daa7ed
-    if (notificationDaemon)
daa7ed
-        GLib.idle_add(GLib.PRIORITY_LOW, moveToTop);
daa7ed
-    else
daa7ed
-        createTray();
daa7ed
+    createTray();
daa7ed
 }
daa7ed
 
daa7ed
-function createSource (title, pid, ndata, sender, trayIcon) {
daa7ed
-  if (trayIcon) {
daa7ed
-    onTrayIconAdded(this, trayIcon, title);
daa7ed
-    return null;
daa7ed
-  }
daa7ed
-
daa7ed
-  return getSource(title, pid, ndata, sender, trayIcon);
daa7ed
-};
daa7ed
-
daa7ed
 function onTrayIconAdded(o, icon, role) {
daa7ed
     let wmClass = icon.wm_class ? icon.wm_class.toLowerCase() : '';
daa7ed
-    if (NotificationDaemon.STANDARD_TRAY_ICON_IMPLEMENTATIONS[wmClass] !== undefined)
daa7ed
+    if (STANDARD_TRAY_ICON_IMPLEMENTATIONS.includes(wmClass))
daa7ed
         return;
daa7ed
 
daa7ed
     let buttonBox = new PanelMenu.ButtonBox();
daa7ed
@@ -145,81 +117,6 @@ function destroyTray() {
daa7ed
     System.gc(); // force finalizing tray to unmanage screen
daa7ed
 }
daa7ed
 
daa7ed
-function moveToTop() {
daa7ed
-    notificationDaemon._trayManager.disconnect(notificationDaemon._trayIconAddedId);
daa7ed
-    notificationDaemon._trayManager.disconnect(notificationDaemon._trayIconRemovedId);
daa7ed
-    trayAddedId = notificationDaemon._trayManager.connect('tray-icon-added', onTrayIconAdded);
daa7ed
-    trayRemovedId = notificationDaemon._trayManager.connect('tray-icon-removed', onTrayIconRemoved);
daa7ed
-
daa7ed
-    notificationDaemon._getSource = createSource;
daa7ed
-
daa7ed
-    let toDestroy = [];
daa7ed
-    if (notificationDaemon._sources) {
daa7ed
-        for (let i = 0; i < notificationDaemon._sources.length; i++) {
daa7ed
-            let source = notificationDaemon._sources[i];
daa7ed
-            if (!source.trayIcon)
daa7ed
-                continue;
daa7ed
-            let parent = source.trayIcon.get_parent();
daa7ed
-            parent.remove_actor(source.trayIcon);
daa7ed
-            onTrayIconAdded(this, source.trayIcon, source.initialTitle);
daa7ed
-            toDestroy.push(source);
daa7ed
-        }
daa7ed
-    }
daa7ed
-    else {
daa7ed
-        for (let i = 0; i < notificationDaemon._iconBox.get_n_children(); i++) {
daa7ed
-            let button = notificationDaemon._iconBox.get_child_at_index(i);
daa7ed
-            let icon = button.child;
daa7ed
-            button.remove_actor(icon);
daa7ed
-            onTrayIconAdded(this, icon, '');
daa7ed
-            toDestroy.push(button);
daa7ed
-        }
daa7ed
-    }
daa7ed
-
daa7ed
-    for (let i = 0; i < toDestroy.length; i++) {
daa7ed
-        toDestroy[i].destroy();
daa7ed
-    }
daa7ed
-}
daa7ed
-
daa7ed
-function moveToTray() {
daa7ed
-    if (trayAddedId != 0) {
daa7ed
-        notificationDaemon._trayManager.disconnect(trayAddedId);
daa7ed
-        trayAddedId = 0;
daa7ed
-    }
daa7ed
-
daa7ed
-    if (trayRemovedId != 0) {
daa7ed
-        notificationDaemon._trayManager.disconnect(trayRemovedId);
daa7ed
-        trayRemovedId = 0;
daa7ed
-    }
daa7ed
-
daa7ed
-    notificationDaemon._trayIconAddedId = notificationDaemon._trayManager.connect('tray-icon-added',
daa7ed
-                                                Lang.bind(notificationDaemon, notificationDaemon._onTrayIconAdded));
daa7ed
-    notificationDaemon._trayIconRemovedId = notificationDaemon._trayManager.connect('tray-icon-removed',
daa7ed
-                                                Lang.bind(notificationDaemon, notificationDaemon._onTrayIconRemoved));
daa7ed
-
daa7ed
-    notificationDaemon._getSource = getSource;
daa7ed
-
daa7ed
-    for (let i = 0; i < icons.length; i++) {
daa7ed
-        let icon = icons[i];
daa7ed
-        let parent = icon.get_parent();
daa7ed
-        if (icon._clicked) {
daa7ed
-            icon.disconnect(icon._clicked);
daa7ed
-        }
daa7ed
-        icon._clicked = undefined;
daa7ed
-        if (icon._proxyAlloc) {
daa7ed
-            Main.panel._rightBox.disconnect(icon._proxyAlloc);
daa7ed
-        }
daa7ed
-        icon._clickProxy.destroy();
daa7ed
-        parent.remove_actor(icon);
daa7ed
-        parent.destroy();
daa7ed
-        notificationDaemon._onTrayIconAdded(notificationDaemon, icon);
daa7ed
-    }
daa7ed
-
daa7ed
-    icons = [];
daa7ed
-}
daa7ed
-
daa7ed
 function disable() {
daa7ed
-    if (notificationDaemon)
daa7ed
-        moveToTray();
daa7ed
-    else
daa7ed
-        destroyTray();
daa7ed
+    destroyTray();
daa7ed
 }
daa7ed
-- 
daa7ed
2.26.2
daa7ed
daa7ed
daa7ed
From d0f2d28a7dcabe79a538edb946c566c15d7bd9aa Mon Sep 17 00:00:00 2001
daa7ed
From: =?UTF-8?q?Florian=20M=C3=BCllner?= <fmuellner@gnome.org>
daa7ed
Date: Fri, 15 Feb 2019 03:12:00 +0100
daa7ed
Subject: [PATCH 2/6] Fix double-destroy error
daa7ed
daa7ed
A parent will destroy all its children when destroyed, so we don't
daa7ed
need to explicitly destroy the icon as well. In fact, gjs now treats
daa7ed
this as a fatal error.
daa7ed
---
daa7ed
 extensions/top-icons/extension.js | 1 -
daa7ed
 1 file changed, 1 deletion(-)
daa7ed
daa7ed
diff --git a/extensions/top-icons/extension.js b/extensions/top-icons/extension.js
daa7ed
index c4c5084..6456189 100644
daa7ed
--- a/extensions/top-icons/extension.js
daa7ed
+++ b/extensions/top-icons/extension.js
daa7ed
@@ -98,7 +98,6 @@ function onTrayIconAdded(o, icon, role) {
daa7ed
 function onTrayIconRemoved(o, icon) {
daa7ed
     let parent = icon.get_parent();
daa7ed
     parent.destroy();
daa7ed
-    icon.destroy();
daa7ed
     icons.splice(icons.indexOf(icon), 1);
daa7ed
 }
daa7ed
 
daa7ed
-- 
daa7ed
2.26.2
daa7ed
daa7ed
daa7ed
From fda29d0517b56dac3ddfa7a9749a52a40c1bbb6a Mon Sep 17 00:00:00 2001
daa7ed
From: =?UTF-8?q?Florian=20M=C3=BCllner?= <fmuellner@gnome.org>
daa7ed
Date: Sat, 17 Nov 2018 00:57:53 +0100
daa7ed
Subject: [PATCH 3/6] Stop using a "click proxy"
daa7ed
daa7ed
It's a terrible work-around for an issue with status icon support
daa7ed
on wayland[0], which is the cause of crashes now that gjs is much
daa7ed
stricter about accessing already released objects.
daa7ed
daa7ed
Crashing is worse than the original problem (which will hopefully
daa7ed
soon be fixed anyway), so drop the work-around.
daa7ed
daa7ed
https://gitlab.gnome.org/GNOME/gnome-shell/issues/191
daa7ed
---
daa7ed
 extensions/top-icons/extension.js | 38 +++----------------------------
daa7ed
 1 file changed, 3 insertions(+), 35 deletions(-)
daa7ed
daa7ed
diff --git a/extensions/top-icons/extension.js b/extensions/top-icons/extension.js
daa7ed
index 6456189..b617284 100644
daa7ed
--- a/extensions/top-icons/extension.js
daa7ed
+++ b/extensions/top-icons/extension.js
daa7ed
@@ -4,8 +4,6 @@ const Shell = imports.gi.Shell;
daa7ed
 const St = imports.gi.St;
daa7ed
 const Main = imports.ui.main;
daa7ed
 const PanelMenu = imports.ui.panelMenu;
daa7ed
-const Meta = imports.gi.Meta;
daa7ed
-const Mainloop = imports.mainloop;
daa7ed
 const System = imports.system;
daa7ed
 
daa7ed
 let icons = [];
daa7ed
@@ -56,42 +54,12 @@ function onTrayIconAdded(o, icon, role) {
daa7ed
     icons.push(icon);
daa7ed
     Main.panel._rightBox.insert_child_at_index(box, 0);
daa7ed
 
daa7ed
-    let clickProxy = new St.Bin({ width: iconSize, height: iconSize });
daa7ed
-    clickProxy.reactive = true;
daa7ed
-    Main.uiGroup.add_actor(clickProxy);
daa7ed
-
daa7ed
-    icon._proxyAlloc = Main.panel._rightBox.connect('allocation-changed', function() {
daa7ed
-        Meta.later_add(Meta.LaterType.BEFORE_REDRAW, function() {
daa7ed
-            let [x, y] = icon.get_transformed_position();
daa7ed
-            clickProxy.set_position(x, y);
daa7ed
-        });
daa7ed
-    });
daa7ed
-
daa7ed
-    icon.connect("destroy", function() {
daa7ed
-        Main.panel._rightBox.disconnect(icon._proxyAlloc);
daa7ed
-        clickProxy.destroy();
daa7ed
-    });
daa7ed
-
daa7ed
-    clickProxy.connect('button-release-event', function(actor, event) {
daa7ed
+    icon.connect('button-release-event', function(actor, event) {
daa7ed
         icon.click(event);
daa7ed
     });
daa7ed
 
daa7ed
-    icon._clickProxy = clickProxy;
daa7ed
-
daa7ed
-    /* Fixme: HACK */
daa7ed
-    Meta.later_add(Meta.LaterType.BEFORE_REDRAW, function() {
daa7ed
-        let [x, y] = icon.get_transformed_position();
daa7ed
-        clickProxy.set_position(x, y);
daa7ed
-        return false;
daa7ed
-    });
daa7ed
-    let timerId = 0;
daa7ed
-    let i = 0;
daa7ed
-    timerId = Mainloop.timeout_add(500, function() {
daa7ed
-        icon.set_size(icon.width == iconSize ? iconSize - 1 : iconSize,
daa7ed
-                      icon.width == iconSize ? iconSize - 1 : iconSize);
daa7ed
-        i++;
daa7ed
-        if (i == 2)
daa7ed
-            Mainloop.source_remove(timerId);
daa7ed
+    icon.connect('destroy', function() {
daa7ed
+        box.destroy();
daa7ed
     });
daa7ed
 }
daa7ed
 
daa7ed
-- 
daa7ed
2.26.2
daa7ed
daa7ed
daa7ed
From 20f4b27ace58d7b6c5df4936c5e5d11d13992fbd Mon Sep 17 00:00:00 2001
daa7ed
From: =?UTF-8?q?Florian=20M=C3=BCllner?= <fmuellner@gnome.org>
daa7ed
Date: Fri, 15 Feb 2019 17:33:41 +0100
daa7ed
Subject: [PATCH 4/6] Slightly improve integration with top bar
daa7ed
daa7ed
It is lost in the mists of time why we are using a base class and
daa7ed
meddle around with its hierarchy, instead of using the preferred
daa7ed
API for top bar items.
daa7ed
daa7ed
While at it, also support activation by keynav.
daa7ed
---
daa7ed
 extensions/top-icons/extension.js | 24 +++++++++++-------------
daa7ed
 1 file changed, 11 insertions(+), 13 deletions(-)
daa7ed
daa7ed
diff --git a/extensions/top-icons/extension.js b/extensions/top-icons/extension.js
daa7ed
index b617284..59e91d5 100644
daa7ed
--- a/extensions/top-icons/extension.js
daa7ed
+++ b/extensions/top-icons/extension.js
daa7ed
@@ -31,36 +31,34 @@ function enable() {
daa7ed
     createTray();
daa7ed
 }
daa7ed
 
daa7ed
-function onTrayIconAdded(o, icon, role) {
daa7ed
+function onTrayIconAdded(o, icon) {
daa7ed
     let wmClass = icon.wm_class ? icon.wm_class.toLowerCase() : '';
daa7ed
     if (STANDARD_TRAY_ICON_IMPLEMENTATIONS.includes(wmClass))
daa7ed
         return;
daa7ed
 
daa7ed
-    let buttonBox = new PanelMenu.ButtonBox();
daa7ed
-    let box = buttonBox.actor;
daa7ed
-    let parent = box.get_parent();
daa7ed
+    let button = new PanelMenu.Button(0.5, null, true);
daa7ed
 
daa7ed
     let scaleFactor = St.ThemeContext.get_for_stage(global.stage).scale_factor;
daa7ed
     let iconSize = PANEL_ICON_SIZE * scaleFactor;
daa7ed
 
daa7ed
     icon.set_size(iconSize, iconSize);
daa7ed
-    box.add_actor(icon);
daa7ed
-
daa7ed
-    icon.reactive = true;
daa7ed
-
daa7ed
-    if (parent)
daa7ed
-        parent.remove_actor(box);
daa7ed
+    button.actor.add_actor(icon);
daa7ed
 
daa7ed
     icons.push(icon);
daa7ed
-    Main.panel._rightBox.insert_child_at_index(box, 0);
daa7ed
 
daa7ed
-    icon.connect('button-release-event', function(actor, event) {
daa7ed
+    button.actor.connect('button-release-event', function(actor, event) {
daa7ed
+        icon.click(event);
daa7ed
+    });
daa7ed
+    button.actor.connect('key-press-event', function(actor, event) {
daa7ed
         icon.click(event);
daa7ed
     });
daa7ed
 
daa7ed
     icon.connect('destroy', function() {
daa7ed
-        box.destroy();
daa7ed
+        button.destroy();
daa7ed
     });
daa7ed
+
daa7ed
+    let role = wmClass || `${icon}`;
daa7ed
+    Main.panel.addToStatusArea(role, button);
daa7ed
 }
daa7ed
 
daa7ed
 function onTrayIconRemoved(o, icon) {
daa7ed
-- 
daa7ed
2.26.2
daa7ed
daa7ed
daa7ed
From 866cbb3a7d2226b93d1d682db682f8f8ef247ddf Mon Sep 17 00:00:00 2001
daa7ed
From: =?UTF-8?q?Florian=20M=C3=BCllner?= <fmuellner@gnome.org>
daa7ed
Date: Fri, 31 May 2019 18:57:42 +0200
daa7ed
Subject: [PATCH 5/6] Fix icon sizing issue
daa7ed
daa7ed
PanelMenu.Button is a custom actor that expands its child to the
daa7ed
available height and adds horizontal padding. So in order to not
daa7ed
distort the icon, don't add it directly but add an intermediate
daa7ed
container for alignment.
daa7ed
daa7ed
Also lower the icon size to the standard top bar 16px.
daa7ed
---
daa7ed
 extensions/top-icons/extension.js | 12 ++++++++++--
daa7ed
 1 file changed, 10 insertions(+), 2 deletions(-)
daa7ed
daa7ed
diff --git a/extensions/top-icons/extension.js b/extensions/top-icons/extension.js
daa7ed
index 59e91d5..f0da96f 100644
daa7ed
--- a/extensions/top-icons/extension.js
daa7ed
+++ b/extensions/top-icons/extension.js
daa7ed
@@ -1,5 +1,6 @@
daa7ed
 // -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
daa7ed
 
daa7ed
+const Clutter = imports.gi.Clutter;
daa7ed
 const Shell = imports.gi.Shell;
daa7ed
 const St = imports.gi.St;
daa7ed
 const Main = imports.ui.main;
daa7ed
@@ -9,7 +10,7 @@ const System = imports.system;
daa7ed
 let icons = [];
daa7ed
 let sysTray = null;
daa7ed
 
daa7ed
-const PANEL_ICON_SIZE = 24;
daa7ed
+const PANEL_ICON_SIZE = 16;
daa7ed
 
daa7ed
 const STANDARD_TRAY_ICON_IMPLEMENTATIONS = [
daa7ed
     'bluetooth-applet',
daa7ed
@@ -42,7 +43,14 @@ function onTrayIconAdded(o, icon) {
daa7ed
     let iconSize = PANEL_ICON_SIZE * scaleFactor;
daa7ed
 
daa7ed
     icon.set_size(iconSize, iconSize);
daa7ed
-    button.actor.add_actor(icon);
daa7ed
+    icon.set_x_align(Clutter.ActorAlign.CENTER);
daa7ed
+    icon.set_y_align(Clutter.ActorAlign.CENTER);
daa7ed
+
daa7ed
+    let iconBin = new St.Widget({
daa7ed
+        layout_manager: new Clutter.BinLayout(),
daa7ed
+    });
daa7ed
+    iconBin.add_actor(icon);
daa7ed
+    button.actor.add_actor(iconBin);
daa7ed
 
daa7ed
     icons.push(icon);
daa7ed
 
daa7ed
-- 
daa7ed
2.26.2
daa7ed
daa7ed
daa7ed
From 4e2ac2ff096265db9916d323255f7d57ab742d6e Mon Sep 17 00:00:00 2001
daa7ed
From: =?UTF-8?q?Florian=20M=C3=BCllner?= <fmuellner@gnome.org>
daa7ed
Date: Wed, 27 May 2020 22:01:06 +0200
daa7ed
Subject: [PATCH 6/6] Set icons' accessible name
daa7ed
daa7ed
Status icons aren't great as far as accessibility is concerned (well,
daa7ed
they aren't great, full stop). But we can at least do slightly better
daa7ed
than stuffing an anonymous actor in the top bar by using the icon's
daa7ed
title for the accessible name.
daa7ed
---
daa7ed
 extensions/top-icons/extension.js | 4 ++++
daa7ed
 1 file changed, 4 insertions(+)
daa7ed
daa7ed
diff --git a/extensions/top-icons/extension.js b/extensions/top-icons/extension.js
daa7ed
index f0da96f..3611f59 100644
daa7ed
--- a/extensions/top-icons/extension.js
daa7ed
+++ b/extensions/top-icons/extension.js
daa7ed
@@ -1,6 +1,7 @@
daa7ed
 // -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
daa7ed
 
daa7ed
 const Clutter = imports.gi.Clutter;
daa7ed
+const GObject = imports.gi.GObject;
daa7ed
 const Shell = imports.gi.Shell;
daa7ed
 const St = imports.gi.St;
daa7ed
 const Main = imports.ui.main;
daa7ed
@@ -45,6 +46,9 @@ function onTrayIconAdded(o, icon) {
daa7ed
     icon.set_size(iconSize, iconSize);
daa7ed
     icon.set_x_align(Clutter.ActorAlign.CENTER);
daa7ed
     icon.set_y_align(Clutter.ActorAlign.CENTER);
daa7ed
+    icon.bind_property('title',
daa7ed
+        button.actor, 'accessible-name',
daa7ed
+        GObject.BindingFlags.SYNC_CREATE);
daa7ed
 
daa7ed
     let iconBin = new St.Widget({
daa7ed
         layout_manager: new Clutter.BinLayout(),
daa7ed
-- 
daa7ed
2.26.2
daa7ed