Review of "Aurora Shell" version 50.10 (27)

Details Page Preview

A customizable GNOME Shell extension that enhances the user experience with various modules and features. Clipboard History reads and stores clipboard content locally so it can be browsed and restored. Capture Tools writes captured images and locally recognized text to the clipboard when requested. No clipboard or OCR data is shared with third parties, and the Clipboard History shortcut is unset by default.

Extension Homepage
https://github.com/luminusOS/aurora-shell

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 manual_review 1

Shexli found 5 issues that may need reviewer attention.

EGO-A-005 manual_review

extensions should not access the clipboard directly

Direct clipboard access via `St.Clipboard.get_default()` requires reviewer scrutiny.

Review Guidelines

  • capture/captureTools.js:566
    St.Clipboard.get_default()
  • capture/screenshotCapture.js:38
    St.Clipboard.get_default()
  • clipboard/clipboardHistory.js:158
    St.Clipboard.get_default()
  • clipboard/clipboardHistory.js:169
    St.Clipboard.get_default()
  • clipboard/clipboardMonitor.js:52
    St.Clipboard.get_default()

EGO-L-002 warning

objects created by extension should be destroyed in disable()

Objects assigned in `enable()` are missing matching `.destroy()` calls in `disable()` or its helper methods.

Destroy all objects

  • capture/captureTools.js:115
    this._ocrLayer = new St.Widget({ reactive: false, x_expand: true, y_expand: true })
  • capture/captureTools.js:511
    this._textEntry = entry
  • dock/externalStorageIcon.js:242
    this._ejectItem = new PopupMenu.PopupMenuItem(ejectLabel)
  • dock/externalStorageIcon.js:220
          this._iconActor = new St.Icon({
            gicon: this._item.icon,
            icon_size: size,
            style_class: 'show-apps-icon',
            track_hover: true,
          })
  • dock/externalStorageIcon.js:230
    this._menu = new PopupMenu.PopupMenu(this.toggleButton, 0.5, St.Side.TOP)
  • dock/externalStorageIcon.js:234
    this._menuManager = new PopupMenu.PopupMenuManager(this.toggleButton)
  • dock/externalStorageIcon.js:236
          this._openItem = new PopupMenu.PopupMenuItem(
            this._item.mount ? _('Open') : _('Mount and Open'),
          )
  • dock/externalStorageIcon.js:177
          this.toggleButton = new St.Button({
            style_class: 'show-apps',
            track_hover: true,
            can_focus: true,
            reactive: true,
          })
  • dock/trashIcon.js:97
    this._emptyItem = new PopupMenu.PopupMenuItem(_('Empty Trash'))
  • dock/trashIcon.js:78
          this._iconActor = new St.Icon({
            icon_name: this._empty ? ICON_EMPTY : ICON_FULL,
            icon_size: size,
            style_class: 'show-apps-icon',
            track_hover: true,
          })
  • dock/trashIcon.js:88
    this._menu = new PopupMenu.PopupMenu(this.toggleButton, 0.5, St.Side.TOP)
  • dock/trashIcon.js:92
    this._menuManager = new PopupMenu.PopupMenuManager(this.toggleButton)
  • dock/trashIcon.js:33
          this.toggleButton = new St.Button({
            style_class: 'show-apps',
            track_hover: true,
            can_focus: true,
            reactive: true,
          })

EGO-L-005 warning

owned object references should be released in disable()

Owned references that are cleaned up in `disable()` should also be released with `null` or `undefined`.

