diff --git a/Changelog b/Changelog index b46cc70b..b3556a2a 100644 --- a/Changelog +++ b/Changelog @@ -1,3 +1,14 @@ +v1.3.1: Dan vs. Greg: The never ending story, reloaded. (unreleased) + New Features + - [DRun] Search categories. (#449) + Improvements + - Fix exit when failed to grab keyboard. (#524) + - Introduce lazy keyboard grab mode for people who want rofi to show on key-down in i3. + - Add copyrights to theme (needed for debian packaging). + - DMENU: Correctly detect end-of-file (#518) + - Directly queue redraw on overlay change. + - Remove pango markup from workspace names in I3. (#507) + v1.3.0: Dan vs. Greg: The never ending story. New Features - Use randr for getting monitor layout. Fallback to xinerama if not available. 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 84f71ef9..cbfba281 100644 --- a/source/rofi.c +++ b/source/rofi.c @@ -578,6 +578,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" ); @@ -597,13 +627,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 18386571..77db45eb 100644 --- a/source/view.c +++ b/source/view.c @@ -1295,7 +1295,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; }