[gnome-shell/wip/fmuellner/window-preview-translucency: 170/171] workspace: Let WindowClone inherit from StWidget



commit be85f7710164ce95abbc6030c883add46df0e103
Author: Florian Müllner <fmuellner gnome org>
Date:   Wed Nov 14 19:26:33 2018 +0100

    workspace: Let WindowClone inherit from StWidget
    
    Using inheritance over delegation will give us more control over
    the actor drawing.
    
    https://gitlab.gnome.org/GNOME/gnome-shell/issues/774

 js/ui/workspace.js | 181 +++++++++++++++++++++++++++--------------------------
 1 file changed, 93 insertions(+), 88 deletions(-)
---
diff --git a/js/ui/workspace.js b/js/ui/workspace.js
index 34c0b1f0c..868f91bc9 100644
--- a/js/ui/workspace.js
+++ b/js/ui/workspace.js
@@ -94,15 +94,25 @@ class WindowCloneLayout extends Clutter.LayoutManager {
     }
 });
 
-var WindowClone = class {
-    constructor(realWindow, workspace) {
+var WindowClone = GObject.registerClass({
+    Signals: {
+        'drag-begin': {},
+        'drag-cancelled': {},
+        'drag-end': {},
+        'hide-chrome': {},
+        'selected': { param_types: [GObject.TYPE_UINT] },
+        'show-chrome': {},
+        'size-changed': {}
+    },
+}, class WindowClone extends St.Widget {
+    _init(realWindow, workspace) {
         this.realWindow = realWindow;
         this.metaWindow = realWindow.meta_window;
         this.metaWindow._delegate = this;
         this._workspace = workspace;
 
         this._windowClone = new Clutter.Clone({ source: realWindow });
-        // We expect this.actor to be used for all interaction rather than
+        // We expect this to be used for all interaction rather than
         // this._windowClone; as the former is reactive and the latter
         // is not, this just works for most cases. However, for DND all
         // actors are picked, so DND operations would operate on the clone.
@@ -113,14 +123,16 @@ var WindowClone = class {
         // the invisible border; this is inconvenient; rather than trying
         // to compensate all over the place we insert a ClutterActor into
         // the hierarchy that is sized to only the visible portion.
-        this.actor = new St.Widget({ reactive: true,
-                                     can_focus: true,
-                                     accessible_role: Atk.Role.PUSH_BUTTON,
-                                     layout_manager: new WindowCloneLayout() });
+        super._init({
+            reactive: true,
+            can_focus: true,
+            accessible_role: Atk.Role.PUSH_BUTTON,
+            layout_manager: new WindowCloneLayout()
+        });
 
-        this.actor.add_child(this._windowClone);
+        this.add_child(this._windowClone);
 
-        this.actor._delegate = this;
+        this._delegate = this;
 
         this.slotId = 0;
         this._slot = [0, 0, 0, 0];
@@ -142,23 +154,23 @@ var WindowClone = class {
 
         this._updateAttachedDialogs();
         this._computeBoundingBox();
-        this.actor.x = this._boundingBox.x;
-        this.actor.y = this._boundingBox.y;
+        this.x = this._boundingBox.x;
+        this.y = this._boundingBox.y;
 
         let clickAction = new Clutter.ClickAction();
         clickAction.connect('clicked', this._onClicked.bind(this));
         clickAction.connect('long-press', this._onLongPress.bind(this));
-        this.actor.add_action(clickAction);
-        this.actor.connect('destroy', this._onDestroy.bind(this));
-        this.actor.connect('key-press-event', this._onKeyPress.bind(this));
+        this.add_action(clickAction);
+        this.connect('destroy', this._onDestroy.bind(this));
+        this.connect('key-press-event', this._onKeyPress.bind(this));
 
-        this.actor.connect('enter-event', () => this.emit('show-chrome'));
-        this.actor.connect('key-focus-in', () => this.emit('show-chrome'));
+        this.connect('enter-event', () => this.emit('show-chrome'));
+        this.connect('key-focus-in', () => this.emit('show-chrome'));
 
-        this.actor.connect('leave-event', () => this.emit('hide-chrome'));
-        this.actor.connect('key-focus-out', () => this.emit('hide-chrome'));
+        this.connect('leave-event', () => this.emit('hide-chrome'));
+        this.connect('key-focus-out', () => this.emit('hide-chrome'));
 
-        this._draggable = DND.makeDraggable(this.actor,
+        this._draggable = DND.makeDraggable(this,
                                             { restoreOnSuccess: true,
                                               manualMode: true,
                                               dragActorMaxSize: WINDOW_DND_SIZE,
@@ -185,7 +197,7 @@ var WindowClone = class {
 
     deleteAll() {
         // Delete all windows, starting from the bottom-most (most-modal) one
-        let windows = this.actor.get_children();
+        let windows = this.get_children();
         for (let i = windows.length - 1; i >= 1; i--) {
             let realWindow = windows[i].source;
             let metaWindow = realWindow.meta_window;
@@ -215,7 +227,7 @@ var WindowClone = class {
     }
 
     hasAttachedDialogs() {
-        return this.actor.get_n_children() > 1;
+        return this.get_n_children() > 1;
     }
 
     _doAddAttachedDialog(metaWin, realWin) {
@@ -229,7 +241,7 @@ var WindowClone = class {
 
             this._onMetaWindowSizeChanged();
         });
-        this.actor.add_child(clone);
+        this.add_child(clone);
     }
 
     _updateAttachedDialogs() {
@@ -267,7 +279,7 @@ var WindowClone = class {
     _computeBoundingBox() {
         let rect = this.metaWindow.get_frame_rect();
 
-        this.actor.get_children().forEach(child => {
+        this.get_children().forEach(child => {
             let realWindow;
             if (child == this._windowClone)
                 realWindow = this.realWindow;
@@ -280,7 +292,7 @@ var WindowClone = class {
 
         // Convert from a MetaRectangle to a native JS object
         this._boundingBox = { x: rect.x, y: rect.y, width: rect.width, height: rect.height };
-        this.actor.layout_manager.boundingBox = rect;
+        this.layout_manager.boundingBox = rect;
     }
 
     // Find the actor just below us, respecting reparenting done by DND code
@@ -306,17 +318,13 @@ var WindowClone = class {
 
         let actualAbove = this.getActualStackAbove();
         if (actualAbove == null)
-            this.actor.lower_bottom();
+            this.lower_bottom();
         else
-            this.actor.raise(actualAbove);
-    }
-
-    destroy() {
-        this.actor.destroy();
+            this.raise(actualAbove);
     }
 
     _disconnectSignals() {
-        this.actor.get_children().forEach(child => {
+        this.get_children().forEach(child => {
             let realWindow;
             if (child == this._windowClone)
                 realWindow = this.realWindow;
@@ -338,14 +346,12 @@ var WindowClone = class {
         this._disconnectSignals();
 
         this.metaWindow._delegate = null;
-        this.actor._delegate = null;
+        this._delegate = null;
 
         if (this.inDrag) {
             this.emit('drag-end');
             this.inDrag = false;
         }
-
-        this.disconnectAll();
     }
 
     _activate() {
@@ -393,8 +399,8 @@ var WindowClone = class {
 
     _onDragBegin(draggable, time) {
         this._dragSlot = this._slot;
-        [this.dragOrigX, this.dragOrigY] = this.actor.get_position();
-        this.dragOrigScale = this.actor.scale_x;
+        [this.dragOrigX, this.dragOrigY] = this.get_position();
+        this.dragOrigScale = this.scale_x;
         this.inDrag = true;
         this.emit('drag-begin');
     }
@@ -417,18 +423,17 @@ var WindowClone = class {
         // We may not have a parent if DnD completed successfully, in
         // which case our clone will shortly be destroyed and replaced
         // with a new one on the target workspace.
-        if (this.actor.get_parent() != null) {
+        if (this.get_parent() != null) {
             if (this._stackAbove == null)
-                this.actor.lower_bottom();
+                this.lower_bottom();
             else
-                this.actor.raise(this._stackAbove);
+                this.raise(this._stackAbove);
         }
 
 
         this.emit('drag-end');
     }
-};
-Signals.addSignalMethods(WindowClone.prototype);
+});
 
 
 /**
@@ -452,7 +457,7 @@ var WindowOverlay = class {
         this.title = new St.Label({ style_class: 'window-caption',
                                     text: this._getCaption() });
         this.title.clutter_text.ellipsize = Pango.EllipsizeMode.END;
-        windowClone.actor.label_actor = this.title;
+        windowClone.label_actor = this.title;
 
         this._maxTitleWidth = -1;
 
@@ -467,7 +472,7 @@ var WindowOverlay = class {
 
         this.closeButton.connect('clicked', () => this._windowClone.deleteAll());
 
-        windowClone.actor.connect('destroy', this._onDestroy.bind(this));
+        windowClone.connect('destroy', this._onDestroy.bind(this));
         windowClone.connect('show-chrome', this._onShowChrome.bind(this));
         windowClone.connect('hide-chrome', this._onHideChrome.bind(this));
 
@@ -503,7 +508,7 @@ var WindowOverlay = class {
     show() {
         this._hidden = false;
 
-        if (this._windowClone.actor['has-pointer'])
+        if (this._windowClone['has-pointer'])
             this._animateVisible();
     }
 
@@ -675,7 +680,7 @@ var WindowOverlay = class {
     _idleHideOverlay() {
         this._idleHideOverlayId = 0;
 
-        if (!this._windowClone.actor['has-pointer'] &&
+        if (!this._windowClone['has-pointer'] &&
             !this.closeButton['has-pointer'])
             this._animateInvisible();
 
@@ -1296,8 +1301,8 @@ var Workspace = class {
             if (clone.inDrag)
                 continue;
 
-            let cloneWidth = clone.actor.width * scale;
-            let cloneHeight = clone.actor.height * scale;
+            let cloneWidth = clone.width * scale;
+            let cloneHeight = clone.height * scale;
             clone.slot = [x, y, cloneWidth, cloneHeight];
 
             let cloneCenter = x + cloneWidth / 2;
@@ -1312,10 +1317,10 @@ var Workspace = class {
             if (!clone.positioned) {
                 // This window appeared after the overview was already up
                 // Grow the clone from the center of the slot
-                clone.actor.x = x + cloneWidth / 2;
-                clone.actor.y = y + cloneHeight / 2;
-                clone.actor.scale_x = 0;
-                clone.actor.scale_y = 0;
+                clone.x = x + cloneWidth / 2;
+                clone.y = y + cloneHeight / 2;
+                clone.scale_x = 0;
+                clone.scale_y = 0;
                 clone.positioned = true;
             }
 
@@ -1325,14 +1330,14 @@ var Workspace = class {
                      * therefore we need to resize them now so they
                      * can be scaled up later */
                     if (initialPositioning) {
-                        clone.actor.opacity = 0;
-                        clone.actor.scale_x = 0;
-                        clone.actor.scale_y = 0;
-                        clone.actor.x = x;
-                        clone.actor.y = y;
+                        clone.opacity = 0;
+                        clone.scale_x = 0;
+                        clone.scale_y = 0;
+                        clone.x = x;
+                        clone.y = y;
                     }
 
-                    Tweener.addTween(clone.actor,
+                    Tweener.addTween(clone,
                                      { opacity: 255,
                                        time: Overview.ANIMATION_TIME,
                                        transition: 'easeInQuad'
@@ -1342,10 +1347,10 @@ var Workspace = class {
                 this._animateClone(clone, clone.overlay, x, y, scale);
             } else {
                 // cancel any active tweens (otherwise they might override our changes)
-                Tweener.removeTweens(clone.actor);
-                clone.actor.set_position(x, y);
-                clone.actor.set_scale(scale, scale);
-                clone.actor.set_opacity(255);
+                Tweener.removeTweens(clone);
+                clone.set_position(x, y);
+                clone.set_scale(scale, scale);
+                clone.set_opacity(255);
                 clone.overlay.relayout(false);
                 this._showWindowOverlay(clone, clone.overlay);
             }
@@ -1366,13 +1371,13 @@ var Workspace = class {
                 clone.setStackAbove(this._dropRect);
             } else {
                 let previousClone = clones[i - 1];
-                clone.setStackAbove(previousClone.actor);
+                clone.setStackAbove(previousClone);
             }
         }
     }
 
     _animateClone(clone, overlay, x, y, scale) {
-        Tweener.addTween(clone.actor,
+        Tweener.addTween(clone,
                          { x: x,
                            y: y,
                            scale_x: scale,
@@ -1411,7 +1416,7 @@ var Workspace = class {
 
         let actorUnderPointer = global.stage.get_actor_at_pos(Clutter.PickMode.REACTIVE, x, y);
         for (let i = 0; i < this._windows.length; i++) {
-            if (this._windows[i].actor == actorUnderPointer)
+            if (this._windows[i] == actorUnderPointer)
                 return GLib.SOURCE_CONTINUE;
         }
 
@@ -1433,12 +1438,12 @@ var Workspace = class {
             // destroyed; we'd like to animate this, but it's too late at
             // this point.)
             if (win) {
-                let [stageX, stageY] = clone.actor.get_transformed_position();
-                let [stageWidth, stageHeight] = clone.actor.get_transformed_size();
+                let [stageX, stageY] = clone.get_transformed_position();
+                let [stageWidth, stageHeight] = clone.get_transformed_size();
                 win._overviewHint = {
                     x: stageX,
                     y: stageY,
-                    scale: stageWidth / clone.actor.width
+                    scale: stageWidth / clone.width
                 };
             }
             clone.destroy();
@@ -1518,11 +1523,11 @@ var Workspace = class {
             let scale = win._overviewHint.scale;
             delete win._overviewHint;
 
-            clone.slot = [x, y, clone.actor.width * scale, clone.actor.height * scale];
+            clone.slot = [x, y, clone.width * scale, clone.height * scale];
             clone.positioned = true;
 
-            clone.actor.set_position(x, y);
-            clone.actor.set_scale(scale, scale);
+            clone.set_position(x, y);
+            clone.set_scale(scale, scale);
             clone.overlay.relayout(false);
         }
 
@@ -1596,7 +1601,7 @@ var Workspace = class {
                 let overlay = this._windowOverlays[i];
                 if (overlay)
                     overlay.hide();
-                this._windows[i].actor.opacity = 0;
+                this._windows[i].opacity = 0;
             } else {
                 let fromTop = topIndex - i;
                 let time;
@@ -1605,7 +1610,7 @@ var Workspace = class {
                 else
                     time = windowBaseTime;
 
-                this._windows[i].actor.opacity = 255;
+                this._windows[i].opacity = 255;
                 this._fadeWindow(i, time, 0);
             }
         }
@@ -1619,7 +1624,7 @@ var Workspace = class {
 
         for (let i = 0; i < this._windows.length; i++) {
             let clone = this._windows[i];
-            Tweener.removeTweens(clone.actor);
+            Tweener.removeTweens(clone);
         }
 
         if (this._repositionWindowsId > 0) {
@@ -1654,7 +1659,7 @@ var Workspace = class {
                 let overlay = this._windowOverlays[i];
                 if (overlay)
                     overlay.hide();
-                this._windows[i].actor.opacity = 0;
+                this._windows[i].opacity = 0;
             } else {
                 let fromTop = topIndex - i;
                 let time;
@@ -1663,7 +1668,7 @@ var Workspace = class {
                 else
                     time = windowBaseTime * nTimeSlots;
 
-                this._windows[i].actor.opacity = 0;
+                this._windows[i].opacity = 0;
                 this._fadeWindow(i, time, 255);
             }
         }
@@ -1678,18 +1683,18 @@ var Workspace = class {
 
         if (clone.metaWindow.showing_on_its_workspace()) {
             let [origX, origY] = clone.getOriginalPosition();
-            clone.actor.scale_x = 1;
-            clone.actor.scale_y = 1;
-            clone.actor.x = origX;
-            clone.actor.y = origY;
-            Tweener.addTween(clone.actor,
+            clone.scale_x = 1;
+            clone.scale_y = 1;
+            clone.x = origX;
+            clone.y = origY;
+            Tweener.addTween(clone,
                              { time: time,
                                opacity: opacity,
                                transition: 'easeOutQuad'
                              });
         } else {
             // The window is hidden
-            clone.actor.opacity = 0;
+            clone.opacity = 0;
         }
     }
 
@@ -1706,7 +1711,7 @@ var Workspace = class {
 
         for (let i = 0; i < this._windows.length; i++) {
             let clone = this._windows[i];
-            Tweener.removeTweens(clone.actor);
+            Tweener.removeTweens(clone);
         }
 
         if (this._repositionWindowsId > 0) {
@@ -1732,7 +1737,7 @@ var Workspace = class {
 
         if (clone.metaWindow.showing_on_its_workspace()) {
             let [origX, origY] = clone.getOriginalPosition();
-            Tweener.addTween(clone.actor,
+            Tweener.addTween(clone,
                              { x: origX,
                                y: origY,
                                scale_x: 1.0,
@@ -1743,7 +1748,7 @@ var Workspace = class {
                              });
         } else {
             // The window is hidden, make it shrink and fade it out
-            Tweener.addTween(clone.actor,
+            Tweener.addTween(clone,
                              { scale_x: 0,
                                scale_y: 0,
                                opacity: 0,
@@ -1834,16 +1839,16 @@ var Workspace = class {
         clone.connect('size-changed', () => {
             this._recalculateWindowPositions(WindowPositionFlags.NONE);
         });
-        clone.actor.connect('destroy', () => {
+        clone.connect('destroy', () => {
             this._removeWindowClone(clone.metaWindow);
         });
 
-        this.actor.add_actor(clone.actor);
+        this.actor.add_actor(clone);
 
         overlay.connect('chrome-visible', () => {
             let focus = global.stage.key_focus;
             if (focus == null || this.actor.contains(focus))
-                clone.actor.grab_key_focus();
+                clone.grab_key_focus();
 
             this._windowOverlays.forEach(o => {
                 if (o != overlay)
@@ -1854,7 +1859,7 @@ var Workspace = class {
         if (this._windows.length == 0)
             clone.setStackAbove(null);
         else
-            clone.setStackAbove(this._windows[this._windows.length - 1].actor);
+            clone.setStackAbove(this._windows[this._windows.length - 1]);
 
         this._windows.push(clone);
         this._windowOverlays.push(overlay);


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