[gnome-shell] altTab: Don't mess up MRU order while cycling windows



commit 3171819c363381724226e67e2222f3ac3f6f5e0e
Author: Florian Müllner <fmuellner gnome org>
Date:   Thu Sep 8 16:05:06 2016 +0200

    altTab: Don't mess up MRU order while cycling windows
    
    Commit bd6e7f14d17b reimplemented the cycle keybindings to
    fix cycling between more than two windows, but the approach
    of highlighting cycled windows by actually focusing them has
    the drawback that cycling messes up the MRU order of windows.
    To fix this, only change the window focus when the operation
    finishes, and use a dedicated actor that draws a border around
    a window clone for highlighting.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=771063

 data/theme/gnome-shell-high-contrast.css |    4 ++
 data/theme/gnome-shell-sass              |    2 +-
 data/theme/gnome-shell.css               |    4 ++
 js/ui/altTab.js                          |   75 +++++++++++++++++++++++++++++-
 4 files changed, 82 insertions(+), 3 deletions(-)
---
diff --git a/data/theme/gnome-shell-high-contrast.css b/data/theme/gnome-shell-high-contrast.css
index 9f7d65b..28922be 100644
--- a/data/theme/gnome-shell-high-contrast.css
+++ b/data/theme/gnome-shell-high-contrast.css
@@ -604,6 +604,10 @@ StScrollBar {
   width: 96px;
   height: 96px; }
 
+/* Window Cycler */
+.cycler-highlight {
+  border: 5px solid #215d9c; }
+
 /* Workspace Switcher */
 .workspace-switcher-group {
   padding: 12px; }
diff --git a/data/theme/gnome-shell-sass b/data/theme/gnome-shell-sass
index 7ab2789..b219008 160000
--- a/data/theme/gnome-shell-sass
+++ b/data/theme/gnome-shell-sass
@@ -1 +1 @@
-Subproject commit 7ab2789464b2e917b56aec9df6b78975db1a8eb6
+Subproject commit b2190083c256564258fce97645ae6da72e9d0f7f
diff --git a/data/theme/gnome-shell.css b/data/theme/gnome-shell.css
index 740ee9c..6907223 100644
--- a/data/theme/gnome-shell.css
+++ b/data/theme/gnome-shell.css
@@ -604,6 +604,10 @@ StScrollBar {
   width: 96px;
   height: 96px; }
 
+/* Window Cycler */
+.cycler-highlight {
+  border: 5px solid #215d9c; }
+
 /* Workspace Switcher */
 .workspace-switcher-group {
   padding: 12px; }
diff --git a/js/ui/altTab.js b/js/ui/altTab.js
index cf1174b..e65d46b 100644
--- a/js/ui/altTab.js
+++ b/js/ui/altTab.js
@@ -354,6 +354,67 @@ const AppSwitcherPopup = new Lang.Class({
     }
 });
 
+const CyclerHighlight = new Lang.Class({
+    Name: 'CyclerHighlight',
+
+    _init: function() {
+        this._window = null;
+
+        this.actor = new St.Widget({ layout_manager: new Clutter.BinLayout() });
+
+        this._clone = new Clutter.Clone();
+        this.actor.add_actor(this._clone);
+
+        this._highlight = new St.Widget({ style_class: 'cycler-highlight' });
+        this.actor.add_actor(this._highlight);
+
+        let coordinate = Clutter.BindCoordinate.ALL;
+        let constraint = new Clutter.BindConstraint({ coordinate: coordinate });
+        this._clone.bind_property('source', constraint, 'source', 0);
+
+        this.actor.add_constraint(constraint);
+
+        this.actor.connect('notify::allocation',
+                           Lang.bind(this, this._onAllocationChanged));
+        this.actor.connect('destroy', Lang.bind(this, this._onDestroy));
+    },
+
+    set window(w) {
+        if (this._window == w)
+            return;
+
+        this._window = w;
+
+        if (this._clone.source)
+            this._clone.source.show();
+
+        let windowActor = this._window ? this._window.get_compositor_private()
+                                       : null;
+
+        if (windowActor)
+            windowActor.hide();
+
+        this._clone.source = windowActor;
+    },
+
+    _onAllocationChanged: function() {
+        if (!this._window) {
+            this._highlight.set_size(0, 0);
+            this._highlight.hide();
+        } else {
+            let [x, y] = this.actor.allocation.get_origin();
+            let rect = this._window.get_frame_rect();
+            this._highlight.set_size(rect.width, rect.height);
+            this._highlight.set_position(rect.x - x, rect.y - y);
+            this._highlight.show();
+        }
+    },
+
+    _onDestroy: function() {
+        this.window = null;
+    }
+});
+
 const CyclerPopup = new Lang.Class({
     Name: 'CyclerPopup',
     Extends: SwitcherPopup.SwitcherPopup,
@@ -367,6 +428,9 @@ const CyclerPopup = new Lang.Class({
         if (this._items.length == 0)
             return;
 
+        this._highlight = new CyclerHighlight();
+        global.window_group.add_actor(this._highlight.actor);
+
         // We don't show an actual popup, so just provide what SwitcherPopup
         // expects instead of inheriting from SwitcherList
         this._switcherList = { actor: new St.Widget(),
@@ -375,11 +439,18 @@ const CyclerPopup = new Lang.Class({
     },
 
     _highlightItem: function(index, justOutline) {
-        Main.activateWindow(this._items[index]);
+        this._highlight.window = this._items[index];
+        global.window_group.set_child_above_sibling(this._highlight.actor, null);
     },
 
     _finish: function() {
-        this._highlightItem(this._selectedIndex);
+        Main.activateWindow(this._items[this._selectedIndex]);
+
+        this.parent();
+    },
+
+    _onDestroy: function() {
+        this._highlight.actor.destroy();
 
         this.parent();
     }


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