From 0de4af866fe95df711eed2caa6c9a108e392e0f0 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Florian=20M=C3=BCllner?= <fmuellner@gnome.org>
Date: Fri, 14 Feb 2014 18:35:07 +0100
Subject: [PATCH 1/3] window-list: Sync hover after closing menus
StButton takes the hover state into account to decide whether a
series of events should be considered a click. So when dismissing
a menu by clicking on a different window/app button, its menu
cannot be triggered before leaving and re-entering the button
(and thus syncing the hover state).
Fix this by always syncing the hover state after a grab is dropped.
https://bugzilla.gnome.org/show_bug.cgi?id=724688
---
extensions/window-list/extension.js | 15 +++++++++++++++
1 file changed, 15 insertions(+)
diff --git a/extensions/window-list/extension.js b/extensions/window-list/extension.js
index f282550..fc8e022 100644
--- a/extensions/window-list/extension.js
+++ b/extensions/window-list/extension.js
@@ -45,6 +45,16 @@ function _openMenu(menu) {
menu.actor.navigate_focus(null, Gtk.DirectionType.TAB_FORWARD, false);
}
+function _onMenuStateChanged(menu, isOpen) {
+ if (isOpen)
+ return;
+
+ let [x, y,] = global.get_pointer();
+ let actor = global.stage.get_actor_at_pos(Clutter.PickMode.REACTIVE, x, y);
+ if (windowList.actor.contains(actor))
+ actor.sync_hover();
+}
+
const WindowContextMenu = new Lang.Class({
Name: 'WindowContextMenu',
@@ -185,6 +195,7 @@ const WindowButton = new Lang.Class({
this._menuManager = new PopupMenu.PopupMenuManager(this);
this._contextMenu = new WindowContextMenu(this.actor, this.metaWindow);
+ this._contextMenu.connect('open-state-changed', _onMenuStateChanged);
this._contextMenu.actor.hide();
this._menuManager.addMenu(this._contextMenu);
Main.uiGroup.add_actor(this._contextMenu.actor);
@@ -361,6 +372,7 @@ const AppButton = new Lang.Class({
this._menuManager = new PopupMenu.PopupMenuManager(this);
this._menu = new PopupMenu.PopupMenu(this.actor, 0.5, St.Side.BOTTOM);
+ this._menu.connect('open-state-changed', _onMenuStateChanged);
this._menu.actor.hide();
this._menu.connect('activate', Lang.bind(this, this._onMenuActivate));
this._menuManager.addMenu(this._menu);
@@ -368,6 +380,7 @@ const AppButton = new Lang.Class({
this._contextMenuManager = new PopupMenu.PopupMenuManager(this);
this._appContextMenu = new AppContextMenu(this.actor, this.app);
+ this._appContextMenu.connect('open-state-changed', _onMenuStateChanged);
this._appContextMenu.actor.hide();
this._contextMenuManager.addMenu(this._appContextMenu);
Main.uiGroup.add_actor(this._appContextMenu.actor);
@@ -442,6 +455,8 @@ const AppButton = new Lang.Class({
this._windowTitle = new WindowTitle(this.metaWindow);
this._singleWindowTitle.child = this._windowTitle.actor;
this._windowContextMenu = new WindowContextMenu(this.actor, this.metaWindow);
+ this._windowContextMenu.connect('open-state-changed',
+ _onMenuStateChanged);
Main.uiGroup.add_actor(this._windowContextMenu.actor);
this._windowContextMenu.actor.hide();
this._contextMenuManager.addMenu(this._windowContextMenu);
--
1.8.5.3
From 9e991c4abb1cbc8dfea4e30f6d8d50dfb31fbca5 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Florian=20M=C3=BCllner?= <fmuellner@gnome.org>
Date: Sat, 15 Feb 2014 00:17:39 +0100
Subject: [PATCH 2/3] window-list: Only have a single context menu at any time
Depending on the number of windows, AppButtons use different right-click
menus ("Minimize" vs. "Minimize all").
As the menu for the multiple-windows case remains the same, it is created
and added just once. However this means that in the single-window case,
the corresponding PopupMenuManager will track two menus for the same
source actor, resulting in various misbehaviors.
Fix these issues by adding and removing the app context menu appropriately,
so that the PopupMenuManager tracks a single menu at any time.
https://bugzilla.gnome.org/show_bug.cgi?id=724688
---
extensions/window-list/extension.js | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/extensions/window-list/extension.js b/extensions/window-list/extension.js
index fc8e022..7547a51 100644
--- a/extensions/window-list/extension.js
+++ b/extensions/window-list/extension.js
@@ -382,7 +382,6 @@ const AppButton = new Lang.Class({
this._appContextMenu = new AppContextMenu(this.actor, this.app);
this._appContextMenu.connect('open-state-changed', _onMenuStateChanged);
this._appContextMenu.actor.hide();
- this._contextMenuManager.addMenu(this._appContextMenu);
Main.uiGroup.add_actor(this._appContextMenu.actor);
this._textureCache = St.TextureCache.get_default();
@@ -461,6 +460,7 @@ const AppButton = new Lang.Class({
this._windowContextMenu.actor.hide();
this._contextMenuManager.addMenu(this._windowContextMenu);
}
+ this._contextMenuManager.removeMenu(this._appContextMenu);
this._contextMenu = this._windowContextMenu;
} else {
if (this._windowTitle) {
@@ -471,6 +471,7 @@ const AppButton = new Lang.Class({
this._windowContextMenu = null;
}
this._contextMenu = this._appContextMenu;
+ this._contextMenuManager.addMenu(this._appContextMenu);
}
},
--
1.8.5.3
From c8fe5fa5a6c6613a9e56ceda6c1b78e5d69ba6e4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Florian=20M=C3=BCllner?= <fmuellner@gnome.org>
Date: Sat, 15 Feb 2014 00:19:56 +0100
Subject: [PATCH 3/3] window-list: Call destroy() on menus instead of their
actors
PopupBaseMenu provides a destroy() method that will destroy the menu
actor and make sure that the menu will be removed from the corresponding
PopupMenuManager (if any). We miss the latter when we destroy the menu
actor directly, so use the menu method instead.
https://bugzilla.gnome.org/show_bug.cgi?id=724688
---
extensions/window-list/extension.js | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/extensions/window-list/extension.js b/extensions/window-list/extension.js
index 7547a51..1a60989 100644
--- a/extensions/window-list/extension.js
+++ b/extensions/window-list/extension.js
@@ -264,7 +264,7 @@ const WindowButton = new Lang.Class({
_onDestroy: function() {
global.window_manager.disconnect(this._switchWorkspaceId);
global.display.disconnect(this._notifyFocusId);
- this._contextMenu.actor.destroy();
+ this._contextMenu.destroy();
}
});
@@ -467,7 +467,7 @@ const AppButton = new Lang.Class({
this.metaWindow = null;
this._singleWindowTitle.child = null;
this._windowTitle = null;
- this._windowContextMenu.actor.destroy();
+ this._windowContextMenu.destroy();
this._windowContextMenu = null;
}
this._contextMenu = this._appContextMenu;
@@ -529,7 +529,7 @@ const AppButton = new Lang.Class({
global.window_manager.disconnect(this._switchWorkspaceId);
this._windowTracker.disconnect(this._notifyFocusId);
this.app.disconnect(this._windowsChangedId);
- this._menu.actor.destroy();
+ this._menu.destroy();
}
});
--
1.8.5.3