diff options
author | Vito Caputo <vcaputo@pengaru.com> | 2017-10-05 16:54:38 -0700 |
---|---|---|
committer | Vito Caputo <vcaputo@pengaru.com> | 2017-10-05 16:54:38 -0700 |
commit | 55e7b6fa5bbb84dc8f2689ff674b27706ffe5ef3 (patch) | |
tree | 1d152a7fa0c7f09fd0652f8f9720393d9ebbee3f | |
parent | 7096b3b6c1325630d18e5d61aac58f9c3772b8e1 (diff) |
*: 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.
-rw-r--r-- | src/vwm.c | 11 | ||||
-rw-r--r-- | src/xevent.c | 13 | ||||
-rw-r--r-- | src/xevent.h | 1 | ||||
-rw-r--r-- | src/xwindow.c | 6 |
4 files changed, 28 insertions, 3 deletions
@@ -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. |