@@ -87,10 +87,21 @@ class ActionDispatcher {
87
87
88
88
// grab = stage.grab(this.actor)
89
89
grab = Main . pushModal ( this . actor ) ;
90
+ // Assume that grab succeeds and store that state in the object
91
+ this . success = true ;
90
92
// We expect at least a keyboard grab here
91
93
if ( ( grab . get_seat_state ( ) & Clutter . GrabState . KEYBOARD ) === 0 ) {
92
94
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
+ }
94
105
}
95
106
96
107
this . signals . connect ( this . actor , 'key-press-event' , this . _keyPressEvent . bind ( this ) ) ;
@@ -101,6 +112,9 @@ class ActionDispatcher {
101
112
}
102
113
103
114
show ( backward , binding , mask ) {
115
+ // If required grab was not successful, then do not show anything
116
+ if ( ! this . success ) return ;
117
+
104
118
this . _modifierMask = getModLock ( mask ) ;
105
119
this . navigator = getNavigator ( ) ;
106
120
TopBar . fixTopBar ( ) ;
@@ -446,11 +460,11 @@ function getActionDispatcher(mode) {
446
460
return dispatcher ;
447
461
}
448
462
dispatcher = new ActionDispatcher ( ) ;
449
- return getActionDispatcher ( mode ) ;
463
+ return getActionDispatcher ( mode ) ;
450
464
}
451
465
452
466
/**
453
- * Fishes current dispatcher (if any).
467
+ * Finishes current dispatcher (if any).
454
468
*/
455
469
function finishDispatching ( ) {
456
470
dispatcher ?. _finish ( global . get_current_time ( ) ) ;
@@ -473,5 +487,14 @@ function dismissDispatcher(mode) {
473
487
474
488
function preview_navigate ( meta_window , space , { display, screen, binding } ) {
475
489
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 ( ) ) ;
477
500
}
0 commit comments