summaryrefslogtreecommitdiff
path: root/dix
diff options
context:
space:
mode:
authorDaniel Stone <daniel@fooishbar.org>2007-08-01 06:55:36 +0300
committerDaniel Stone <daniel@fooishbar.org>2007-08-01 06:55:36 +0300
commit6b055e5d9751e3679ff98065e43225ec8a960053 (patch)
treee0c1a18deb141c823f6d159954675167aef38186 /dix
parent0e0174d45ecbeb7b6dddc4af53da9d6211038e0e (diff)
Input: Fix stuck modifiers (bug #11683)
Disclaimer: It's 6:51am. I'm trying to be as understandable as possible. What was happening previously was this: * Press Alt * Extended event generated and processed: state is now Alt down once * Core event generated - keyboard switched: inherited state is Alt down once - event processed: Alt down twice * Release Alt * Extended event generated and processed: state is now null * Core event generated and processed: Alt down once If we switch the order: * Press Alt * Core event generated: - keyboard switched: inherited state is null - event processed: Alt down once * Extended event generated and processed: state is now Alt down once * Release Alt * Core event generated and processed: state is now null * Extended event generated and processed: state is now null When we carry over the previous state, it needs to be the _previous_ state (state and modifiersPerKey), assuming that we're going to catch now-core events for any of these. For example, if Ctrl is held down as we pivot, we need to carry Ctrl over with a count of one, for which an extended + core release will then clear. Carrying over the union of the previous state _and the state resulting from the immediate action_ was what broke things.
Diffstat (limited to 'dix')
-rw-r--r--dix/getevents.c54
1 files changed, 28 insertions, 26 deletions
diff --git a/dix/getevents.c b/dix/getevents.c
index bc3db7919..2a10038bc 100644
--- a/dix/getevents.c
+++ b/dix/getevents.c
@@ -445,6 +445,13 @@ GetKeyboardValuatorEvents(xEvent *events, DeviceIntPtr pDev, int type,
ms = GetTimeInMillis();
+ if (pDev->coreEvents) {
+ events->u.keyButtonPointer.time = ms;
+ events->u.u.type = type;
+ events->u.u.detail = key_code;
+ events++;
+ }
+
kbp = (deviceKeyButtonPointer *) events;
kbp->time = ms;
kbp->deviceid = pDev->id;
@@ -462,12 +469,6 @@ GetKeyboardValuatorEvents(xEvent *events, DeviceIntPtr pDev, int type,
num_valuators, valuators);
}
- if (pDev->coreEvents) {
- events->u.keyButtonPointer.time = ms;
- events->u.u.type = type;
- events->u.u.detail = key_code;
- }
-
return numEvents;
}
@@ -606,8 +607,27 @@ GetPointerEvents(xEvent *events, DeviceIntPtr pDev, int type, int buttons,
pDev->valuator->lastx = x;
pDev->valuator->lasty = y;
- if (!coreOnly)
- {
+ /* for some reason inputInfo.pointer does not have coreEvents set */
+ if (coreOnly || pDev->coreEvents) {
+ events->u.u.type = type;
+ events->u.keyButtonPointer.time = ms;
+ events->u.keyButtonPointer.rootX = x;
+ events->u.keyButtonPointer.rootY = y;
+
+ if (type == ButtonPress || type == ButtonRelease) {
+ /* We hijack SetPointerMapping to work on all core-sending
+ * devices, so we use the device-specific map here instead of
+ * the core one. */
+ events->u.u.detail = pDev->button->map[buttons];
+ }
+ else {
+ events->u.u.detail = 0;
+ }
+
+ events++;
+ }
+
+ if (!coreOnly) {
kbp = (deviceKeyButtonPointer *) events;
kbp->time = ms;
kbp->deviceid = pDev->id;
@@ -635,24 +655,6 @@ GetPointerEvents(xEvent *events, DeviceIntPtr pDev, int type, int buttons,
}
}
- /* for some reason inputInfo.pointer does not have coreEvents set */
- if (coreOnly || pDev->coreEvents) {
- events->u.u.type = type;
- events->u.keyButtonPointer.time = ms;
- events->u.keyButtonPointer.rootX = x;
- events->u.keyButtonPointer.rootY = y;
-
- if (type == ButtonPress || type == ButtonRelease) {
- /* We hijack SetPointerMapping to work on all core-sending
- * devices, so we use the device-specific map here instead of
- * the core one. */
- events->u.u.detail = pDev->button->map[buttons];
- }
- else {
- events->u.u.detail = 0;
- }
- }
-
return num_events;
}