diff --git a/include/x11-helper.h b/include/x11-helper.h index e950fdc7..ac8ea92f 100644 --- a/include/x11-helper.h +++ b/include/x11-helper.h @@ -123,21 +123,23 @@ void release_pointer ( void ); /** * @param w xcb_window_t we want to grab keyboard on. + * @param iters Number of retries. * * Grab keyboard. * * @return 1 when keyboard is grabbed, 0 not. */ -int take_keyboard ( xcb_window_t w ); +int take_keyboard ( xcb_window_t w, int iters ); /** * @param w xcb_window_t we want to grab mouse on. + * @param iters Number of retries. * * Grab mouse. * * @return 1 when mouse is grabbed, 0 not. */ -int take_pointer ( xcb_window_t w ); +int take_pointer ( xcb_window_t w, int iters ); /** * @param mask The mask to canonilize diff --git a/source/rofi.c b/source/rofi.c index bad4cacc..2d2e11e7 100644 --- a/source/rofi.c +++ b/source/rofi.c @@ -576,6 +576,36 @@ static void error_trap_pop ( G_GNUC_UNUSED SnDisplay *display, xcb_connection_t --error_trap_depth; } +unsigned int lazy_grab_retry_count_kb = 0; +unsigned int lazy_grab_retry_count_pt = 0; +static gboolean lazy_grab_pointer ( G_GNUC_UNUSED gpointer data ) +{ + // After 5 sec. + if ( lazy_grab_retry_count_kb > (5*1000)) { + fprintf(stderr, "Failed to grab keyboard after %u times. Giving up.\n", lazy_grab_retry_count_kb); + g_main_loop_quit ( main_loop ); + return G_SOURCE_REMOVE; + } + if ( take_pointer ( xcb_stuff_get_root_window ( xcb ), 0 ) ){ + return G_SOURCE_REMOVE; + } + lazy_grab_retry_count_kb++; + return G_SOURCE_CONTINUE; +} +static gboolean lazy_grab_keyboard ( G_GNUC_UNUSED gpointer data ) +{ + // After 5 sec. + if ( lazy_grab_retry_count_pt > (5*1000)) { + fprintf(stderr, "Failed to grab pointer after %u times. Giving up.\n", lazy_grab_retry_count_pt); + return G_SOURCE_REMOVE; + } + if ( take_keyboard ( xcb_stuff_get_root_window ( xcb), 0 ) ){ + return G_SOURCE_REMOVE; + } + lazy_grab_retry_count_pt++; + return G_SOURCE_CONTINUE; +} + static gboolean startup ( G_GNUC_UNUSED gpointer data ) { TICK_N ( "Startup" ); @@ -595,13 +625,12 @@ static gboolean startup ( G_GNUC_UNUSED gpointer data ) // We grab this using the rootwindow (as dmenu does it). // this seems to result in the smallest delay for most people. if ( ( window_flags & MENU_NORMAL_WINDOW ) == 0 ) { - int has_keyboard = take_keyboard ( xcb_stuff_get_root_window ( xcb ) ); - if ( !has_keyboard ) { - fprintf ( stderr, "Failed to grab keyboard, even after %d uS.", 500 * 1000 ); - g_main_loop_quit ( main_loop ); - return G_SOURCE_REMOVE; + if ( !take_keyboard ( xcb_stuff_get_root_window ( xcb), 0) ){ + g_timeout_add ( 1,lazy_grab_keyboard, NULL); + } + if ( !take_pointer ( xcb_stuff_get_root_window ( xcb ), 0 )) { + g_timeout_add ( 1,lazy_grab_pointer, NULL); } - take_pointer ( xcb_stuff_get_root_window ( xcb ) ); } TICK_N ( "Grab keyboard" ); __create_window ( window_flags ); diff --git a/source/view.c b/source/view.c index 70890ff8..9ff53a68 100644 --- a/source/view.c +++ b/source/view.c @@ -1266,7 +1266,7 @@ void rofi_view_itterrate ( RofiViewState *state, xcb_generic_event_t *ev, xkb_st } case XCB_FOCUS_IN: if ( ( CacheState.flags & MENU_NORMAL_WINDOW ) == 0 ) { - take_keyboard ( CacheState.main_window ); + take_keyboard ( CacheState.main_window, 1); } break; case XCB_FOCUS_OUT: diff --git a/source/x11-helper.c b/source/x11-helper.c index b3022678..1c909922 100644 --- a/source/x11-helper.c +++ b/source/x11-helper.c @@ -515,9 +515,10 @@ int monitor_active ( workarea *mon ) monitor_dimensions ( 0, 0, mon ); return FALSE; } -int take_pointer ( xcb_window_t w ) +int take_pointer ( xcb_window_t w, int iters ) { - for ( int i = 0; i < 500; i++ ) { + int i = 0; + while ( TRUE ) { if ( xcb_connection_has_error ( xcb->connection ) ) { fprintf ( stderr, "Connection has error\n" ); exit ( EXIT_FAILURE ); @@ -532,14 +533,17 @@ int take_pointer ( xcb_window_t w ) } free ( r ); } + if ( (++i) > iters ){ + break; + } usleep ( 1000 ); } - fprintf ( stderr, "Failed to grab pointer.\n" ); return 0; } -int take_keyboard ( xcb_window_t w ) +int take_keyboard ( xcb_window_t w, int iters ) { - for ( int i = 0; i < 500; i++ ) { + int i = 0; + while ( TRUE ) { if ( xcb_connection_has_error ( xcb->connection ) ) { fprintf ( stderr, "Connection has error\n" ); exit ( EXIT_FAILURE ); @@ -555,9 +559,11 @@ int take_keyboard ( xcb_window_t w ) } free ( r ); } + if ( (++i) > iters ){ + break; + } usleep ( 1000 ); } - return 0; }