diff --git a/src/events.c b/src/events.c index 814e1ef..4dde482 100644 --- a/src/events.c +++ b/src/events.c @@ -680,15 +680,48 @@ colormap_notify (XEvent *ev) } } +/* + * enforce_focussed_window() runs after receipt of a FocusIn event with mode + * NotifyNormal. + * + * It checks if the given window (the one receiving focus) is one ratpoison + * focussed. If it is not, it sets focus back to what it should be. + * + * This is useful in cases where you have programs stealing keyboard focus. + */ +static void +enforce_focussed_window (Window w) { + /* If this is a window we focussed, then leave it alone. */ + if (w == focussed_window) + { + return; + } + + set_window_focus (focussed_window); +} + static void focus_change (XFocusChangeEvent *ev) { - rp_window *win; + if (ev == NULL) + { + return; + } + + /* See if we need to revert focus theft. */ + if (ev->type == FocusIn && ev->mode == NotifyNormal) + { + enforce_focussed_window (ev->window); + return; + } /* We're only interested in the NotifyGrab mode */ - if (ev->mode != NotifyGrab) return; + if (ev->mode != NotifyGrab) + { + return; + } - win = find_window (ev->window); + rp_window *win = find_window (ev->window); if (win != NULL) { diff --git a/src/globals.c b/src/globals.c index 1481a5c..83af975 100644 --- a/src/globals.c +++ b/src/globals.c @@ -91,6 +91,9 @@ struct numset *rp_frame_numset; /* The X11 selection globals */ rp_xselection selection; +/* The window we last gave focus to. */ +Window focussed_window = 0; + static void x_export_selection (void) { @@ -253,6 +256,7 @@ void set_rp_window_focus (rp_window *win) { PRINT_DEBUG (("Giving focus to '%s'\n", window_name (win))); + focussed_window = win->w; XSetInputFocus (dpy, win->w, RevertToPointerRoot, CurrentTime); } @@ -261,6 +265,7 @@ void set_window_focus (Window window) { PRINT_DEBUG (("Giving focus to %ld\n", window)); + focussed_window = window; XSetInputFocus (dpy, window, RevertToPointerRoot, CurrentTime); } diff --git a/src/globals.h b/src/globals.h index 1fb7e0f..7dc5483 100644 --- a/src/globals.h +++ b/src/globals.h @@ -207,6 +207,9 @@ void set_selection (char *txt); void set_nselection (char *txt, int len); char *get_selection (void); +/* The window we last gave focus to. */ +extern Window focussed_window; + /* Wrapper font functions to support Xft */ void rp_draw_string (rp_screen *s, Drawable d, int style, int x, int y, char *string, int length);