[PATCH v2 3/4] Input: Add focus-in event source
Daniel Stone
daniels at collabora.com
Fri Nov 20 07:37:30 PST 2015
Add a new event source type for keypress events synthesised from focus
notifications (e.g. KeymapNotify from the parent server, when running
nested). This is used to keep the keys-down array in sync with the host
server's, without sending actual keypress events to clients.
Signed-off-by: Daniel Stone <daniels at collabora.com>
---
Xi/exevents.c | 4 ++++
dix/getevents.c | 5 +++++
include/eventstr.h | 1 +
xkb/xkbActions.c | 26 ++++++++++++++++++++++++++
4 files changed, 36 insertions(+)
v2: Use flag in DeviceEvent, rather than new event type.
diff --git a/Xi/exevents.c b/Xi/exevents.c
index e728310..74e49ed 100644
--- a/Xi/exevents.c
+++ b/Xi/exevents.c
@@ -1760,6 +1760,10 @@ ProcessDeviceEvent(InternalEvent *ev, DeviceIntPtr device)
switch (event->type) {
case ET_KeyPress:
+ /* Don't deliver focus events (e.g. from KeymapNotify when running
+ * nested) to clients. */
+ if (event->source_type == EVENT_SOURCE_FOCUS)
+ return;
if (!grab && CheckDeviceGrabs(device, event, 0))
return;
break;
diff --git a/dix/getevents.c b/dix/getevents.c
index f04b415..4d06818 100644
--- a/dix/getevents.c
+++ b/dix/getevents.c
@@ -1101,6 +1101,11 @@ GetKeyboardEvents(InternalEvent *events, DeviceIntPtr pDev, int type,
}
#endif
+ if (type == KeymapNotify) {
+ source_type = EVENT_SOURCE_FOCUS;
+ type = KeyPress;
+ }
+
/* refuse events from disabled devices */
if (!pDev->enabled)
return 0;
diff --git a/include/eventstr.h b/include/eventstr.h
index 4fd846f..7446961 100644
--- a/include/eventstr.h
+++ b/include/eventstr.h
@@ -83,6 +83,7 @@ enum EventType {
*/
enum DeviceEventSource {
EVENT_SOURCE_NORMAL = 0, /**< Default: from a user action (e.g. key press) */
+ EVENT_SOURCE_FOCUS, /**< Keys or buttons previously down on focus-in */
};
/**
diff --git a/xkb/xkbActions.c b/xkb/xkbActions.c
index ddd09ab..aeb702c 100644
--- a/xkb/xkbActions.c
+++ b/xkb/xkbActions.c
@@ -1206,6 +1206,32 @@ XkbActionGetFilter(DeviceIntPtr dev, DeviceEvent *event, KeyCode key,
XkbSrvInfoPtr xkbi = dev->key->xkbInfo;
XkbFilterPtr filter;
+ /* For focus events, we only want to run actions which update our state to
+ * (hopefully vaguely kinda) match that of the host server, rather than
+ * actually execute anything. For example, if we enter our VT with
+ * Ctrl+Alt+Backspace held down, we don't want to terminate our server
+ * immediately, but we _do_ want Ctrl+Alt to be latched down, so if
+ * Backspace is released and then pressed again, the server will terminate.
+ *
+ * This is pretty flaky, and we should in fact inherit the complete state
+ * from the host server. There are some state combinations that we cannot
+ * express by running the state machine over every key, e.g. if AltGr+Shift
+ * generates a different state to Shift+AltGr. */
+ if (event->source_type == EVENT_SOURCE_FOCUS) {
+ switch (act->type) {
+ case XkbSA_SetMods:
+ case XkbSA_SetGroup:
+ case XkbSA_LatchMods:
+ case XkbSA_LatchGroup:
+ case XkbSA_LockMods:
+ case XkbSA_LockGroup:
+ break;
+ default:
+ *sendEvent = 1;
+ return;
+ }
+ }
+
switch (act->type) {
case XkbSA_SetMods:
case XkbSA_SetGroup:
--
2.5.0
More information about the xorg-devel
mailing list