Review of "Better Tray Icons" version 2.2.1 (4)

Details Page Preview

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.

Extension Homepage
https://github.com/nexaknight/BetterTrayIcons

No comments.

Diff Against

Files

Note: Binary files aren't shown on the web site. To see all files, please download the extension zipfile.

Shexli (experimental) warning 4

Shexli found 4 issues that may need reviewer attention.

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()`.

File Operations

  • src/shell/utils/dbus.js:22
    interfaceFile.load_contents(null)

EGO-P-006 warning

unnecessary build and translation artifacts should not be shipped

Compiled GSettings schemas should not be shipped for 45+ packages.

Don't include unnecessary files

  • schemas/gschemas.compiled
    schemas/gschemas.compiled

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.

Disconnect all signals

  • extension.js:123
            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:74
                this._fileMonitorSignalId = this._fileMonitor.connect('changed', (_monitor, f, _other, eventType) => {
                    if (eventType === Gio.FileMonitorEvent.CHANGED || eventType === Gio.FileMonitorEvent.CREATED)
                        this._queueSyncImport(f);
                })
  • extension.js:141
    this._settings.connect(`changed::${key}`, handler)
  • src/shell/xembedBridge.js:290
            this._sigIconDestroy = this._icon.connect('destroy', () => {
                this._sigIconDestroy = 0;
                this.destroy();
            })
  • src/shell/xembedBridge.js:268
                this.actor.connect('button-press-event', () => {
                    this.actor.add_style_pseudo_class('active');
                    return Clutter.EVENT_PROPAGATE;
                })
  • src/shell/xembedBridge.js:330
    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.

Remove main loop sources

  • extension.js:130
                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:21
            this._enableTimeoutId = GLib.idle_add(GLib.PRIORITY_DEFAULT, () => {
                this._enableTimeoutId = 0;
                this._realEnable();
                return GLib.SOURCE_REMOVE;
            })
  • extension.js:87
            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:346
            this._pendingClickId = GLib.idle_add(GLib.PRIORITY_DEFAULT, () => {
                this._pendingClickId = 0;
                if (!this._isDestroyed && this._icon)
                    this._icon.click(eventCopy);
                return GLib.SOURCE_REMOVE;
            })

All Versions

Version Status
2.2.1 (4) Unreviewed
2.0.3 (3) Rejected
2 Rejected
1 Rejected