Blame SOURCES/horizontal-workspace-support.patch

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