[gnome-shell-extensions] adapt native-window-placement to 3.9 changes



commit 64d76fef6a3d756130d19498e8795c3326bf7b86
Author: Wepmaschda <wepmaschda gmx de>
Date:   Sat May 25 02:59:50 2013 +0200

    adapt native-window-placement to 3.9 changes
    
    * remove unnecessary chromeHeight that breaks the system
    * copy original _updateWindowPositions from 3.9
    * use nativeWindowPlacement in update function
    * tidy up NaturalWindowPlacement function
    
    https://bugzilla.gnome.org/show_bug.cgi?id=699054

 extensions/native-window-placement/extension.js |  177 +++++++++++++++--------
 1 files changed, 120 insertions(+), 57 deletions(-)
---
diff --git a/extensions/native-window-placement/extension.js b/extensions/native-window-placement/extension.js
index d4f67e5..2fea947 100644
--- a/extensions/native-window-placement/extension.js
+++ b/extensions/native-window-placement/extension.js
@@ -138,47 +138,12 @@ function enable() {
      * PresentWindowsEffect::calculateWindowTransformationsNatural() from KDE, see:
      * 
https://projects.kde.org/projects/kde/kdebase/kde-workspace/repository/revisions/master/entry/kwin/effects/presentwindows/presentwindows.cpp
      */
-    Workspace.Workspace.prototype._calculateWindowTransformationsNatural = function(clones) {
+    Workspace.Workspace.prototype._calculateWindowTransformationsNatural = function(clones, area) {
         // As we are using pseudo-random movement (See "slot") we need to make sure the list
         // is always sorted the same way no matter which window is currently active.
 
-        let node = this.actor.get_theme_node();
-        let columnSpacing = node.get_length('-horizontal-spacing');
-        let rowSpacing = node.get_length('-vertical-spacing');
-        let padding = {
-            left: node.get_padding(St.Side.LEFT),
-            top: node.get_padding(St.Side.TOP),
-            bottom: node.get_padding(St.Side.BOTTOM),
-            right: node.get_padding(St.Side.RIGHT),
-        };
-
-        let closeButtonHeight, captionHeight;
-        let leftBorder, rightBorder;
-        // If the window captions are below the window, put an additional gap to account for them
-        if (!windowCaptionsOnTop && this._windowOverlays.length) {
-            // All of the overlays have the same chrome sizes,
-            // so just pick the first one.
-            let overlay = this._windowOverlays[0];
-            [closeButtonHeight, captionHeight] = overlay.chromeHeights();
-            [leftBorder, rightBorder] = overlay.chromeWidths();
-        } else {
-            [closeButtonHeight, captionHeight] = [0, 0];
-            [leftBorder, rightBorder] = [0, 0];
-        }
-
-        rowSpacing += captionHeight;
-        columnSpacing += (rightBorder + leftBorder) / 2;
-        padding.top += closeButtonHeight;
-        padding.bottom += captionHeight;
-        padding.left += leftBorder;
-        padding.right += rightBorder;
-
-        let area = new Rect(this._x + padding.left,
-                            this._y + padding.top,
-                            this._width - padding.left - padding.right,
-                            this._height - padding.top - padding.bottom);
-
-        let bounds = area.copy();
+        let area_rect = new Rect(area.x, area.y, area.width, area.height);
+        let bounds = area_rect.copy();
 
         let direction = 0;
         let directions = [];
@@ -221,7 +186,7 @@ function enable() {
                         if (diff[0] == 0 && diff[1] == 0)
                             diff[0] = 1;
                         // Try to keep screen/workspace aspect ratio
-                        if ( bounds.height / bounds.width > area.height / area.width )
+                        if ( bounds.height / bounds.width > area_rect.height / area_rect.width )
                             diff[0] *= 2;
                         else
                             diff[1] *= 2;
@@ -293,15 +258,15 @@ function enable() {
 
         // Work out scaling by getting the most top-left and most bottom-right window coords.
         let scale;
-        scale = Math.min(area.width / bounds.width,
-                         area.height / bounds.height,
+        scale = Math.min(area_rect.width / bounds.width,
+                         area_rect.height / bounds.height,
                          1.0);
 
         // Make bounding rect fill the screen size for later steps
-        bounds.x = bounds.x - (area.width - bounds.width * scale) / 2;
-        bounds.y = bounds.y - (area.height - bounds.height * scale) / 2;
-        bounds.width = area.width / scale;
-        bounds.height = area.height / scale;
+        bounds.x = bounds.x - (area_rect.width - bounds.width * scale) / 2;
+        bounds.y = bounds.y - (area_rect.height - bounds.height * scale) / 2;
+        bounds.width = area_rect.width / scale;
+        bounds.height = area_rect.height / scale;
 
         // Move all windows back onto the screen and set their scale
         for (let i = 0; i < rects.length; i++) {
@@ -318,8 +283,8 @@ function enable() {
 
         let slots = [];
         for (let i = 0; i < rects.length; i++) {
-            rects[i].x = rects[i].x * scale + area.x;
-            rects[i].y = rects[i].y * scale + area.y;
+            rects[i].x = rects[i].x * scale + area_rect.x;
+            rects[i].y = rects[i].y * scale + area_rect.y;
 
             slots.push([rects[i].x, rects[i].y, scale, clones[i]]);
         }
@@ -328,20 +293,118 @@ function enable() {
     }
     workspaceInjections['_calculateWindowTransformationsNatural'] = undefined;
 
-    /// map gnome shell's computeAllWindowSlots() to our window placement function
-    workspaceInjections['_computeAllWindowSlots'] = Workspace.Workspace.prototype._computeAllWindowSlots;
-    Workspace.Workspace.prototype._computeAllWindowSlots = function(windows) {
-        return this._calculateWindowTransformationsNatural(windows);
-    }
+    /**
+     * _updateWindowPositions:
+     * @flags:
+     *  INITIAL - this is the initial positioning of the windows.
+     *  ANIMATE - Indicates that we need animate changing position.
+     */
+    workspaceInjections['_updateWindowPositions'] = Workspace.Workspace.prototype._updateWindowPositions;
+    Workspace.Workspace.prototype._updateWindowPositions = function(flags) {
+            if (this._currentLayout == null) {
+                this._recalculateWindowPositions(flags);
+                return;
+            }
+
+            let initialPositioning = flags & WindowPositionFlags.INITIAL;
+            let animate = flags & WindowPositionFlags.ANIMATE;
+
+            let layout = this._currentLayout;
+            let strategy = layout.strategy;
+
+            let [, , padding] = this._getSpacingAndPadding();
+            let area = Workspace.padArea(this._actualGeometry, padding);
+
+            /// EDIT replace this version by our own:
+            //let slots = strategy.computeWindowSlots(layout, area);
+
+
+            /// EDIT copied from _realRecalculateWindowPositions:
+            let clones = this._windows.slice();
+            if (clones.length == 0)
+                return;
+
+            clones.sort(function(a, b) {
+                return a.metaWindow.get_stable_sequence() - b.metaWindow.get_stable_sequence();
+            });
+
+            if (this._reservedSlot)
+                clones.push(this._reservedSlot);
+
+            /// EDIT our own window placement function:
+            let slots = this._calculateWindowTransformationsNatural(clones, area);
+
+
+            let currentWorkspace = global.screen.get_active_workspace();
+            let isOnCurrentWorkspace = this.metaWorkspace == null || this.metaWorkspace == currentWorkspace;
+
+            for (let i = 0; i < slots.length; i++) {
+                let slot = slots[i];
+                let [x, y, scale, clone] = slot;
+                let metaWindow = clone.metaWindow;
+                let overlay = clone.overlay;
+                clone.slotId = i;
+
+                // Positioning a window currently being dragged must be avoided;
+                // we'll just leave a blank spot in the layout for it.
+                if (clone.inDrag)
+                    continue;
+
+                let cloneWidth = clone.actor.width * scale;
+                let cloneHeight = clone.actor.height * scale;
+                clone.slot = [x, y, cloneWidth, cloneHeight];
+
+                if (overlay && (initialPositioning || !clone.positioned))
+                    overlay.hide();
+
+                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.positioned = true;
+                }
+
+                if (animate && isOnCurrentWorkspace) {
+                    if (!metaWindow.showing_on_its_workspace()) {
+                        /* Hidden windows should fade in and grow
+                         * 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;
+                        }
+
+                        Tweener.addTween(clone.actor,
+                                         { opacity: 255,
+                                           time: Overview.ANIMATION_TIME,
+                                           transition: 'easeInQuad'
+                                         });
+                    }
+
+                    this._animateClone(clone, overlay, x, y, scale, initialPositioning);
+                } 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.overlay.relayout(false);
+                    this._showWindowOverlay(clone, overlay, isOnCurrentWorkspace);
+                }
+            }
+        }
+
+
 
     /// position window titles on top of windows in overlay ////
     if (windowCaptionsOnTop) {
-        winInjections['chromeHeights'] = Workspace.WindowOverlay.prototype.chromeHeights;
-        Workspace.WindowOverlay.prototype.chromeHeights = function () {
-            return [Math.max( this.closeButton.height - this.closeButton._overlap, this.title.height - 
this.title._overlap),
-                    0];
-        };
 
+        /// This is almost a direct copy of the original relayout function. Differences are marked.
         winInjections['relayout'] = Workspace.WindowOverlay.prototype.relayout;
         Workspace.WindowOverlay.prototype.relayout = function(animate) {
             let button = this.closeButton;


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