summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorQuentin Glidic <sardemff7+git@sardemff7.net>2020-03-26 13:45:45 +0100
committerQuentin Glidic <sardemff7+git@sardemff7.net>2020-12-13 15:56:37 +0100
commit11b677b521140cd7d7451c54f48cd6c2d9c9bf4a (patch)
treeb7bf8b5273e205944702c6a6cb9c7b7ab0bce440
parentec858dd305ef843e45998860f67af8524dc42fef (diff)
xcb: Nicer focus stealing in O-R mode
Signed-off-by: Quentin Glidic <sardemff7+git@sardemff7.net>
-rw-r--r--include/xcb-internal.h1
-rw-r--r--include/xcb.h3
-rw-r--r--source/view.c7
-rw-r--r--source/xcb.c26
4 files changed, 37 insertions, 0 deletions
diff --git a/include/xcb-internal.h b/include/xcb-internal.h
index 75fd4b89..fcbbc1ba 100644
--- a/include/xcb-internal.h
+++ b/include/xcb-internal.h
@@ -61,6 +61,7 @@ struct _xcb_stuff
xcb_timestamp_t last_timestamp;
NkBindingsSeat *bindings_seat;
gboolean mouse_seen;
+ xcb_window_t focus_revert;
};
#endif
diff --git a/include/xcb.h b/include/xcb.h
index d811a2c7..a88d8d92 100644
--- a/include/xcb.h
+++ b/include/xcb.h
@@ -127,6 +127,9 @@ typedef struct _workarea
*/
int monitor_active ( workarea *mon );
+void rofi_xcb_set_input_focus(xcb_window_t w);
+void rofi_xcb_revert_input_focus(void);
+
/**
* Depth of visual
*/
diff --git a/source/view.c b/source/view.c
index 0ebcd4bd..5e266405 100644
--- a/source/view.c
+++ b/source/view.c
@@ -1894,6 +1894,12 @@ RofiViewState *rofi_view_create ( Mode *sw,
xcb_map_window ( xcb->connection, CacheState.main_window );
widget_queue_redraw ( WIDGET ( state->main_window ) );
xcb_flush ( xcb->connection );
+
+ /* When Override Redirect, the WM will not let us know we can take focus, so just steal it */
+ if ( ( ( menu_flags & MENU_NORMAL_WINDOW ) == 0 ) ) {
+ rofi_xcb_set_input_focus(CacheState.main_window);
+ }
+
if ( xcb->sncontext != NULL ) {
sn_launchee_context_complete ( xcb->sncontext );
}
@@ -1946,6 +1952,7 @@ int rofi_view_error_dialog ( const char *msg, int markup )
void rofi_view_hide ( void )
{
if ( CacheState.main_window != XCB_WINDOW_NONE ) {
+ rofi_xcb_revert_input_focus();
xcb_unmap_window ( xcb->connection, CacheState.main_window );
display_early_cleanup ();
}
diff --git a/source/xcb.c b/source/xcb.c
index 3ad31a92..2067a106 100644
--- a/source/xcb.c
+++ b/source/xcb.c
@@ -1047,6 +1047,32 @@ static gboolean main_loop_x11_event_handler ( xcb_generic_event_t *ev, G_GNUC_UN
return G_SOURCE_CONTINUE;
}
+void rofi_xcb_set_input_focus ( xcb_window_t w )
+{
+ xcb_generic_error_t *error;
+ xcb_get_input_focus_reply_t *freply;
+ xcb_get_input_focus_cookie_t fcookie = xcb_get_input_focus ( xcb->connection );
+ freply = xcb_get_input_focus_reply ( xcb->connection, fcookie, &error );
+ if ( error != NULL ) {
+ g_warning ( "Could not get input focus (error %d), will revert focus to best effort", error->error_code );
+ free ( error );
+ xcb->focus_revert = 0;
+ } else {
+ xcb->focus_revert = freply->focus;
+ }
+ xcb_set_input_focus ( xcb->connection, XCB_INPUT_FOCUS_POINTER_ROOT, w, XCB_CURRENT_TIME );
+ xcb_flush ( xcb->connection );
+}
+
+void rofi_xcb_revert_input_focus (void)
+{
+ if ( xcb->focus_revert == 0 )
+ return;
+
+ xcb_set_input_focus ( xcb->connection, XCB_INPUT_FOCUS_POINTER_ROOT, xcb->focus_revert, XCB_CURRENT_TIME );
+ xcb_flush ( xcb->connection );
+}
+
static int take_pointer ( xcb_window_t w, int iters )
{
int i = 0;