summaryrefslogtreecommitdiff
path: root/src/backends
diff options
context:
space:
mode:
authorOwen W. Taylor <otaylor@fishsoup.net>2015-08-21 16:25:53 -0400
committerOwen W. Taylor <otaylor@fishsoup.net>2015-09-03 16:02:25 -0400
commit614d6bd0f80ce336df7dca64e04746b057753f3b (patch)
treeedabb63cf400cfe5954fc70b8e1eadf4c348ca59 /src/backends
parent1d56d50fcd8e7d1afabde18f64f4b62aa834d38c (diff)
downloadmutter-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.c30
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