[gnome-shell/issue-23: 43/43] altTab: Add also a shortcut to close windows from the switcher popups



commit 166dbe6e87ab1fd889546646e59010d28a9804bf
Author: Mario Sanchez Prada <mario endlessm com>
Date:   Tue Dec 5 10:02:23 2017 +0000

    altTab: Add also a shortcut to close windows from the switcher popups
    
    Similar to what has been done for the apps switcher, this allows closing
    windows pressing W or F4 while operating the windows switcher popup or
    the apps switcher popup while navigating the list of windows for an app.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=620106

 js/ui/altTab.js | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 59 insertions(+)
---
diff --git a/js/ui/altTab.js b/js/ui/altTab.js
index 407a56e4c..6c2693ff9 100644
--- a/js/ui/altTab.js
+++ b/js/ui/altTab.js
@@ -156,6 +156,18 @@ var AppSwitcherPopup = new Lang.Class({
                                  this._items[this._selectedIndex].cachedWindows.length);
     },
 
+    _closeAppWindow: function(appIndex, windowIndex) {
+        let appIcon = this._items[appIndex];
+        if (!appIcon)
+            return;
+
+        let window = appIcon.cachedWindows[windowIndex];
+        if (!window)
+            return;
+
+        window.delete(global.get_current_time());
+    },
+
     _quitApplication: function(appIndex) {
         let appIcon = this._items[appIndex];
         if (!appIcon)
@@ -185,6 +197,8 @@ var AppSwitcherPopup = new Lang.Class({
                 this._select(this._selectedIndex, this._nextWindow());
             else if (keysym == Clutter.Up)
                 this._select(this._selectedIndex, null, true);
+            else if (keysym == Clutter.w || keysym == Clutter.F4)
+                this._closeAppWindow(this._selectedIndex, this._currentWindow);
             else
                 return Clutter.EVENT_PROPAGATE;
         } else {
@@ -258,6 +272,17 @@ var AppSwitcherPopup = new Lang.Class({
         this._select(this._selectedIndex, n);
     },
 
+    _windowRemoved : function(thumbnailList, n) {
+        let appIcon = this._items[this._selectedIndex];
+        if (!appIcon)
+            return;
+
+        if (appIcon.cachedWindows.length > 0) {
+            let newIndex = Math.min(n, appIcon.cachedWindows.length - 1);
+            this._select(this._selectedIndex, newIndex);
+        }
+    },
+
     _finish : function(timestamp) {
         let appIcon = this._items[this._selectedIndex];
         if (this._currentWindow < 0)
@@ -361,6 +386,7 @@ var AppSwitcherPopup = new Lang.Class({
         this._thumbnails = new ThumbnailList (this._items[this._selectedIndex].cachedWindows);
         this._thumbnails.connect('item-activated', Lang.bind(this, this._windowActivated));
         this._thumbnails.connect('item-entered', Lang.bind(this, this._windowEntered));
+        this._thumbnails.connect('item-removed', Lang.bind(this, this._windowRemoved));
         this._thumbnails.actor.connect('destroy', () => {
             this._thumbnails = null;
             this._thumbnailsFocused = false;
@@ -550,6 +576,14 @@ var WindowSwitcherPopup = new Lang.Class({
         return getWindows(workspace);
     },
 
+    _closeWindow: function(windowIndex) {
+        let windowIcon = this._items[windowIndex];
+        if (!windowIcon)
+            return;
+
+        windowIcon.window.delete(global.get_current_time());
+    },
+
     _keyPressHandler: function(keysym, action) {
         if (action == Meta.KeyBindingAction.SWITCH_WINDOWS) {
             this._select(this._next());
@@ -560,6 +594,8 @@ var WindowSwitcherPopup = new Lang.Class({
                 this._select(this._previous());
             else if (keysym == Clutter.Right)
                 this._select(this._next());
+            else if (keysym == Clutter.w || keysym == Clutter.F4)
+                this._closeWindow(this._selectedIndex);
             else
                 return Clutter.EVENT_PROPAGATE;
         }
@@ -988,7 +1024,19 @@ var WindowList = new Lang.Class({
 
             this.addItem(icon.actor, icon.label);
             this.icons.push(icon);
+
+            icon._unmanagedSignalId = icon.window.connect('unmanaged', (window) => {
+                this._removeWindow(window)
+            });
         }
+
+        this.actor.connect('destroy', () => { this._onDestroy(); });
+    },
+
+    _onDestroy: function() {
+        this.icons.forEach(icon => {
+            icon.window.disconnect(icon._unmanagedSignalId);
+        });
     },
 
     _getPreferredHeight: function(actor, forWidth, alloc) {
@@ -1017,5 +1065,16 @@ var WindowList = new Lang.Class({
         this.parent(index, justOutline);
 
         this._label.set_text(index == -1 ? '' : this.icons[index].label.text);
+    },
+
+    _removeWindow: function(window) {
+        let index = this.icons.findIndex(icon => {
+            return icon.window == window;
+        });
+        if (index === -1)
+            return;
+
+        this.icons.splice(index, 1);
+        this.removeItem(index);
     }
 });


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