Blame SOURCES/horizontal-workspace-support.patch

35159f
From b42dd3f87ad5fb6c7ee139cb0de22e0fbb393ba2 Mon Sep 17 00:00:00 2001
35159f
From: =?UTF-8?q?Florian=20M=C3=BCllner?= <fmuellner@gnome.org>
35159f
Date: Tue, 4 Jun 2019 19:22:26 +0000
35159f
Subject: [PATCH 1/2] workspaceSwitcherPopup: Support horizontal layout
35159f
35159f
While mutter supports a variety of different grid layouts (n columns/rows,
35159f
growing vertically or horizontally from any of the four corners), we
35159f
hardcode a fixed vertical layout of a single column.
35159f
35159f
Now that mutter exposes the actual layout to us, add support for a more
35159f
traditional horizontal layout as well.
35159f
35159f
https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/575
35159f
---
35159f
 data/theme/gnome-shell-sass/_common.scss |  3 +-
35159f
 js/ui/windowManager.js                   | 36 ++++++++--
35159f
 js/ui/workspaceSwitcherPopup.js          | 86 ++++++++++++++++++------
35159f
 3 files changed, 98 insertions(+), 27 deletions(-)
35159f
35159f
diff --git a/data/theme/gnome-shell-sass/_common.scss b/data/theme/gnome-shell-sass/_common.scss
35159f
index 293ea2ab9..b1eeb0ce9 100644
35159f
--- a/data/theme/gnome-shell-sass/_common.scss
35159f
+++ b/data/theme/gnome-shell-sass/_common.scss
35159f
@@ -680,7 +680,8 @@ StScrollBar {
35159f
     spacing: 8px;
35159f
   }
35159f
 
