From 55e7b6fa5bbb84dc8f2689ff674b27706ffe5ef3 Mon Sep 17 00:00:00 2001 From: Vito Caputo Date: Thu, 5 Oct 2017 16:54:38 -0700 Subject: *: handle FocusIn events Some programs call XSetInputFocus(), so we should select FocusChangeEvent and handle FocusIn events, calling vwm_win_set_focus() when appropriate. It's rare, but SDL2 programs in particular seem to do this and vwm gets in a pretty annoying state when it does occur. This change should improve the situation. --- src/vwm.c | 11 ++++++++++- src/xevent.c | 13 +++++++++++++ src/xevent.h | 1 + src/xwindow.c | 6 ++++-- 4 files changed, 28 insertions(+), 3 deletions(-) diff --git a/src/vwm.c b/src/vwm.c index 179b1dc..c2c3027 100644 --- a/src/vwm.c +++ b/src/vwm.c @@ -126,7 +126,7 @@ static vwm_t * vwm_startup(void) #undef color XSelectInput(VWM_XDISPLAY(vwm), VWM_XROOT(vwm), - PropertyChangeMask | SubstructureNotifyMask | SubstructureRedirectMask | PointerMotionMask | ButtonPressMask | ButtonReleaseMask); + FocusChangeMask | PropertyChangeMask | SubstructureNotifyMask | SubstructureRedirectMask | PointerMotionMask | ButtonPressMask | ButtonReleaseMask); XGrabKey(VWM_XDISPLAY(vwm), AnyKey, WM_GRAB_MODIFIER, VWM_XROOT(vwm), False, GrabModeAsync, GrabModeAsync); XFlush(VWM_XDISPLAY(vwm)); @@ -259,6 +259,15 @@ void vwm_process_event(vwm_t *vwm) vwm_xevent_handle_property_notify(vwm, &event.xproperty); break; + case FocusIn: + VWM_TRACE("focusin"); + vwm_xevent_handle_focusin(vwm, &event.xfocus); + break; + + case FocusOut: + VWM_TRACE("focusout"); + break; + case MappingNotify: VWM_TRACE("mapping notify"); vwm_xevent_handle_mapping_notify(vwm, &event.xmapping); diff --git a/src/xevent.c b/src/xevent.c index e1b38e3..a14f37e 100644 --- a/src/xevent.c +++ b/src/xevent.c @@ -227,6 +227,19 @@ void vwm_xevent_handle_property_notify(vwm_t *vwm, XPropertyEvent *ev) } +void vwm_xevent_handle_focusin(vwm_t *vwm, XFocusInEvent *ev) +{ + vwm_window_t *vwin; + + if (ev->mode != NotifyNormal) + return; + + if ((vwin = vwm_win_lookup(vwm, ev->window)) && + (vwin != vwm_win_get_focused(vwm))) + vwm_win_set_focused(vwm, vwin); +} + + void vwm_xevent_handle_mapping_notify(vwm_t *vwm, XMappingEvent *ev) { XRefreshKeyboardMapping(ev); diff --git a/src/xevent.h b/src/xevent.h index dc710fd..da9a828 100644 --- a/src/xevent.h +++ b/src/xevent.h @@ -15,4 +15,5 @@ void vwm_xevent_handle_unmap_notify(vwm_t *vwm, XUnmapEvent *ev); void vwm_xevent_handle_map_notify(vwm_t *vwm, XMapEvent *ev); void vwm_xevent_handle_map_request(vwm_t *vwm, XMapRequestEvent *ev); void vwm_xevent_handle_property_notify(vwm_t *vwm, XPropertyEvent *ev); +void vwm_xevent_handle_focusin(vwm_t *vwm, XFocusInEvent *ev); void vwm_xevent_handle_mapping_notify(vwm_t *vwm, XMappingEvent *ev); diff --git a/src/xwindow.c b/src/xwindow.c index 1aa4f71..6fc9691 100644 --- a/src/xwindow.c +++ b/src/xwindow.c @@ -159,8 +159,10 @@ vwm_xwindow_t * vwm_xwin_create(vwm_t *vwm, Window win, vwm_grab_mode_t grabbed) XFetchName(VWM_XDISPLAY(vwm), win, &xwin->name); /* This is so we get the PropertyNotify event and can get the pid when it's set post-create, - * with my _NET_WM_PID patch the property is immediately available */ - XSelectInput(VWM_XDISPLAY(vwm), win, PropertyChangeMask); + * with my _NET_WM_PID patch the property is immediately available. + * FocusChangeMask is needed to notice when clients call XSetInputFocus(). + */ + XSelectInput(VWM_XDISPLAY(vwm), win, PropertyChangeMask | FocusChangeMask); /* we must track the mapped-by-client state of the window independent of managed vs. unmanaged because * in the case of override_redirect windows they may be unmapped (invisible) or mapped (visible) like menus without being managed. -- cgit v1.2.3