Skip to content

Commit 6e270ce

Browse files
authored
(Backport to Gnome 44) Fail gracefully instead of crashing if grab fails with the error "Could not grab modal" (#1032)
Related to #991. This is backport of the PR to the PaperWM extension version targeting Gnome 44. The PR to the `develop` branch is #1031. Please see that PR for more details.
2 parents 3a736d7 + 14b9131 commit 6e270ce

File tree

1 file changed

+27
-4
lines changed

1 file changed

+27
-4
lines changed

navigator.js

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -87,10 +87,21 @@ class ActionDispatcher {
8787

8888
// grab = stage.grab(this.actor)
8989
grab = Main.pushModal(this.actor);
90+
// Assume that grab succeeds and store that state in the object
91+
this.success = true;
9092
// We expect at least a keyboard grab here
9193
if ((grab.get_seat_state() & Clutter.GrabState.KEYBOARD) === 0) {
9294
console.error("Failed to grab modal");
93-
throw new Error('Could not grab modal');
95+
// Release current grab and let the user try again
96+
try {
97+
this.success = false;
98+
if (grab) {
99+
Main.popModal(grab);
100+
grab = null;
101+
}
102+
} catch (e) {
103+
console.error("Failed to release grab");
104+
}
94105
}
95106

96107
this.signals.connect(this.actor, 'key-press-event', this._keyPressEvent.bind(this));
@@ -101,6 +112,9 @@ class ActionDispatcher {
101112
}
102113

103114
show(backward, binding, mask) {
115+
// If required grab was not successful, then do not show anything
116+
if (!this.success) return;
117+
104118
this._modifierMask = getModLock(mask);
105119
this.navigator = getNavigator();
106120
TopBar.fixTopBar();
@@ -446,11 +460,11 @@ function getActionDispatcher(mode) {
446460
return dispatcher;
447461
}
448462
dispatcher = new ActionDispatcher();
449-
return getActionDispatcher(mode);
463+
return getActionDispatcher(mode);
450464
}
451465

452466
/**
453-
* Fishes current dispatcher (if any).
467+
* Finishes current dispatcher (if any).
454468
*/
455469
function finishDispatching() {
456470
dispatcher?._finish(global.get_current_time());
@@ -473,5 +487,14 @@ function dismissDispatcher(mode) {
473487

474488
function preview_navigate(meta_window, space, { display, screen, binding }) {
475489
let tabPopup = getActionDispatcher(Clutter.GrabState.KEYBOARD);
476-
tabPopup.show(binding.is_reversed(), binding.get_name(), binding.get_mask());
490+
491+
// Getting a dispatcher does not always succeed. Sometimes, it can fail because we are unable to
492+
// grab the keyboard.
493+
// In the case of a failure, fail gracefully by destroying the pop-up.
494+
if (!tabPopup.success) {
495+
tabPopup.destroy();
496+
return;
497+
}
498+
499+
tabPopup.show(binding.is_reversed(), binding.get_name(), binding.get_mask());
477500
}

0 commit comments

Comments
 (0)