[gnome-shell-extensions/gnome-3-38] workspace-indicator: Use custom layout manager for thumbnails



commit 1276a880de78d6e4bce8814b7d2d987b7deab347
Author: Florian Müllner <fmuellner gnome org>
Date:   Wed Oct 21 02:34:41 2020 +0200

    workspace-indicator: Use custom layout manager for thumbnails
    
    The current code positions window previews explicitly using a fixed
    layout manager. For that it relies on a valid parent allocation,
    which is error-prone and frequently results in warnings.
    
    Address this by moving the positioning code into a custom layout
    manager, and only update the visibility from the window preview.
    
    https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/issues/260

 extensions/workspace-indicator/extension.js | 69 +++++++++++++++--------------
 1 file changed, 35 insertions(+), 34 deletions(-)
---
diff --git a/extensions/workspace-indicator/extension.js b/extensions/workspace-indicator/extension.js
index 6d13acf..12634e2 100644
--- a/extensions/workspace-indicator/extension.js
+++ b/extensions/workspace-indicator/extension.js
@@ -30,27 +30,15 @@ class WindowPreview extends St.Button {
         this.connect('destroy', this._onDestroy.bind(this));
 
         this._sizeChangedId = this._window.connect('size-changed',
-            this._relayout.bind(this));
+            () => this.queue_relayout());
         this._positionChangedId = this._window.connect('position-changed',
-            this._relayout.bind(this));
+            () => this.queue_relayout());
         this._minimizedChangedId = this._window.connect('notify::minimized',
-            this._relayout.bind(this));
+            this._updateVisible.bind(this));
         this._monitorEnteredId = global.display.connect('window-entered-monitor',
-            this._relayout.bind(this));
+            this._updateVisible.bind(this));
         this._monitorLeftId = global.display.connect('window-left-monitor',
-            this._relayout.bind(this));
-
-        // Do initial layout when we get a parent
-        let id = this.connect('parent-set', () => {
-            this.disconnect(id);
-            if (!this.get_parent())
-                return;
-            this._laterId = Meta.later_add(Meta.LaterType.BEFORE_REDRAW, () => {
-                this._laterId = 0;
-                this._relayout();
-                return false;
-            });
-        });
+            this._updateVisible.bind(this));
 
         this._focusChangedId = global.display.connect('notify::focus-window',
             this._onFocusChanged.bind(this));
@@ -69,8 +57,6 @@ class WindowPreview extends St.Button {
         global.display.disconnect(this._monitorEnteredId);
         global.display.disconnect(this._monitorLeftId);
         global.display.disconnect(this._focusChangedId);
-        if (this._laterId)
-            Meta.later_remove(this._laterId);
     }
 
     _onFocusChanged() {
@@ -80,26 +66,41 @@ class WindowPreview extends St.Button {
             this.remove_style_class_name('active');
     }
 
-    _relayout() {
+    _updateVisible() {
         let monitor = Main.layoutManager.findIndexForActor(this);
         this.visible = monitor === this._window.get_monitor() &&
             this._window.window_type !== Meta.WindowType.DESKTOP &&
             this._window.showing_on_its_workspace();
+    }
+});
 
-        if (!this.visible)
-            return;
+let WorkspaceLayout = GObject.registerClass(
+class WorkspaceLayout extends Clutter.LayoutManager {
+    vfunc_get_preferred_width() {
+        return [0, 0];
+    }
+
+    vfunc_get_preferred_height() {
+        return [0, 0];
+    }
 
-        let workArea = Main.layoutManager.getWorkAreaForMonitor(monitor);
-        let hscale = this.get_parent().allocation.get_width() / workArea.width;
-        let vscale = this.get_parent().allocation.get_height() / workArea.height;
-
-        let frameRect = this._window.get_frame_rect();
-        this.set_size(
-            Math.round(Math.min(frameRect.width, workArea.width) * hscale),
-            Math.round(Math.min(frameRect.height, workArea.height) * vscale));
-        this.set_position(
-            Math.round(frameRect.x * hscale),
-            Math.round(frameRect.y * vscale));
+    vfunc_allocate(container, box) {
+        const monitor = Main.layoutManager.findIndexForActor(container);
+        const workArea = Main.layoutManager.getWorkAreaForMonitor(monitor);
+        const hscale = box.get_width() / workArea.width;
+        const vscale = box.get_height() / workArea.height;
+
+        for (const child of container) {
+            const childBox = new Clutter.ActorBox();
+            const frameRect = child.metaWindow.get_frame_rect();
+            childBox.set_size(
+                Math.min(frameRect.width, workArea.width) * hscale,
+                Math.min(frameRect.height, workArea.height) * vscale);
+            childBox.set_origin(
+                Math.round(frameRect.x * hscale),
+                Math.round(frameRect.y * vscale));
+            child.allocate(childBox);
+        }
     }
 });
 
@@ -109,7 +110,7 @@ class WorkspaceThumbnail extends St.Button {
         super._init({
             style_class: 'workspace',
             child: new Clutter.Actor({
-                layout_manager: new Clutter.BinLayout(),
+                layout_manager: new WorkspaceLayout(),
                 clip_to_allocation: true,
             }),
         });


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]