Destroy all objects

  • dock/externalStorageIcon.js:242
    this._ejectItem = new PopupMenu.PopupMenuItem(ejectLabel)
  • dock/externalStorageIcon.js:220
          this._iconActor = new St.Icon({
            gicon: this._item.icon,
            icon_size: size,
            style_class: 'show-apps-icon',
            track_hover: true,
          })
  • dock/externalStorageIcon.js:230
    this._menu = new PopupMenu.PopupMenu(this.toggleButton, 0.5, St.Side.TOP)
  • dock/externalStorageIcon.js:234
    this._menuManager = new PopupMenu.PopupMenuManager(this.toggleButton)
  • dock/externalStorageIcon.js:236
          this._openItem = new PopupMenu.PopupMenuItem(
            this._item.mount ? _('Open') : _('Mount and Open'),
          )
  • dock/externalStorageIcon.js:177
          this.toggleButton = new St.Button({
            style_class: 'show-apps',
            track_hover: true,
            can_focus: true,
            reactive: true,
          })
  • dock/trashIcon.js:97
    this._emptyItem = new PopupMenu.PopupMenuItem(_('Empty Trash'))
  • dock/trashIcon.js:78
          this._iconActor = new St.Icon({
            icon_name: this._empty ? ICON_EMPTY : ICON_FULL,
            icon_size: size,
            style_class: 'show-apps-icon',
            track_hover: true,
          })
  • dock/trashIcon.js:88
    this._menu = new PopupMenu.PopupMenu(this.toggleButton, 0.5, St.Side.TOP)
  • dock/trashIcon.js:92
    this._menuManager = new PopupMenu.PopupMenuManager(this.toggleButton)
  • dock/trashIcon.js:33
          this.toggleButton = new St.Button({
            style_class: 'show-apps',
            track_hover: true,
            can_focus: true,
            reactive: true,
          })

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

  • capture/captureTools.js:199
    scope.connect(ui, 'closed', () => this._resetSession())
  • capture/captureTools.js:201
    scope.connect(button, 'notify::checked', () => this._syncVisibility())
  • capture/captureTools.js:203
    scope.connect(button, 'notify::checked', () => this._clearOcr())
  • capture/captureTools.js:204
    scope.connect(ui._selectionButton, 'notify::checked', () => this._syncToolbarPlacement())
  • capture/captureTools.js:205
        scope.connect(ui._areaSelector, 'drag-started', () => {
          this._clearOcr();
          this._setInteractionState('selection');
        })
  • capture/captureTools.js:209
        scope.connect(ui._areaSelector, 'drag-ended', () => {
          this._setInteractionState('idle');
          this._syncToolbarPlacement();
        })
  • capture/captureTools.js:214
    scope.connect(this._toolbar, 'notify::allocation', () => this._syncToolbarPlacement())
  • capture/captureTools.js:503
    entry.clutter_text.connect('activate', () => this._commitText(true))
  • capture/captureTools.js:509
    entry.clutter_text.connect('key-focus-out', () => this._commitText(true))
  • capture/captureTools.js:504
        entry.clutter_text.connect('key-press-event', (_actor, event) => {
          if (event.get_key_symbol() !== Clutter.KEY_Escape) return Clutter.EVENT_PROPAGATE;
          this._commitText(false);
          return Clutter.EVENT_STOP;
        })
  • clipboard/clipboardHistory.js:80
        this._lifecycle.connect(rawSettings, 'changed::clipboard-history-poll-interval', () => {
          this._monitor?.setInterval(rawSettings.get_int('clipboard-history-poll-interval'));
        })
  • desktop/trayIcons/trayIcons.js:113
        this._lifecycle.connect(settings, 'changed::tray-icons-hide-bg-quick-settings', () => {
          if (settings.get_boolean('tray-icons-hide-bg-quick-settings')) {
            this._hideBgAppsQuickSettings();
          } else {
            this._restoreBgAppsQuickSettings();
          }
        })
  • desktop/trayIcons/trayIcons.js:120
        this._lifecycle.connect(settings, 'changed::tray-icons-recolor-symbolic-pixmaps', () => {
          logger.debug(
            `Recolor symbolic SNI pixmaps=${settings.get_boolean('tray-icons-recolor-symbolic-pixmaps')}; refreshing SNI icons`,
            { prefix: LOG_PREFIX },
          );
          this._sniHost?
  • desktop/trayIcons/trayIcons.js:75
        this._lifecycle.connect(this._desktopSettings, 'changed::color-scheme', () => {
          const scheme = this._desktopSettings?.getString('color-scheme') ?? 'unknown';
          logger.debug(`Color scheme changed to ${scheme}; refreshing SNI icons`, {
            prefix: LOG_PREFIX,
          });
          this._sn
  • desktop/trayIcons/trayIcons.js:89
        this._lifecycle.connect(settings, 'changed::tray-icons-limit', () => {
          this._container?.setLimit(settings.get_int('tray-icons-limit'));
        })
  • desktop/trayIcons/trayIcons.js:92
        this._lifecycle.connect(settings, 'changed::tray-icons-icon-size', () => {
          this._container?.setIconSize(settings.get_int('tray-icons-icon-size'));
        })
  • desktop/trayIcons/trayIcons.js:95
        this._lifecycle.connect(settings, 'changed::tray-icons-attention-timeout', () => {
          this._container?.setAttentionTimeout(settings.get_int('tray-icons-attention-timeout'));
        })
  • desktop/trayIcons/trayIcons.js:98
        this._lifecycle.connect(settings, 'changed::tray-icons-dedup-bg-apps', () => {
          this._dedupBgApps = settings.get_boolean('tray-icons-dedup-bg-apps');
          if (this._dedupBgApps) {
            for (const [appId, entry] of [...this._bgItemAppIds]) {
              this._sniCoversApp(appId, entry.app)
  • panel/auroraMenu.js:78
    this._lifecycle.connect(settings, `changed::${MENU_ICON_KEY}`, () => this._syncPanelIcon())
  • panel/auroraMenu.js:79
    this._lifecycle.connect(settings, `changed::${APP_STORE_COMMAND_KEY}`, rebuildMenu)
  • panel/auroraMenu.js:80
    this._lifecycle.connect(settings, `changed::${CUSTOM_ITEMS_KEY}`, rebuildMenu)
  • panel/auroraMenu.js:81
    this._lifecycle.connect(settings, `changed::${CUSTOM_ENABLED_KEY}`, rebuildMenu)
  • panel/auroraMenu.js:82
    this._lifecycle.connect(settings, `changed::${CUSTOM_LABEL_KEY}`, rebuildMenu)
  • panel/auroraMenu.js:83
    this._lifecycle.connect(settings, `changed::${CUSTOM_COMMAND_KEY}`, rebuildMenu)
  • panel/auroraMenu.js:84
    this._lifecycle.connect(settings, `changed::${SHOW_ABOUT_KEY}`, rebuildMenu)
  • panel/auroraMenu.js:85
    this._lifecycle.connect(settings, `changed::${SHOW_HOME_KEY}`, rebuildMenu)
  • panel/auroraMenu.js:86
    this._lifecycle.connect(settings, `changed::${SHOW_DOWNLOADS_KEY}`, rebuildMenu)
  • panel/auroraMenu.js:87
    this._lifecycle.connect(settings, `changed::${SHOW_RECENT_KEY}`, rebuildMenu)
  • panel/auroraMenu.js:88
    this._lifecycle.connect(settings, `changed::${SHOW_SETTINGS_KEY}`, rebuildMenu)
  • panel/auroraMenu.js:89
    this._lifecycle.connect(settings, `changed::${SHOW_SOFTWARE_KEY}`, rebuildMenu)
  • panel/auroraMenu.js:90
    this._lifecycle.connect(settings, `changed::${SHOW_EXTENSIONS_KEY}`, rebuildMenu)
  • panel/auroraMenu.js:91
        this._lifecycle.connect(settings, `changed::${HIDE_ACTIVITIES_KEY}`, () =>
          this._syncActivitiesButton(),
        )
  • panel/clock/meetingClock/meetingClock.js:102
        this._lifecycle.connect(settings, `changed::${SNOOZE_MINUTES_KEY}`, () =>
          this._scheduleAlerts(),
        )
  • panel/clock/meetingClock/meetingClock.js:105
        this._lifecycle.connect(settings, `changed::${ALERT_EVENTS_WITHOUT_LINK_KEY}`, () =>
          this._scheduleAlerts(),
        )
  • panel/clock/meetingClock/meetingClock.js:108
        this._lifecycle.connect(settings, `changed::${PANEL_REVEAL_INTERVAL_MINUTES_KEY}`, () =>
          this._schedulePanelRevealTimer(),
        )
  • panel/clock/meetingClock/meetingClock.js:111
        this._lifecycle.connect(settings, `changed::${PANEL_LOOKAHEAD_MINUTES_KEY}`, () =>
          this._render(),
        )
  • panel/clock/meetingClock/meetingClock.js:114
        this._lifecycle.connect(settings, `changed::${EXCLUDE_ALL_DAY_KEY}`, () => {
          this._render();
          this._scheduleAlerts();
        })
  • panel/clock/meetingClock/meetingClock.js:96
        this._lifecycle.connect(settings, `changed::${ALERTS_ENABLED_KEY}`, () =>
          this._scheduleAlerts(),
        )
  • panel/clock/meetingClock/meetingClock.js:99
        this._lifecycle.connect(settings, `changed::${ALERT_MINUTES_KEY}`, () =>
          this._scheduleAlerts(),
        )
  • panel/clock/weatherClock/weatherClock.js:181
    this._lifecycle?.connect(obj, signalName, callback)
  • panel/clock/weatherClock/weatherClock.js:50
          this._lifecycle.connect(this._gweatherSettings, `changed::${TEMPERATURE_UNIT_KEY}`, () =>
            this._onWeatherChanged(),
          )
  • panel/clock/weatherClock/weatherClock.js:56
        this._lifecycle.connect(this.context.settings, `changed::${AFTER_CLOCK_KEY}`, () =>
          this._registerClockWidget(),
        )
  • privacy/privacy.js:24
    this._lifecycle.connect(settings, `changed::${DND_KEY}`, () => this._applyDnd())
  • privacy/privacy.js:25
    this._lifecycle.connect(settings, `changed::${PANEL_KEY}`, () => this._applyPanel())
  • theme/autoThemeSwitcher.js:28
    this._lifecycle.connect(settings, `changed::${LIGHT_HOURS_KEY}`, () => this._tick())
  • theme/autoThemeSwitcher.js:29
    this._lifecycle.connect(settings, `changed::${LIGHT_MINUTES_KEY}`, () => this._tick())
  • theme/autoThemeSwitcher.js:30
    this._lifecycle.connect(settings, `changed::${DARK_HOURS_KEY}`, () => this._tick())
  • theme/autoThemeSwitcher.js:31
    this._lifecycle.connect(settings, `changed::${DARK_MINUTES_KEY}`, () => this._tick())

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

  • clipboard/clipboardHistory.js:53
        this._startupIdleId = GLib.idle_add(GLib.PRIORITY_DEFAULT_IDLE, () => {
          this._startupIdleId = 0;
          this._monitor?.start();
          return GLib.SOURCE_REMOVE;
        })
  • shared/ui/dash.js:900
          this._autohideTimeoutId = GLib.timeout_add(GLib.PRIORITY_DEFAULT, AUTOHIDE_TIMEOUT, () => {
            if (this._isDestroyed) {
              this._autohideTimeoutId = 0;
              return GLib.SOURCE_REMOVE;
            }
            if (this._dashContainerHasHover()) {
              this._autohideTimeoutId = 0;
  • shared/ui/dash.js:861
                  this._springLoadTimerId = GLib.timeout_add(
                    GLib.PRIORITY_DEFAULT,
                    SPRING_LOAD_DELAY,
                    () => {
                      this._springLoadTimerId = 0;
                      if (this._isDestroyed) return GLib.SOURCE_REMOVE;
                      const windo
  • shared/ui/dash.js:1007
          this._workAreaUpdateId = GLib.idle_add(GLib.PRIORITY_DEFAULT, () => {
            this._workAreaUpdateId = 0;
            if (this._workArea) {
              this.applyWorkArea(this._workArea);
            }
            return GLib.SOURCE_REMOVE;
          })
  • theme/autoThemeSwitcher.js:83
        this._sourceId = GLib.timeout_add_seconds(GLib.PRIORITY_DEFAULT, delay, () => {
          this._sourceId = null;
          this._tick();
          return GLib.SOURCE_REMOVE;
        })

All Versions

Version Status
50.10 (27) Unreviewed
50.9 (26) Active
50.8 (25) Active
50.6 (24) Active
50.5 (23) Rejected
50.4 (22) Rejected
50.2 (21) Rejected
50.3 (20) Rejected
50.2 (19) Rejected
18 Rejected
17 Active
16 Active
15 Rejected
14 Rejected
13 Rejected
12 Rejected
11 Rejected
10 Active
9 Rejected
8 Active
7 Rejected
6 Active
5 Active
4 Rejected
3 Rejected
2 Rejected
1 Rejected

Previous Reviews on this Version

leandromqrs posted a review
Very very very sorry about the very large diff :'(. I need to change the architecture to make possible a mobile approach Most of shexli is false-positive. Like the PopupMenuItem that does not have destroy function, just remove