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
1.3.1 (3) Unreviewed
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