35159f
-  .ws-switcher-active-up, .ws-switcher-active-down {
35159f
+  .ws-switcher-active-up, .ws-switcher-active-down,
35159f
+  .ws-switcher-active-left, .ws-switcher-active-right {
35159f
     height: 50px;
35159f
     background-color: $selected_bg_color;
35159f
     color: $selected_fg_color;
35159f
diff --git a/js/ui/windowManager.js b/js/ui/windowManager.js
35159f
index b9f5fef46..dfe1b4460 100644
35159f
--- a/js/ui/windowManager.js
35159f
+++ b/js/ui/windowManager.js
35159f
@@ -2145,6 +2145,8 @@ var WindowManager = class {
35159f
         let [action,,,target] = binding.get_name().split('-');
35159f
         let newWs;
35159f
         let direction;
35159f
+        let vertical = workspaceManager.layout_rows == -1;
35159f
+        let rtl = Clutter.get_default_text_direction() == Clutter.TextDirection.RTL;
35159f
 
35159f
         if (action == 'move') {
35159f
             // "Moving" a window to another workspace doesn't make sense when
35159f
@@ -2157,7 +2159,12 @@ var WindowManager = class {
35159f
         }
35159f
 
35159f
         if (target == 'last') {
35159f
-            direction = Meta.MotionDirection.DOWN;
35159f
+            if (vertical)
35159f
+                direction = Meta.MotionDirection.DOWN;
35159f
+            else if (rtl)
35159f
+                direction = Meta.MotionDirection.LEFT;
35159f
+            else
35159f
+                direction = Meta.MotionDirection.RIGHT;
35159f
             newWs = workspaceManager.get_workspace_by_index(workspaceManager.n_workspaces - 1);
35159f
         } else if (isNaN(target)) {
35159f
             // Prepend a new workspace dynamically
35159f
@@ -2173,16 +2180,33 @@ var WindowManager = class {
35159f
             target--;
35159f
             newWs = workspaceManager.get_workspace_by_index(target);
35159f
 
35159f
-            if (workspaceManager.get_active_workspace().index() > target)
35159f
-                direction = Meta.MotionDirection.UP;
35159f
-            else
35159f
-                direction = Meta.MotionDirection.DOWN;
35159f
+            if (workspaceManager.get_active_workspace().index() > target) {
35159f
+                if (vertical)
35159f
+                    direction = Meta.MotionDirection.UP;
35159f
+                else if (rtl)
35159f
+                    direction = Meta.MotionDirection.RIGHT;
35159f
+                else
35159f
+                    direction = Meta.MotionDirection.LEFT;
35159f
+            } else {
35159f
+                if (vertical)
35159f
+                    direction = Meta.MotionDirection.DOWN;
35159f
+                else if (rtl)
35159f
+                    direction = Meta.MotionDirection.LEFT;
35159f
+                else
35159f
+                    direction = Meta.MotionDirection.RIGHT;
35159f
+            }
35159f
         }
35159f
 
35159f
-        if (direction != Meta.MotionDirection.UP &&
35159f
+        if (workspaceManager.layout_rows == -1 &&
35159f
+            direction != Meta.MotionDirection.UP &&
35159f
             direction != Meta.MotionDirection.DOWN)
35159f
             return;
35159f
 
35159f
+        if (workspaceManager.layout_columns == -1 &&
35159f
+            direction != Meta.MotionDirection.LEFT &&
35159f
+            direction != Meta.MotionDirection.RIGHT)
35159f
+            return;
35159f
+
35159f
         if (action == 'switch')
35159f
             this.actionMoveWorkspace(newWs);
35159f
         else
35159f
diff --git a/js/ui/workspaceSwitcherPopup.js b/js/ui/workspaceSwitcherPopup.js
35159f
index 26404eaab..d21c5de4d 100644
35159f
--- a/js/ui/workspaceSwitcherPopup.js
35159f
+++ b/js/ui/workspaceSwitcherPopup.js
35159f
@@ -17,41 +17,75 @@ class WorkspaceSwitcherPopupList extends St.Widget {
35159f
         this._itemSpacing = 0;
35159f
         this._childHeight = 0;
35159f
         this._childWidth = 0;
35159f
+        this._orientation = global.workspace_manager.layout_rows == -1
35159f
+            ? Clutter.Orientation.VERTICAL
35159f
+            : Clutter.Orientation.HORIZONTAL;
35159f
 
35159f
         this.connect('style-changed', () => {
35159f
            this._itemSpacing = this.get_theme_node().get_length('spacing');
35159f
         });
35159f
     }
35159f
 
35159f
-    vfunc_get_preferred_height(forWidth) {
35159f
+    _getPreferredSizeForOrientation(forSize) {
35159f
         let workArea = Main.layoutManager.getWorkAreaForMonitor(Main.layoutManager.primaryIndex);
35159f
         let themeNode = this.get_theme_node();
35159f
 
35159f
-        let availHeight = workArea.height;
35159f
-        availHeight -= themeNode.get_vertical_padding();
35159f
+        let availSize;
35159f
+        if (this._orientation == Clutter.Orientation.HORIZONTAL)
35159f
+            availSize = workArea.width - themeNode.get_horizontal_padding();
35159f
+        else
35159f
+            availSize = workArea.height - themeNode.get_vertical_padding();
35159f
 
35159f
-        let height = 0;
35159f
+        let size = 0;
35159f
         for (let child of this.get_children()) {
35159f
             let [childMinHeight, childNaturalHeight] = child.get_preferred_height(-1);
35159f
-            let [childMinWidth, childNaturalWidth] = child.get_preferred_width(childNaturalHeight);
35159f
-            height += childNaturalHeight * workArea.width / workArea.height;
35159f
+            let height = childNaturalHeight * workArea.width / workArea.height;
35159f
+
35159f
+            if (this._orientation == Clutter.Orientation.HORIZONTAL) {
35159f
+                size += height * workArea.width / workArea.height;
35159f
+            } else {
35159f
+                size += height;
35159f
+            }
35159f
         }
35159f
 
35159f
         let workspaceManager = global.workspace_manager;
35159f
         let spacing = this._itemSpacing * (workspaceManager.n_workspaces - 1);
35159f
-        height += spacing;
35159f
-        height = Math.min(height, availHeight);
35159f
+        size += spacing;
35159f
+        size = Math.min(size, availSize);
35159f
+
35159f
+        if (this._orientation == Clutter.Orientation.HORIZONTAL) {
35159f
+            this._childWidth = (size - spacing) / workspaceManager.n_workspaces;
35159f
+            return themeNode.adjust_preferred_width(size, size);
35159f
+        } else {
35159f
+            this._childHeight = (size - spacing) / workspaceManager.n_workspaces;
35159f
+            return themeNode.adjust_preferred_height(size, size);
35159f
+        }
35159f
+    }
35159f
+
35159f
+    _getSizeForOppositeOrientation() {
35159f
+        let workArea = Main.layoutManager.getWorkAreaForMonitor(Main.layoutManager.primaryIndex);
35159f
 
35159f
-        this._childHeight = (height - spacing) / workspaceManager.n_workspaces;
35159f
+        if (this._orientation == Clutter.Orientation.HORIZONTAL) {
35159f
+            this._childHeight = Math.round(this._childWidth * workArea.height / workArea.width);
35159f
+            return [this._childHeight, this._childHeight];
35159f
+        } else {
35159f
+            this._childWidth = Math.round(this._childHeight * workArea.width / workArea.height);
35159f
+            return [this._childWidth, this._childWidth];
35159f
+        }
35159f
+    }
35159f
 
35159f
-        return themeNode.adjust_preferred_height(height, height);
35159f
+    vfunc_get_preferred_height(forWidth) {
35159f
+        if (this._orientation == Clutter.Orientation.HORIZONTAL)
35159f
+            return this._getSizeForOppositeOrientation();
35159f
+        else
35159f
+            return this._getPreferredSizeForOrientation(forWidth);
35159f
     }
35159f
 
35159f
     vfunc_get_preferred_width(forHeight) {
35159f
-        let workArea = Main.layoutManager.getWorkAreaForMonitor(Main.layoutManager.primaryIndex);
35159f
-        this._childWidth = Math.round(this._childHeight * workArea.width / workArea.height);
35159f
-
35159f
-        return [this._childWidth, this._childWidth];
35159f
+        if (this._orientation == Clutter.Orientation.HORIZONTAL)
35159f
+            return this._getPreferredSizeForOrientation(forHeight);
35159f
+        else
35159f
+            return this._getSizeForOppositeOrientation();
35159f
     }
35159f
 
35159f
     vfunc_allocate(box, flags) {
35159f
@@ -62,15 +96,23 @@ class WorkspaceSwitcherPopupList extends St.Widget {
35159f
 
35159f
         let childBox = new Clutter.ActorBox();
35159f
 
35159f
+        let rtl = this.text_direction == Clutter.TextDirection.RTL;
35159f
+        let x = rtl ? box.x2 - this._childWidth : box.x1;
35159f
         let y = box.y1;
35159f
-        let prevChildBoxY2 = box.y1 - this._itemSpacing;
35159f
         for (let child of this.get_children()) {
35159f
-            childBox.x1 = box.x1;
35159f
-            childBox.x2 = box.x1 + this._childWidth;
35159f
-            childBox.y1 = prevChildBoxY2 + this._itemSpacing;
35159f
+            childBox.x1 = Math.round(x);
35159f
+            childBox.x2 = Math.round(x + this._childWidth);
35159f
+            childBox.y1 = Math.round(y);
35159f
             childBox.y2 = Math.round(y + this._childHeight);
35159f
-            y += this._childHeight + this._itemSpacing;
35159f
-            prevChildBoxY2 = childBox.y2;
35159f
+
35159f
+            if (this._orientation == Clutter.Orientation.HORIZONTAL) {
35159f
+                if (rtl)
35159f
+                    x -= this._childWidth + this._itemSpacing;
35159f
+                else
35159f
+                    x += this._childWidth + this._itemSpacing;
35159f
+            } else {
35159f
+                y += this._childHeight + this._itemSpacing;
35159f
+            }
35159f
             child.allocate(childBox, flags);
35159f
         }
35159f
     }
35159f
@@ -123,6 +165,10 @@ class WorkspaceSwitcherPopup extends St.Widget {
35159f
                indicator = new St.Bin({ style_class: 'ws-switcher-active-up' });
35159f
            else if(i == this._activeWorkspaceIndex && this._direction == Meta.MotionDirection.DOWN)
35159f
                indicator = new St.Bin({ style_class: 'ws-switcher-active-down' });
35159f
+           else if(i == this._activeWorkspaceIndex && this._direction == Meta.MotionDirection.LEFT)
35159f
+               indicator = new St.Bin({ style_class: 'ws-switcher-active-left' });
35159f
+           else if(i == this._activeWorkspaceIndex && this._direction == Meta.MotionDirection.RIGHT)
35159f
+               indicator = new St.Bin({ style_class: 'ws-switcher-active-right' });
35159f
            else
35159f
                indicator = new St.Bin({ style_class: 'ws-switcher-box' });
35159f
 
35159f
-- 
35159f
2.21.0
35159f
35159f
35159f
From 813976ff69b15ab884d44f5f6a56ae66f407acfd Mon Sep 17 00:00:00 2001
35159f
From: =?UTF-8?q?Florian=20M=C3=BCllner?= <fmuellner@gnome.org>
35159f
Date: Tue, 4 Jun 2019 19:49:23 +0000
35159f
Subject: [PATCH 2/2] workspacesView: Support horizontal layout
35159f
35159f
Just as we did for the workspace switcher popup, support workspaces
35159f
being laid out in a single row in the window picker.
35159f
35159f
Note that this takes care of the various workspace switch actions in
35159f
the overview (scrolling, panning, touch(pad) gestures) as well as the
35159f
switch animation, but not of the overview's workspace switcher component.
35159f
35159f
There are currently no plans to support other layouts there, as the
35159f
component is inherently vertical (in fact, it was the whole reason for
35159f
switching the layout in the first place).
35159f
35159f
https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/575
35159f
---
35159f
 js/ui/workspacesView.js | 81 ++++++++++++++++++++++++++++++-----------
35159f
 1 file changed, 60 insertions(+), 21 deletions(-)
35159f
35159f
diff --git a/js/ui/workspacesView.js b/js/ui/workspacesView.js
35159f
index fe06d9dae..069937d5a 100644
35159f
--- a/js/ui/workspacesView.js
35159f
+++ b/js/ui/workspacesView.js
35159f
@@ -181,26 +181,32 @@ var WorkspacesView = class extends WorkspacesViewBase {
35159f
 
35159f
             Tweener.removeTweens(workspace.actor);
35159f
 
35159f
-            let y = (w - active) * this._fullGeometry.height;
35159f
+            let params = {};
35159f
+            if (workspaceManager.layout_rows == -1)
35159f
+                params.y = (w - active) * this._fullGeometry.height;
35159f
+            else if (this.actor.text_direction == Clutter.TextDirection.RTL)
35159f
+                params.x = (active - w) * this._fullGeometry.width;
35159f
+            else
35159f
+                params.x = (w - active) * this._fullGeometry.width;
35159f
 
35159f
             if (showAnimation) {
35159f
-                let params = { y: y,
35159f
-                               time: WORKSPACE_SWITCH_TIME,
35159f
-                               transition: 'easeOutQuad'
35159f
-                             };
35159f
+                let tweenParams = Object.assign(params, {
35159f
+                    time: WORKSPACE_SWITCH_TIME,
35159f
+                    transition: 'easeOutQuad'
35159f
+                });
35159f
                 // we have to call _updateVisibility() once before the
35159f
                 // animation and once afterwards - it does not really
35159f
                 // matter which tween we use, so we pick the first one ...
35159f
                 if (w == 0) {
35159f
                     this._updateVisibility();
35159f
-                    params.onComplete = () => {
35159f
+                    tweenParams.onComplete = () => {
35159f
                         this._animating = false;
35159f
                         this._updateVisibility();
35159f
                     };
35159f
                 }
35159f
-                Tweener.addTween(workspace.actor, params);
35159f
+                Tweener.addTween(workspace.actor, tweenParams);
35159f
             } else {
35159f
-                workspace.actor.set_position(0, y);
35159f
+                workspace.actor.set(params);
35159f
                 if (w == 0)
35159f
                     this._updateVisibility();
35159f
             }
35159f
@@ -338,22 +344,39 @@ var WorkspacesView = class extends WorkspacesViewBase {
35159f
             metaWorkspace.activate(global.get_current_time());
35159f
         }
35159f
 
35159f
-        let last = this._workspaces.length - 1;
35159f
-        let firstWorkspaceY = this._workspaces[0].actor.y;
35159f
-        let lastWorkspaceY = this._workspaces[last].actor.y;
35159f
-        let workspacesHeight = lastWorkspaceY - firstWorkspaceY;
35159f
-
35159f
         if (adj.upper == 1)
35159f
             return;
35159f
 
35159f
-        let currentY = firstWorkspaceY;
35159f
-        let newY =  - adj.value / (adj.upper - 1) * workspacesHeight;
35159f
+        let last = this._workspaces.length - 1;
35159f
+
35159f
+        if (workspaceManager.layout_rows == -1) {
35159f
+            let firstWorkspaceY = this._workspaces[0].actor.y;
35159f
+            let lastWorkspaceY = this._workspaces[last].actor.y;
35159f
+            let workspacesHeight = lastWorkspaceY - firstWorkspaceY;
35159f
+
35159f
+            let currentY = firstWorkspaceY;
35159f
+            let newY = -adj.value / (adj.upper - 1) * workspacesHeight;
35159f
 
35159f
-        let dy = newY - currentY;
35159f
+            let dy = newY - currentY;
35159f
+
35159f
+            for (let i = 0; i < this._workspaces.length; i++) {
35159f
+                this._workspaces[i].actor.visible = Math.abs(i - adj.value) <= 1;
35159f
+                this._workspaces[i].actor.y += dy;
35159f
+            }
35159f
+        } else {
35159f
+            let firstWorkspaceX = this._workspaces[0].actor.x;
35159f
+            let lastWorkspaceX = this._workspaces[last].actor.x;
35159f
+            let workspacesWidth = lastWorkspaceX - firstWorkspaceX;
35159f
 
35159f
-        for (let i = 0; i < this._workspaces.length; i++) {
35159f
-            this._workspaces[i].actor.visible = Math.abs(i - adj.value) <= 1;
35159f
-            this._workspaces[i].actor.y += dy;
35159f
+            let currentX = firstWorkspaceX;
35159f
+            let newX = -adj.value / (adj.upper - 1) * workspacesWidth;
35159f
+
35159f
+            let dx = newX - currentX;
35159f
+
35159f
+            for (let i = 0; i < this._workspaces.length; i++) {
35159f
+                this._workspaces[i].actor.visible = Math.abs(i - adj.value) <= 1;
35159f
+                this._workspaces[i].actor.x += dx;
35159f
+            }
35159f
         }
35159f
     }
35159f
 };
35159f
@@ -504,7 +527,12 @@ var WorkspacesDisplay = class {
35159f
     _onPan(action) {
35159f
         let [dist, dx, dy] = action.get_motion_delta(0);
35159f
         let adjustment = this._scrollAdjustment;
35159f
-        adjustment.value -= (dy / this.actor.height) * adjustment.page_size;
35159f
+        if (global.workspace_manager.layout_rows == -1)
35159f
+            adjustment.value -= (dy / this.actor.height) * adjustment.page_size;
35159f
+        else if (this.actor.text_direction == Clutter.TextDirection.RTL)
35159f
+            adjustment.value += (dx / this.actor.width) * adjustment.page_size;
35159f
+        else
35159f
+            adjustment.value -= (dx / this.actor.width) * adjustment.page_size;
35159f
         return false;
35159f
     }
35159f
 
35159f
@@ -536,7 +564,12 @@ var WorkspacesDisplay = class {
35159f
         let workspaceManager = global.workspace_manager;
35159f
         let active = workspaceManager.get_active_workspace_index();
35159f
         let adjustment = this._scrollAdjustment;
35159f
-        adjustment.value = (active - yRel / this.actor.height) * adjustment.page_size;
35159f
+        if (workspaceManager.layout_rows == -1)
35159f
+            adjustment.value = (active - yRel / this.actor.height) * adjustment.page_size;
35159f
+        else if (this.actor.text_direction == Clutter.TextDirection.RTL)
35159f
+            adjustment.value = (active + xRel / this.actor.width) * adjustment.page_size;
35159f
+        else
35159f
+            adjustment.value = (active - xRel / this.actor.width) * adjustment.page_size;
35159f
     }
35159f
 
35159f
     _onSwitchWorkspaceActivated(action, direction) {
35159f
@@ -755,6 +788,12 @@ var WorkspacesDisplay = class {
35159f
         case Clutter.ScrollDirection.DOWN:
35159f
             ws = activeWs.get_neighbor(Meta.MotionDirection.DOWN);
35159f
             break;
35159f
+        case Clutter.ScrollDirection.LEFT:
35159f
+            ws = activeWs.get_neighbor(Meta.MotionDirection.LEFT);
35159f
+            break;
35159f
+        case Clutter.ScrollDirection.RIGHT:
35159f
+            ws = activeWs.get_neighbor(Meta.MotionDirection.RIGHT);
35159f
+            break;
35159f
         default:
35159f
             return Clutter.EVENT_PROPAGATE;
35159f
         }
35159f
-- 
35159f
2.21.0
35159f