Review of "Dynamic Island" version 1.0 (1)

Details Page Preview

Turns the top bar into a frosted-glass island in the middle of the screen, with the time, date and battery. Click it for a control center: Wi-Fi, Bluetooth and the rest of Quick Settings, sliders, toggles, your open apps and other extensions' icons. Notifications appear in the island, the bell on its left opens a notification center and the bubble on its right shows what is playing. It slides out of the way in fullscreen or when a window reaches under it.

Extension Homepage
https://github.com/HIMURAw/gnome-dynamic-island

No comments.

FAQ

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

  • extension.js:492
    this._art = new St.Icon({style_class: 'dynada-art', icon_size: ART_SIZE})
  • extension.js:482
            this._artButton = new St.Button({
                style_class: 'dynada-art-button',
                can_focus: true,
                width: ART_SIZE,
                height: ART_SIZE,
                y_align: Clutter.ActorAlign.CENTER,
            })
  • extension.js:458
            this._backButton = new St.Button({
                style_class: 'dynada-back',
                can_focus: true,
                x_align: Clutter.ActorAlign.START,
                child: content,
            })
  • extension.js:603
    this._badge = new St.Widget({style_class: 'dynada-badge', visible: false})
  • extension.js:363
            this._batteryColumn = new St.BoxLayout({
                orientation: Clutter.Orientation.VERTICAL,
                y_align: Clutter.ActorAlign.CENTER,
            })
  • extension.js:368
    this._batteryState = new St.Label({style_class: 'dynada-battery-state', x_align: Clutter.ActorAlign.END})
  • extension.js:601
    this._bellIcon = new St.Icon({gicon: bellIcon(this.dir), icon_size: 16})
  • extension.js:367
    this._bigBattery = new St.Label({style_class: 'dynada-big-battery', x_align: Clutter.ActorAlign.END})
  • extension.js:358
    this._bigTime = new St.Label({style_class: 'dynada-big-time'})
  • extension.js:639
            this._bubbleButton = new St.Button({
                style_class: 'dynada-bubble-button',
                can_focus: true,
                accessible_name: _('Now playing'),
                x_expand: true,
                y_expand: true,
                child: this._bubbleIcon,
            })
  • extension.js:638
    this._bubbleIcon = new St.Icon({icon_name: 'audio-x-generic-symbolic', icon_size: 16})
  • extension.js:398
            this._ccConnect = new St.BoxLayout({
                style_class: 'dynada-card dynada-cc-connect',
                orientation: Clutter.Orientation.VERTICAL,
                x_expand: true,
                visible: false,
            })
  • extension.js:436
            this._ccExtra = new St.BoxLayout({
                style_class: 'dynada-cc-extra',
                orientation: Clutter.Orientation.VERTICAL,
                x_expand: true,
                visible: false,
            })
  • extension.js:409
            this._ccSliders = new St.BoxLayout({
                style_class: 'dynada-cc-sliders',
                orientation: Clutter.Orientation.VERTICAL,
                x_expand: true,
                visible: false,
            })
  • extension.js:444
    this._ccSystem = new St.BoxLayout({style_class: 'dynada-cc-system', x_expand: true, visible: false})
  • extension.js:417
            this._ccTiles = new St.Widget({
                style_class: 'dynada-cc-tiles',
                x_expand: true,
                layout_manager: new TileGridLayout(2, TILE_HEIGHT, 10),
                visible: false,
            })
  • extension.js:396
    this._ccTop = new St.BoxLayout({style_class: 'dynada-cc-top', x_expand: true})
  • extension.js:320
    this._compactBattery = new St.BoxLayout({style_class: 'dynada-battery', y_align: Clutter.ActorAlign.CENTER})
  • extension.js:321
    this._compactBatteryIcon = new St.Icon({style_class: 'dynada-battery-icon'})
  • extension.js:322
    this._compactBatteryLabel = new St.Label({y_align: Clutter.ActorAlign.CENTER})
  • extension.js:318
    this._compactDate = new St.Label({style_class: 'dynada-compact-date', y_align: Clutter.ActorAlign.CENTER})
  • extension.js:317
    this._compactTime = new St.Label({style_class: 'dynada-compact-time', y_align: Clutter.ActorAlign.CENTER})
  • extension.js:350
            this._controlsHeader = new St.Button({
                style_class: 'dynada-header',
                can_focus: true,
                accessible_name: _('Close Dynamic Island'),
                x_expand: true,
                child: header,
            })
  • extension.js:465
            this._detailBox = new St.BoxLayout({
                style_class: 'dynada-detail-box',
                orientation: Clutter.Orientation.VERTICAL,
                x_expand: true,
            })
  • extension.js:512
    this._elapsed = new St.Label({style_class: 'dynada-time-label', y_align: Clutter.ActorAlign.CENTER})
  • extension.js:359
    this._longDate = new St.Label({style_class: 'dynada-long-date'})
  • extension.js:502
    this._mediaApp = new St.Label({style_class: 'dynada-media-app'})
  • extension.js:501
    this._mediaArtist = new St.Label({style_class: 'dynada-media-artist'})
  • extension.js:500
    this._mediaTitle = new St.Label({style_class: 'dynada-media-title'})
  • extension.js:378
            this._muteButton = new St.Button({
                style_class: 'dynada-round-button',
                can_focus: true,
                accessible_name: _('Mute or unmute'),
                child: new St.Icon({style_class: 'dynada-volume-icon', icon_name: 'audio-volume-high-symbolic'}),
            })
  • extension.js:570
    this._notificationApp = new St.Label({style_class: 'dynada-notification-app'})
  • extension.js:572
    this._notificationBody = new St.Label({style_class: 'dynada-notification-body'})
  • extension.js:562
    this._notificationIcon = new St.Icon({icon_size: NOTIFICATION_ICON})
  • extension.js:571
    this._notificationTitle = new St.Label({style_class: 'dynada-notification-title'})
  • extension.js:511
    this._progressRow = new St.BoxLayout({style_class: 'dynada-progress-row', x_expand: true})
  • extension.js:514
    this._remaining = new St.Label({style_class: 'dynada-time-label', y_align: Clutter.ActorAlign.CENTER})
  • extension.js:520
    this._transport = new St.BoxLayout({style_class: 'dynada-transport', x_align: Clutter.ActorAlign.CENTER})
  • extension.js:426
            this._tray = new St.Widget({
                style_class: 'dynada-tray',
                x_expand: true,
                layout_manager: new TileGridLayout(6, 44, 8),
                visible: false,
            })
  • extension.js:388
    this._volumeLabel = new St.Label({style_class: 'dynada-volume-label', y_align: Clutter.ActorAlign.CENTER})
  • extension.js:377
    this._volumeRow = new St.BoxLayout({style_class: 'dynada-volume dynada-chip', x_expand: 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

  • extension.js:492
    this._art = new St.Icon({style_class: 'dynada-art', icon_size: ART_SIZE})
  • extension.js:482
            this._artButton = new St.Button({
                style_class: 'dynada-art-button',
                can_focus: true,
                width: ART_SIZE,
                height: ART_SIZE,
                y_align: Clutter.ActorAlign.CENTER,
            })
  • extension.js:458
            this._backButton = new St.Button({
                style_class: 'dynada-back',
                can_focus: true,
                x_align: Clutter.ActorAlign.START,
                child: content,
            })
  • extension.js:603
    this._badge = new St.Widget({style_class: 'dynada-badge', visible: false})
  • extension.js:363
            this._batteryColumn = new St.BoxLayout({
                orientation: Clutter.Orientation.VERTICAL,
                y_align: Clutter.ActorAlign.CENTER,
            })
  • extension.js:368
    this._batteryState = new St.Label({style_class: 'dynada-battery-state', x_align: Clutter.ActorAlign.END})
  • extension.js:601
    this._bellIcon = new St.Icon({gicon: bellIcon(this.dir), icon_size: 16})
  • extension.js:367
    this._bigBattery = new St.Label({style_class: 'dynada-big-battery', x_align: Clutter.ActorAlign.END})
  • extension.js:358
    this._bigTime = new St.Label({style_class: 'dynada-big-time'})
  • extension.js:639
            this._bubbleButton = new St.Button({
                style_class: 'dynada-bubble-button',
                can_focus: true,
                accessible_name: _('Now playing'),
                x_expand: true,
                y_expand: true,
                child: this._bubbleIcon,
            })
  • extension.js:638
    this._bubbleIcon = new St.Icon({icon_name: 'audio-x-generic-symbolic', icon_size: 16})
  • extension.js:398
            this._ccConnect = new St.BoxLayout({
                style_class: 'dynada-card dynada-cc-connect',
                orientation: Clutter.Orientation.VERTICAL,
                x_expand: true,
                visible: false,
            })
  • extension.js:436
            this._ccExtra = new St.BoxLayout({
                style_class: 'dynada-cc-extra',
                orientation: Clutter.Orientation.VERTICAL,
                x_expand: true,
                visible: false,
            })
  • extension.js:409
            this._ccSliders = new St.BoxLayout({
                style_class: 'dynada-cc-sliders',
                orientation: Clutter.Orientation.VERTICAL,
                x_expand: true,
                visible: false,
            })
  • extension.js:444
    this._ccSystem = new St.BoxLayout({style_class: 'dynada-cc-system', x_expand: true, visible: false})
  • extension.js:417
            this._ccTiles = new St.Widget({
                style_class: 'dynada-cc-tiles',
                x_expand: true,
                layout_manager: new TileGridLayout(2, TILE_HEIGHT, 10),
                visible: false,
            })
  • extension.js:396
    this._ccTop = new St.BoxLayout({style_class: 'dynada-cc-top', x_expand: true})
  • extension.js:320
    this._compactBattery = new St.BoxLayout({style_class: 'dynada-battery', y_align: Clutter.ActorAlign.CENTER})
  • extension.js:321
    this._compactBatteryIcon = new St.Icon({style_class: 'dynada-battery-icon'})
  • extension.js:322
    this._compactBatteryLabel = new St.Label({y_align: Clutter.ActorAlign.CENTER})
  • extension.js:318
    this._compactDate = new St.Label({style_class: 'dynada-compact-date', y_align: Clutter.ActorAlign.CENTER})
  • extension.js:317
    this._compactTime = new St.Label({style_class: 'dynada-compact-time', y_align: Clutter.ActorAlign.CENTER})
  • extension.js:350
            this._controlsHeader = new St.Button({
                style_class: 'dynada-header',
                can_focus: true,
                accessible_name: _('Close Dynamic Island'),
                x_expand: true,
                child: header,
            })
  • extension.js:465
            this._detailBox = new St.BoxLayout({
                style_class: 'dynada-detail-box',
                orientation: Clutter.Orientation.VERTICAL,
                x_expand: true,
            })
  • extension.js:512
    this._elapsed = new St.Label({style_class: 'dynada-time-label', y_align: Clutter.ActorAlign.CENTER})
  • extension.js:359
    this._longDate = new St.Label({style_class: 'dynada-long-date'})
  • extension.js:502
    this._mediaApp = new St.Label({style_class: 'dynada-media-app'})
  • extension.js:501
    this._mediaArtist = new St.Label({style_class: 'dynada-media-artist'})
  • extension.js:500
    this._mediaTitle = new St.Label({style_class: 'dynada-media-title'})
  • extension.js:378
            this._muteButton = new St.Button({
                style_class: 'dynada-round-button',
                can_focus: true,
                accessible_name: _('Mute or unmute'),
                child: new St.Icon({style_class: 'dynada-volume-icon', icon_name: 'audio-volume-high-symbolic'}),
            })
  • extension.js:570
    this._notificationApp = new St.Label({style_class: 'dynada-notification-app'})
  • extension.js:572
    this._notificationBody = new St.Label({style_class: 'dynada-notification-body'})
  • extension.js:562
    this._notificationIcon = new St.Icon({icon_size: NOTIFICATION_ICON})
  • extension.js:571
    this._notificationTitle = new St.Label({style_class: 'dynada-notification-title'})
  • extension.js:511
    this._progressRow = new St.BoxLayout({style_class: 'dynada-progress-row', x_expand: true})
  • extension.js:514
    this._remaining = new St.Label({style_class: 'dynada-time-label', y_align: Clutter.ActorAlign.CENTER})
  • extension.js:221
    this._strip = new St.Widget({layout_manager: this._layout})
  • extension.js:520
    this._transport = new St.BoxLayout({style_class: 'dynada-transport', x_align: Clutter.ActorAlign.CENTER})
  • extension.js:426
            this._tray = new St.Widget({
                style_class: 'dynada-tray',
                x_expand: true,
                layout_manager: new TileGridLayout(6, 44, 8),
                visible: false,
            })
  • extension.js:388
    this._volumeLabel = new St.Label({style_class: 'dynada-volume-label', y_align: Clutter.ActorAlign.CENTER})
  • extension.js:377
    this._volumeRow = new St.BoxLayout({style_class: 'dynada-volume dynada-chip', x_expand: 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

  • extension.js:984
            this._notificationDestroyId = notification.connect('destroy', () => {
                this._notificationDestroyId = 0;
                if (this._notification === notification && this._mode === 'notification')
                    this._close();
            })
  • extension.js:223
    this._strip.connect('destroy', () => (this._stripGone = true))

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:1672
            this._adoptIdle = GLib.idle_add(GLib.PRIORITY_DEFAULT, () => {
                this._timeouts.delete(this._adoptIdle);
                this._adoptIdle = 0;
                for (const box of this._panelBoxes()) {
                    for (const child of box.get_children())
                        this._adopt(chil
  • extension.js:909
            this._centerIdle = GLib.idle_add(GLib.PRIORITY_DEFAULT, () => {
                this._timeouts.delete(this._centerIdle);
                this._centerIdle = 0;
                if (this._mode === 'center') {
                    this._center.refresh();
                    this._center.acknowledgeAll();
               
  • extension.js:1094
            this._overlapIdle = GLib.idle_add(GLib.PRIORITY_DEFAULT_IDLE, () => {
                this._timeouts.delete(this._overlapIdle);
                this._overlapIdle = 0;
                this._checkOverlap();
                return GLib.SOURCE_REMOVE;
            })
  • extension.js:1652
                    this._panelIdle = GLib.idle_add(GLib.PRIORITY_DEFAULT, () => {
                        this._timeouts.delete(this._panelIdle);
                        this._panelIdle = 0;
                        Main.panel.hide();
                        return GLib.SOURCE_REMOVE;
                    })

All Versions

Version Status
1.0 (1) Unreviewed