windowMenu: Do actions requiring grab once ungrabbed

Resizing or moving a window needs starting a keyboard grab. However, if the
action is triggered by a menu entry activation it might not work as we already
have already an active grab on input devices to manage the menu itself.

So, possibly wait maximum 100ms for the current grab operation to be completed
before trying go start a new one.

Needs https://gitlab.gnome.org/GNOME/mutter/merge_requests/596
Fixes https://gitlab.gnome.org/GNOME/gnome-shell/issues/1326

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/557
This commit is contained in:
Marco Trevisan (Treviño) 2019-05-27 16:16:38 -05:00
parent 759120b95f
commit 2b3ab3ecec

View File

@ -1,6 +1,6 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -* // -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*
const { Meta, St } = imports.gi; const { GLib, Meta, St } = imports.gi;
const BoxPointer = imports.ui.boxpointer; const BoxPointer = imports.ui.boxpointer;
const Main = imports.ui.main; const Main = imports.ui.main;
@ -42,13 +42,13 @@ var WindowMenu = class extends PopupMenu.PopupMenu {
item.setSensitive(false); item.setSensitive(false);
item = this.addAction(_("Move"), event => { item = this.addAction(_("Move"), event => {
window.begin_grab_op(Meta.GrabOp.KEYBOARD_MOVING, true, event.get_time()); this._grabAction(window, Meta.GrabOp.KEYBOARD_MOVING, event.get_time());
}); });
if (!window.allows_move()) if (!window.allows_move())
item.setSensitive(false); item.setSensitive(false);
item = this.addAction(_("Resize"), event => { item = this.addAction(_("Resize"), event => {
window.begin_grab_op(Meta.GrabOp.KEYBOARD_RESIZING_UNKNOWN, true, event.get_time()); this._grabAction(window, Meta.GrabOp.KEYBOARD_RESIZING_UNKNOWN, event.get_time());
}); });
if (!window.allows_resize()) if (!window.allows_resize())
item.setSensitive(false); item.setSensitive(false);
@ -169,6 +169,26 @@ var WindowMenu = class extends PopupMenu.PopupMenu {
if (!window.can_close()) if (!window.can_close())
item.setSensitive(false); item.setSensitive(false);
} }
_grabAction(window, grabOp, time) {
if (global.display.get_grab_op() == Meta.GrabOp.NONE) {
window.begin_grab_op(grabOp, true, time);
return;
}
let waitId = 0;
let id = global.display.connect('grab-op-end', (display) => {
display.disconnect(id);
GLib.source_remove(waitId);
window.begin_grab_op(grabOp, true, time);
});
waitId = GLib.timeout_add(GLib.PRIORITY_DEFAULT, 100, () => {
global.display.disconnect(id);
return GLib.SOURCE_REMOVE;
});
}
}; };
var WindowMenuManager = class { var WindowMenuManager = class {