// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
/* exported init */
const { Clutter, Shell, St } = imports.gi;
const Main = imports.ui.main;
const PanelMenu = imports.ui.panelMenu;
const System = imports.system;
const PANEL_ICON_SIZE = 16;
const STANDARD_TRAY_ICON_IMPLEMENTATIONS = [
'bluetooth-applet',
'gnome-sound-applet',
'nm-applet',
'gnome-power-manager',
'keyboard',
'a11y-keyboard',
'kbd-scrolllock',
'kbd-numlock',
'kbd-capslock',
'ibus-ui-gtk'
];
class SysTray {
constructor() {
this._icons = [];
this._tray = null;
}
_onTrayIconAdded(o, icon) {
let wmClass = icon.wm_class ? icon.wm_class.toLowerCase() : '';
if (STANDARD_TRAY_ICON_IMPLEMENTATIONS.includes(wmClass))
return;
let button = new PanelMenu.Button(0.5, null, true);
let scaleFactor = St.ThemeContext.get_for_stage(global.stage).scale_factor;
let iconSize = PANEL_ICON_SIZE * scaleFactor;
icon.set({
width: iconSize,
height: iconSize,
x_align: Clutter.ActorAlign.CENTER,
y_align: Clutter.ActorAlign.CENTER
});
let iconBin = new St.Widget({
layout_manager: new Clutter.BinLayout()
});
iconBin.add_actor(icon);
button.add_actor(iconBin);
this._icons.push(icon);
button.connect('button-release-event', (actor, event) => {
icon.click(event);
});
button.connect('key-press-event', (actor, event) => {
icon.click(event);
});
icon.connect('destroy', () => {
button.destroy();
});
let role = wmClass || `${icon}`;
Main.panel.addToStatusArea(role, button);
}
_onTrayIconRemoved(o, icon) {
let parent = icon.get_parent();
parent.destroy();
this._icons.splice(this._icons.indexOf(icon), 1);
}
enable() {
this._tray = new Shell.TrayManager();
this._tray.connect('tray-icon-added',
this._onTrayIconAdded.bind(this));
this._tray.connect('tray-icon-removed',
this._onTrayIconRemoved.bind(this));
this._tray.manage_screen(Main.panel.actor);
}
disable() {
this._icons.forEach(icon => icon.get_parent().destroy());
this._icons = [];
this._tray = null;
System.gc(); // force finalizing tray to unmanage screen
}
}
function init() {
return new SysTray();
}