@@ -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 */
455469function finishDispatching ( ) {
456470 dispatcher ?. _finish ( global . get_current_time ( ) ) ;
@@ -473,5 +487,14 @@ function dismissDispatcher(mode) {
473487
474488function 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