Review of "Stage Manager" version 2

Details Page Preview

macOS Stage Manager-like window management for GNOME. Group windows into stages only one group is visible at a time, others appear as stacked thumbnail cards in a left sidebar. Click a card to swap stages. Supports per-app mode, workspace mode, bell-curve hover animations, and 3D perspective.

Extension Homepage
https://github.com/itsdigvijaysing/gnome-stage-manager

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 5

Shexli found 5 issues that may need reviewer attention.

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-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:262
            this._box = new St.BoxLayout({
                vertical: true,
                x_align: Clutter.ActorAlign.CENTER,
                y_align: Clutter.ActorAlign.START,
                style: 'padding: 40px 0px; spacing: 10px;',
            })
  • extension.js:253
            this._scroll = new St.ScrollView({
                overlay_scrollbars: true,
                hscrollbar_policy: St.PolicyType.NEVER,
                vscrollbar_policy: St.PolicyType.NEVER,
                clip_to_allocation: 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:238
            this._edge.connect('enter-event', () => {
                if (!this._fullscreen()) this._show();
            })
  • extension.js:277
            this._panel.connect('enter-event', () => {
                this._hovered = true;
                this._kill('_hideTimer');
            })
  • extension.js:281
            this._panel.connect('leave-event', () => {
                this._hovered = false;
                this._hoveredIdx = -1;
                this._resetAllCardScales();
                this._destroyPreview();
                if (this._settings.get_boolean('sidebar-auto-hide'))
                    this._scheduleHide();
    
  • extension.js:270
            this._scroll.connect('scroll-event', (_actor, event) => {
                const adj = this._scroll.vadjustment;
                const [, dy] = event.get_scroll_delta();
                adj.value = Math.max(0, Math.min(adj.upper - adj.page_size, adj.value + dy * 55));
                return Clutter.EVENT_STO
  • extension.js:727
            card.connect('button-release-event', () => {
                this._destroyPreview();
                this._swapToGroup(group);
                return Clutter.EVENT_STOP;
            })
  • extension.js:756
            card.connect('button-release-event', () => {
                this._destroyPreview();
                this._activateApp(group);
                return Clutter.EVENT_STOP;
            })
  • extension.js:868
            card.connect('button-release-event', () => {
                this._destroyPreview();
                if (!isCurrent) ws.activate(global.get_current_time());
                if (this._settings.get_boolean('sidebar-auto-hide')) this._scheduleHide();
                this._scheduleRefresh();
                return 
  • extension.js:938
            card.connect('enter-event', () => {
                this._hovered = true;
                this._kill('_hideTimer');
                this._hoveredIdx = cardIdx;
    
                this._applyBellCurve(cardIdx);
    
                // Glow on front layer
                const front = thumb._frontLayer;
                if (fro
  • extension.js:968
            card.connect('leave-event', () => {
                this._hoveredIdx = -1;
    
                // Reset all cards
                const base = this._BASE_SCALE;
                const angle = this._PERSP_ANGLE;
                for (const c of this._cards) {
                    c.ease({
                        scale_x: base
  • extension.js:319
    this._settings.connect('changed::enable-stage-sidebar', () => {
                if (!this._settings.get_boolean('enable-stage-sidebar') && this._visible) this._hide();
            })

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:564
            this._hideTimer = GLib.timeout_add(GLib.PRIORITY_DEFAULT, this._HIDE_DELAY_MS, () => {
                this._hideTimer = null;
                if (!this._hovered) this._hide();
                return GLib.SOURCE_REMOVE;
            })
  • extension.js:961
                this._hoverTimer = GLib.timeout_add(GLib.PRIORITY_DEFAULT, 220, () => {
                    this._hoverTimer = null;
                    this._showPreview(card, windows);
                    return GLib.SOURCE_REMOVE;
                })
  • extension.js:493
            this._refreshTimer = GLib.timeout_add(GLib.PRIORITY_DEFAULT, 120, () => {
                this._refreshTimer = null;
                if (this._visible) this._refresh();
                return GLib.SOURCE_REMOVE;
            })
  • extension.js:485
            this._swapTimer = GLib.timeout_add(GLib.PRIORITY_DEFAULT, 400, () => {
                this._swapTimer = null;
                this._swapping = false;
                return GLib.SOURCE_REMOVE;
            })

EGO-L-007 warning

main loop sources should be removed before being recreated

Main loop sources should be removed before creating a new source on the same field.

Remove main loop sources

  • extension.js:573
            this._refreshTimer = GLib.timeout_add(GLib.PRIORITY_DEFAULT, 200, () => {
                this._refreshTimer = null;
                if (this._visible && !this._hovered) this._refresh();
                return GLib.SOURCE_REMOVE;
            })

All Versions

Version Status
2.0.4 (15) Active
2.0.3 (14) Active
2.0.3 (13) Active
2.0.2 (12) Rejected
2.0.1 (11) Rejected
2.0.0 (10) Rejected
1.4.1 (9) Active
1.4.0 (8) Rejected
1.4.0 (7) Rejected
1.4.0 (6) Rejected
1.3.2 (5) Active
1.3.1 (4) Active
1.3.1 (3) Rejected
2 Rejected
1 Rejected

Previous Reviews on this Version

AI-Developer posted a review
Updated the GitHub Details
AI-Developer posted a review
Please Review this new version. I have just updated the Version Correctly
dlandau rejected
Please check the shexli messages
AI-Developer posted a review
code updated