Brings tray icons back to the GNOME panel. Supports the StatusNotifierItem (SNI) and KStatusNotifierItem specs, so apps like Discord, Steam, Telegram, Signal and Nextcloud show up in the panel like they used to. A configurable number of icons stays inline, the rest are tucked away into an overflow popup behind a toggle button, in row or grid layout. Every icon can be renamed, hidden, reordered or swapped out for a custom one on a per-app basis. Left, middle and right click, plus double-click and long-press, are independently bindable. Spacing, padding, radius, hover background and the toggle styling are all up to you. Settings can be exported, imported and synced across devices through a shared JSON file with rotated backups. Wayland only, X11 sessions are not supported. Conflicts with other tray and AppIndicator extensions, so disable those before enabling this one.
Note: Binary files aren't shown on the web site. To see all files, please download the extension zipfile.
EGO-X-004 warning
extensions should avoid synchronous file IO in shell code
Shell code should avoid synchronous file IO APIs like `GLib.file_get_contents()` and `Gio.File.load_contents()`.
src/shell/utils/dbus.js:34
interfaceFile.load_contents(null)
EGO-L-003 warning
signals connected by extension should be disconnected in disable()
Signals assigned in `enable()` are missing matching disconnect calls in `disable()` or its helper methods.
extension.js:126
this._autoPushSignalId = this._settings.connect('changed', (_s, key) => {
if (key === 'sync-file-path' || key === 'enable-auto-sync')
return;
if (this._lastImportAt && Date.now() - this._lastImportAt < AUTO_PUSH_GUARD_AFTER_IMPORT_MS)
r
extension.js:73
this._fileMonitorSignalId = this._fileMonitor.connect('changed', (_monitor, f, _other, eventType) => {
if (eventType === Gio.FileMonitorEvent.CHANGED || eventType === Gio.FileMonitorEvent.CREATED)
this._queueSyncImport(f);
})
extension.js:144
this._settings.connect(`changed::${key}`, handler)
src/shell/xembedBridge.js:302
this._sigIconDestroy = this._icon.connect('destroy', () => {
this._sigIconDestroy = 0;
this.destroy();
})
src/shell/xembedBridge.js:283
this.actor.connect('button-press-event', () => {
this.actor.add_style_pseudo_class('active');
return Clutter.EVENT_PROPAGATE;
})
src/shell/xembedBridge.js:332
this._settings.connect(`changed::${key}`, () => {
this._draggable?.setEnabled(isDragEnabledFromSettings(this._settings));
})
EGO-L-004 warning
main loop sources should be removed in disable()
Main loop sources assigned in `enable()` are missing matching removals in `disable()` or its helper methods.
extension.js:133
this._autoPushDebounceId = GLib.timeout_add(GLib.PRIORITY_DEFAULT, AUTO_PUSH_DEBOUNCE_MS, () => {
this._autoPushDebounceId = 0;
saveSettingsToFile(this._settings, this._settings.get_string('sync-file-path'))
.catch(e => warn(`Auto-push
extension.js:20
this._enableTimeoutId = GLib.idle_add(GLib.PRIORITY_DEFAULT, () => {
this._enableTimeoutId = 0;
this._realEnable();
return GLib.SOURCE_REMOVE;
})
extension.js:86
this._syncDebounceId = GLib.timeout_add(GLib.PRIORITY_DEFAULT, AUTO_SYNC_DEBOUNCE_MS, () => {
this._syncDebounceId = 0;
// Cancellable lets disable() abort the read before it touches
// a nulled `this._settings`.
disposeAll(this, 'cancel', '_s
src/shell/xembedBridge.js:348
this._pendingClickId = GLib.idle_add(GLib.PRIORITY_DEFAULT, () => {
this._pendingClickId = 0;
if (!this._isDestroyed && this._icon)
this._icon.click(eventCopy);
return GLib.SOURCE_REMOVE;
})
| Version | Status |
|---|---|
| 2 | Unreviewed |
| 1 | Rejected |