js: Change main.pushModal to return the Clutter.Grab handle
All callers have been updated to keep this handle to identify their own grab. Also, optionally use the windowing state to determine whether the grab is suitable for the specific uses. This removes the need to trying to grab twice in the places where we settle for a keyboard grab. Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/2045>
This commit is contained in:
parent
2709f6c102
commit
7419674bd3
@ -1289,7 +1289,7 @@ var LoginDialog = GObject.registerClass({
|
|||||||
|
|
||||||
this.opacity = 0;
|
this.opacity = 0;
|
||||||
|
|
||||||
Main.pushModal(global.stage, { actionMode: Shell.ActionMode.LOGIN_SCREEN });
|
this._grab = Main.pushModal(global.stage, { actionMode: Shell.ActionMode.LOGIN_SCREEN });
|
||||||
|
|
||||||
this.ease({
|
this.ease({
|
||||||
opacity: 255,
|
opacity: 255,
|
||||||
@ -1301,7 +1301,8 @@ var LoginDialog = GObject.registerClass({
|
|||||||
}
|
}
|
||||||
|
|
||||||
close() {
|
close() {
|
||||||
Main.popModal(global.stage);
|
Main.popModal(this._grab);
|
||||||
|
this._grab = null;
|
||||||
Main.ctrlAltTabManager.removeGroup(this);
|
Main.ctrlAltTabManager.removeGroup(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
17
js/ui/dnd.js
17
js/ui/dnd.js
@ -117,7 +117,6 @@ var _Draggable = class _Draggable {
|
|||||||
this._animationInProgress = false; // The drag is over and the item is in the process of animating to its original position (snapping back or reverting).
|
this._animationInProgress = false; // The drag is over and the item is in the process of animating to its original position (snapping back or reverting).
|
||||||
this._dragCancellable = true;
|
this._dragCancellable = true;
|
||||||
|
|
||||||
this._eventsGrabbed = false;
|
|
||||||
this._capturedEventId = 0;
|
this._capturedEventId = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -208,18 +207,22 @@ var _Draggable = class _Draggable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_grabEvents(device, touchSequence) {
|
_grabEvents(device, touchSequence) {
|
||||||
if (!this._eventsGrabbed) {
|
if (!this._eventsGrab) {
|
||||||
this._eventsGrabbed = Main.pushModal(_getEventHandlerActor());
|
let grab = Main.pushModal(_getEventHandlerActor());
|
||||||
if (this._eventsGrabbed)
|
if ((grab.get_seat_state() & Clutter.GrabState.POINTER) !== 0) {
|
||||||
this._grabDevice(_getEventHandlerActor(), device, touchSequence);
|
this._grabDevice(_getEventHandlerActor(), device, touchSequence);
|
||||||
|
this._eventsGrab = grab;
|
||||||
|
} else {
|
||||||
|
Main.popModal(grab);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_ungrabEvents() {
|
_ungrabEvents() {
|
||||||
if (this._eventsGrabbed) {
|
if (this._eventsGrab) {
|
||||||
this._ungrabDevice();
|
this._ungrabDevice();
|
||||||
Main.popModal(_getEventHandlerActor());
|
Main.popModal(this._eventsGrab);
|
||||||
this._eventsGrabbed = false;
|
this._eventsGrab = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -181,9 +181,13 @@ var GrabHelper = class GrabHelper {
|
|||||||
_takeModalGrab() {
|
_takeModalGrab() {
|
||||||
let firstGrab = this._modalCount == 0;
|
let firstGrab = this._modalCount == 0;
|
||||||
if (firstGrab) {
|
if (firstGrab) {
|
||||||
if (!Main.pushModal(this._owner, this._modalParams))
|
let grab = Main.pushModal(this._owner, this._modalParams);
|
||||||
|
if (grab.get_seat_state() === Clutter.GrabState.NONE) {
|
||||||
|
Main.popModal(grab);
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
this._grab = grab;
|
||||||
this._capturedEventId = this._owner.connect('captured-event',
|
this._capturedEventId = this._owner.connect('captured-event',
|
||||||
(actor, event) => {
|
(actor, event) => {
|
||||||
return this.onCapturedEvent(event);
|
return this.onCapturedEvent(event);
|
||||||
@ -202,7 +206,8 @@ var GrabHelper = class GrabHelper {
|
|||||||
this._owner.disconnect(this._capturedEventId);
|
this._owner.disconnect(this._capturedEventId);
|
||||||
this._ignoreUntilRelease = false;
|
this._ignoreUntilRelease = false;
|
||||||
|
|
||||||
Main.popModal(this._owner);
|
Main.popModal(this._grab);
|
||||||
|
this._grab = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ignoreRelease:
|
// ignoreRelease:
|
||||||
|
@ -1560,9 +1560,13 @@ class LookingGlass extends St.BoxLayout {
|
|||||||
if (this._open)
|
if (this._open)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!Main.pushModal(this, { actionMode: Shell.ActionMode.LOOKING_GLASS }))
|
let grab = Main.pushModal(this, { actionMode: Shell.ActionMode.LOOKING_GLASS });
|
||||||
|
if (grab.get_seat_state() === Clutter.GrabState.NONE) {
|
||||||
|
Main.popModal(grab);
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this._grab = grab;
|
||||||
this._notebook.selectIndex(0);
|
this._notebook.selectIndex(0);
|
||||||
this.show();
|
this.show();
|
||||||
this._open = true;
|
this._open = true;
|
||||||
@ -1602,7 +1606,8 @@ class LookingGlass extends St.BoxLayout {
|
|||||||
duration,
|
duration,
|
||||||
mode: Clutter.AnimationMode.EASE_OUT_QUAD,
|
mode: Clutter.AnimationMode.EASE_OUT_QUAD,
|
||||||
onComplete: () => {
|
onComplete: () => {
|
||||||
Main.popModal(this);
|
Main.popModal(this._grab);
|
||||||
|
this._grab = null;
|
||||||
this.hide();
|
this.hide();
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
@ -503,9 +503,9 @@ function notifyError(msg, details) {
|
|||||||
notify(msg, details);
|
notify(msg, details);
|
||||||
}
|
}
|
||||||
|
|
||||||
function _findModal(actor) {
|
function _findModal(grab) {
|
||||||
for (let i = 0; i < modalActorFocusStack.length; i++) {
|
for (let i = 0; i < modalActorFocusStack.length; i++) {
|
||||||
if (modalActorFocusStack[i].actor == actor)
|
if (modalActorFocusStack[i].grab === grab)
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
@ -537,7 +537,7 @@ function _findModal(actor) {
|
|||||||
* global keybindings; the default of NONE will filter
|
* global keybindings; the default of NONE will filter
|
||||||
* out all keybindings
|
* out all keybindings
|
||||||
*
|
*
|
||||||
* @returns {bool}: true iff we successfully acquired a grab or already had one
|
* @returns {Clutter.Grab}: the grab handle created
|
||||||
*/
|
*/
|
||||||
function pushModal(actor, params) {
|
function pushModal(actor, params) {
|
||||||
params = Params.parse(params, { timestamp: global.get_current_time(),
|
params = Params.parse(params, { timestamp: global.get_current_time(),
|
||||||
@ -551,9 +551,9 @@ function pushModal(actor, params) {
|
|||||||
|
|
||||||
modalCount += 1;
|
modalCount += 1;
|
||||||
let actorDestroyId = actor.connect('destroy', () => {
|
let actorDestroyId = actor.connect('destroy', () => {
|
||||||
let index = _findModal(actor);
|
let index = _findModal(grab);
|
||||||
if (index >= 0)
|
if (index >= 0)
|
||||||
popModal(actor);
|
popModal(grab);
|
||||||
});
|
});
|
||||||
|
|
||||||
let prevFocus = global.stage.get_key_focus();
|
let prevFocus = global.stage.get_key_focus();
|
||||||
@ -577,14 +577,13 @@ function pushModal(actor, params) {
|
|||||||
|
|
||||||
actionMode = params.actionMode;
|
actionMode = params.actionMode;
|
||||||
global.stage.set_key_focus(actor);
|
global.stage.set_key_focus(actor);
|
||||||
return true;
|
return grab;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* popModal:
|
* popModal:
|
||||||
* @param {Clutter.Actor} actor: the actor passed to original invocation
|
* @param {Clutter.Grab} grab - the grab given by pushModal()
|
||||||
* of pushModal()
|
* @param {number=} timestamp - optional timestamp
|
||||||
* @param {number=} timestamp: optional timestamp
|
|
||||||
*
|
*
|
||||||
* Reverse the effect of pushModal(). If this invocation is undoing
|
* Reverse the effect of pushModal(). If this invocation is undoing
|
||||||
* the topmost invocation, then the focus will be restored to the
|
* the topmost invocation, then the focus will be restored to the
|
||||||
@ -594,11 +593,11 @@ function pushModal(actor, params) {
|
|||||||
* initiated event. If not provided then the value of
|
* initiated event. If not provided then the value of
|
||||||
* global.get_current_time() is assumed.
|
* global.get_current_time() is assumed.
|
||||||
*/
|
*/
|
||||||
function popModal(actor, timestamp) {
|
function popModal(grab, timestamp) {
|
||||||
if (timestamp == undefined)
|
if (timestamp == undefined)
|
||||||
timestamp = global.get_current_time();
|
timestamp = global.get_current_time();
|
||||||
|
|
||||||
let focusIndex = _findModal(actor);
|
let focusIndex = _findModal(grab);
|
||||||
if (focusIndex < 0) {
|
if (focusIndex < 0) {
|
||||||
global.stage.set_key_focus(null);
|
global.stage.set_key_focus(null);
|
||||||
actionMode = Shell.ActionMode.NORMAL;
|
actionMode = Shell.ActionMode.NORMAL;
|
||||||
@ -611,8 +610,7 @@ function popModal(actor, timestamp) {
|
|||||||
let record = modalActorFocusStack[focusIndex];
|
let record = modalActorFocusStack[focusIndex];
|
||||||
record.actor.disconnect(record.destroyId);
|
record.actor.disconnect(record.destroyId);
|
||||||
|
|
||||||
let grab = record.grab;
|
record.grab.dismiss();
|
||||||
grab.dismiss();
|
|
||||||
|
|
||||||
if (focusIndex == modalActorFocusStack.length - 1) {
|
if (focusIndex == modalActorFocusStack.length - 1) {
|
||||||
if (record.prevFocus)
|
if (record.prevFocus)
|
||||||
|
@ -204,7 +204,8 @@ var ModalDialog = GObject.registerClass({
|
|||||||
this._savedKeyFocus = focus;
|
this._savedKeyFocus = focus;
|
||||||
else
|
else
|
||||||
this._savedKeyFocus = null;
|
this._savedKeyFocus = null;
|
||||||
Main.popModal(this, timestamp);
|
Main.popModal(this._grab, timestamp);
|
||||||
|
this._grab = null;
|
||||||
this._hasModal = false;
|
this._hasModal = false;
|
||||||
|
|
||||||
if (!this._shellReactive)
|
if (!this._shellReactive)
|
||||||
@ -218,9 +219,13 @@ var ModalDialog = GObject.registerClass({
|
|||||||
let params = { actionMode: this._actionMode };
|
let params = { actionMode: this._actionMode };
|
||||||
if (timestamp)
|
if (timestamp)
|
||||||
params['timestamp'] = timestamp;
|
params['timestamp'] = timestamp;
|
||||||
if (!Main.pushModal(this, params))
|
let grab = Main.pushModal(this, params);
|
||||||
|
if (grab.get_seat_state() === Clutter.GrabState.NONE) {
|
||||||
|
Main.popModal(grab);
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
this._grab = grab;
|
||||||
Main.layoutManager.emit('system-modal-opened');
|
Main.layoutManager.emit('system-modal-opened');
|
||||||
|
|
||||||
this._hasModal = true;
|
this._hasModal = true;
|
||||||
|
@ -492,9 +492,12 @@ var Overview = class {
|
|||||||
let shouldBeModal = !this._inXdndDrag;
|
let shouldBeModal = !this._inXdndDrag;
|
||||||
if (shouldBeModal && !this._modal) {
|
if (shouldBeModal && !this._modal) {
|
||||||
let actionMode = Shell.ActionMode.OVERVIEW;
|
let actionMode = Shell.ActionMode.OVERVIEW;
|
||||||
if (Main.pushModal(global.stage, { actionMode })) {
|
let grab = Main.pushModal(global.stage, { actionMode });
|
||||||
|
if (grab.get_seat_state() !== Clutter.GrabState.NONE) {
|
||||||
|
this._grab = grab;
|
||||||
this._modal = true;
|
this._modal = true;
|
||||||
} else {
|
} else {
|
||||||
|
Main.popModal(grab);
|
||||||
this.hide();
|
this.hide();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -502,7 +505,8 @@ var Overview = class {
|
|||||||
} else {
|
} else {
|
||||||
// eslint-disable-next-line no-lonely-if
|
// eslint-disable-next-line no-lonely-if
|
||||||
if (this._modal) {
|
if (this._modal) {
|
||||||
Main.popModal(global.stage);
|
Main.popModal(this._grab);
|
||||||
|
this._grab = false;
|
||||||
this._modal = false;
|
this._modal = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -723,7 +723,7 @@ var PadOsd = GObject.registerClass({
|
|||||||
buttonBox.add_actor(this._editButton);
|
buttonBox.add_actor(this._editButton);
|
||||||
|
|
||||||
this._syncEditionMode();
|
this._syncEditionMode();
|
||||||
Main.pushModal(this);
|
this._grab = Main.pushModal(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
_updatePadChooser() {
|
_updatePadChooser() {
|
||||||
@ -919,7 +919,8 @@ var PadOsd = GObject.registerClass({
|
|||||||
}
|
}
|
||||||
|
|
||||||
_onDestroy() {
|
_onDestroy() {
|
||||||
Main.popModal(this);
|
Main.popModal(this._grab);
|
||||||
|
this._grab = null;
|
||||||
this._actionEditor.close();
|
this._actionEditor.close();
|
||||||
|
|
||||||
let seat = Clutter.get_default_backend().get_default_seat();
|
let seat = Clutter.get_default_backend().get_default_seat();
|
||||||
|
@ -1329,8 +1329,10 @@ var PopupMenuManager = class {
|
|||||||
}
|
}
|
||||||
|
|
||||||
removeMenu(menu) {
|
removeMenu(menu) {
|
||||||
if (menu == this.activeMenu)
|
if (menu === this.activeMenu) {
|
||||||
Main.popModal(menu.actor);
|
Main.popModal(this._grab);
|
||||||
|
this._grab = null;
|
||||||
|
}
|
||||||
|
|
||||||
let position = this._findMenu(menu);
|
let position = this._findMenu(menu);
|
||||||
if (position == -1) // not a menu we manage
|
if (position == -1) // not a menu we manage
|
||||||
@ -1353,12 +1355,13 @@ var PopupMenuManager = class {
|
|||||||
if (open) {
|
if (open) {
|
||||||
if (this.activeMenu)
|
if (this.activeMenu)
|
||||||
this.activeMenu.close(BoxPointer.PopupAnimation.FADE);
|
this.activeMenu.close(BoxPointer.PopupAnimation.FADE);
|
||||||
Main.pushModal(menu.actor, this._grabParams);
|
this._grab = Main.pushModal(menu.actor, this._grabParams);
|
||||||
this.activeMenu = menu;
|
this.activeMenu = menu;
|
||||||
} else {
|
} else {
|
||||||
if (this.activeMenu === menu)
|
if (this.activeMenu === menu)
|
||||||
this.activeMenu = null;
|
this.activeMenu = null;
|
||||||
Main.popModal(menu.actor);
|
Main.popModal(this._grab);
|
||||||
|
this._grab = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -192,14 +192,15 @@ var ScreenShield = class {
|
|||||||
if (this._isModal)
|
if (this._isModal)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
this._isModal = Main.pushModal(this.actor, { actionMode: Shell.ActionMode.LOCK_SCREEN });
|
let grab = Main.pushModal(this.actor, { actionMode: Shell.ActionMode.LOCK_SCREEN });
|
||||||
if (this._isModal)
|
|
||||||
return true;
|
// We expect at least a keyboard grab here
|
||||||
|
this._isModal = (grab.get_seat_state() & Clutter.GrabState.KEYBOARD) !== 0;
|
||||||
|
if (this._isModal)
|
||||||
|
this._grab = grab;
|
||||||
|
else
|
||||||
|
Main.popModal(grab);
|
||||||
|
|
||||||
// We failed to get a pointer grab, it means that
|
|
||||||
// something else has it. Try with a keyboard grab only
|
|
||||||
this._isModal = Main.pushModal(this.actor, { options: Meta.ModalOptions.POINTER_ALREADY_GRABBED,
|
|
||||||
actionMode: Shell.ActionMode.LOCK_SCREEN });
|
|
||||||
return this._isModal;
|
return this._isModal;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -550,7 +551,8 @@ var ScreenShield = class {
|
|||||||
this._dialog.popModal();
|
this._dialog.popModal();
|
||||||
|
|
||||||
if (this._isModal) {
|
if (this._isModal) {
|
||||||
Main.popModal(this.actor);
|
Main.popModal(this._grab);
|
||||||
|
this._grab = null;
|
||||||
this._isModal = false;
|
this._isModal = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||||
/* exported SwitcherPopup, SwitcherList */
|
/* exported SwitcherPopup, SwitcherList */
|
||||||
|
|
||||||
const { Clutter, GLib, GObject, Meta, St } = imports.gi;
|
const { Clutter, GLib, GObject, St } = imports.gi;
|
||||||
|
|
||||||
const Main = imports.ui.main;
|
const Main = imports.ui.main;
|
||||||
|
|
||||||
@ -100,11 +100,13 @@ var SwitcherPopup = GObject.registerClass({
|
|||||||
if (this._items.length == 0)
|
if (this._items.length == 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (!Main.pushModal(this)) {
|
let grab = Main.pushModal(this);
|
||||||
// Probably someone else has a pointer grab, try again with keyboard only
|
// We expect at least a keyboard grab here
|
||||||
if (!Main.pushModal(this, { options: Meta.ModalOptions.POINTER_ALREADY_GRABBED }))
|
if ((grab.get_seat_state() & Clutter.GrabState.KEYBOARD) === 0) {
|
||||||
|
Main.popModal(grab);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
this._grab = grab;
|
||||||
this._haveModal = true;
|
this._haveModal = true;
|
||||||
this._modifierMask = primaryModifier(mask);
|
this._modifierMask = primaryModifier(mask);
|
||||||
|
|
||||||
@ -306,7 +308,8 @@ var SwitcherPopup = GObject.registerClass({
|
|||||||
|
|
||||||
_popModal() {
|
_popModal() {
|
||||||
if (this._haveModal) {
|
if (this._haveModal) {
|
||||||
Main.popModal(this);
|
Main.popModal(this._grab);
|
||||||
|
this._grab = null;
|
||||||
this._haveModal = false;
|
this._haveModal = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -904,9 +904,13 @@ var UnlockDialog = GObject.registerClass({
|
|||||||
timestamp,
|
timestamp,
|
||||||
actionMode: Shell.ActionMode.UNLOCK_SCREEN,
|
actionMode: Shell.ActionMode.UNLOCK_SCREEN,
|
||||||
};
|
};
|
||||||
if (!Main.pushModal(this, modalParams))
|
let grab = Main.pushModal(this, modalParams);
|
||||||
|
if (grab.get_seat_state() !== Clutter.GrabState.ALL) {
|
||||||
|
Main.popModal(grab);
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
this._grab = grab;
|
||||||
this._isModal = true;
|
this._isModal = true;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -918,7 +922,8 @@ var UnlockDialog = GObject.registerClass({
|
|||||||
|
|
||||||
popModal(timestamp) {
|
popModal(timestamp) {
|
||||||
if (this._isModal) {
|
if (this._isModal) {
|
||||||
Main.popModal(this, timestamp);
|
Main.popModal(this._grab, timestamp);
|
||||||
|
this._grab = null;
|
||||||
this._isModal = false;
|
this._isModal = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user