diff options
author | Owen W. Taylor <otaylor@fishsoup.net> | 2015-08-21 16:25:53 -0400 |
---|---|---|
committer | Owen W. Taylor <otaylor@fishsoup.net> | 2015-09-03 16:02:25 -0400 |
commit | 614d6bd0f80ce336df7dca64e04746b057753f3b (patch) | |
tree | edabb63cf400cfe5954fc70b8e1eadf4c348ca59 /src/backends | |
parent | 1d56d50fcd8e7d1afabde18f64f4b62aa834d38c (diff) | |
download | mutter-614d6bd0f80ce336df7dca64e04746b057753f3b.tar.gz |
Nested X11: use KeymapNotify events to fix key state on FocusIn
If the user Alt-Tabs out of the window, we will be left thinking
the Alt key is still pressed since we don't see a release for it.
Solve this and other related issues for the nested X11 compositor
by selecting for KeymapStateMask which causes a KeymapNotify event
to be sent after each FocusIn, and when we get these events, update
the internal XKB state and send any necessary modifiers events to
clients.
https://bugzilla.gnome.org/show_bug.cgi?id=753948
Diffstat (limited to 'src/backends')
-rw-r--r-- | src/backends/x11/meta-backend-x11.c | 30 |
1 files changed, 30 insertions, 0 deletions
diff --git a/src/backends/x11/meta-backend-x11.c b/src/backends/x11/meta-backend-x11.c index a76dbc5c0..641fb8e79 100644 --- a/src/backends/x11/meta-backend-x11.c +++ b/src/backends/x11/meta-backend-x11.c @@ -40,6 +40,7 @@ #include "meta-idle-monitor-xsync.h" #include "meta-monitor-manager-xrandr.h" #include "backends/meta-monitor-manager-dummy.h" +#include "wayland/meta-wayland.h" #include "meta-cursor-renderer-x11.h" #include <meta/util.h> @@ -269,6 +270,21 @@ handle_host_xevent (MetaBackend *backend, } } + if (priv->mode == META_BACKEND_X11_MODE_NESTED && event->type == FocusIn) + { + Window xwin = meta_backend_x11_get_xwindow(x11); + XEvent xev; + + if (event->xfocus.window == xwin) + { + /* Since we've selected for KeymapStateMask, every FocusIn is followed immediately + * by a KeymapNotify event */ + XMaskEvent(priv->xdisplay, KeymapStateMask, &xev); + MetaWaylandCompositor *compositor = meta_wayland_compositor_get_default (); + meta_wayland_compositor_update_key_state (compositor, xev.xkeymap.key_vector, 32, 8); + } + } + if (event->type == (priv->xsync_event_base + XSyncAlarmNotify)) handle_alarm_notify (backend, event); @@ -800,6 +816,20 @@ meta_backend_x11_select_stage_events (MetaBackend *backend) } XISelectEvents (priv->xdisplay, xwin, &mask, 1); + + if (priv->mode == META_BACKEND_X11_MODE_NESTED) + { + /* We have no way of tracking key changes when the stage doesn't have + * focus, so we select for KeymapStateMask so that we get a complete + * dump of the keyboard state in a KeymapNotify event that immediately + * follows each FocusIn (and EnterNotify, but we ignore that.) + */ + XWindowAttributes xwa; + + XGetWindowAttributes(priv->xdisplay, xwin, &xwa); + XSelectInput(priv->xdisplay, xwin, + xwa.your_event_mask | FocusChangeMask | KeymapStateMask); + } } static void |