Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[*.js]
indent_style = space
indent_size = 4
42 changes: 37 additions & 5 deletions navigator.js
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ class ActionDispatcher {
this.actor = Tiling.spaces.spaceContainer;
this.actor.set_flags(Clutter.ActorFlags.REACTIVE);
this.navigator = getNavigator();
this.success = true;

if (grab) {
Utils.debug("#dispatch", "already in grab");
Expand All @@ -89,8 +90,21 @@ class ActionDispatcher {
grab = Main.pushModal(this.actor);
// We expect at least a keyboard grab here
if ((grab.get_seat_state() & Clutter.GrabState.KEYBOARD) === 0) {
console.error("Failed to grab modal");
throw new Error('Could not grab modal');
console.error("[Fix-Attempt-2: grab modal] Failed to grab modal - failing gracefully");

// Release the current grab which does not match what we want.
// Set `grab` to `null`. So, we will attempt to grab the keyboard again next time.
this.success = false;
try {
if (grab) {
Main.popModal(grab);
grab = null;
}
} catch (e) {
Utils.debug("[Fix-Attempt-2: grab modal] Failed to release grab: ", e);
}

return;
}

this.signals.connect(this.actor, 'key-press-event', this._keyPressEvent.bind(this));
Expand All @@ -101,6 +115,9 @@ class ActionDispatcher {
}

show(backward, binding, mask) {
// If grab was not successful, don't try to do this.
if (!this.success) return;

this._modifierMask = getModLock(mask);
this.navigator = getNavigator();
TopBar.fixTopBar();
Expand Down Expand Up @@ -441,16 +458,25 @@ function finishNavigation(force = false) {
* @returns {ActionDispatcher}
*/
function getActionDispatcher(mode) {
// Falsy values include null, undefined, and a few other values. Everything else in Javascript
// is truthy.
// https://developer.mozilla.org/en-US/docs/Glossary/Falsy
if (dispatcher) {
dispatcher.mode |= mode;
return dispatcher;
}

dispatcher = new ActionDispatcher();
return getActionDispatcher(mode);
if (!dispatcher.success) {
console.error("[Fix-Attempt-2: grab modal] Action dispatcher creation was not successful");
}

dispatcher.mode |= mode;
return dispatcher;
}

/**
* Fishes current dispatcher (if any).
* Finishes current dispatcher (if any).
*/
function finishDispatching() {
dispatcher?._finish(global.get_current_time());
Expand All @@ -473,5 +499,11 @@ function dismissDispatcher(mode) {

function preview_navigate(meta_window, space, { display, screen, binding }) {
let tabPopup = getActionDispatcher(Clutter.GrabState.KEYBOARD);
tabPopup.show(binding.is_reversed(), binding.get_name(), binding.get_mask());
// Getting the action dispatcher does not always succeed. In the cases where it does not
// succeed, attempt to fail gracefully by destroying what we created and returning silently.
if (!tabPopup.success) {
tabPopup.destroy();
} else {
tabPopup.show(binding.is_reversed(), binding.get_name(), binding.get_mask());
}
}