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.
This commit is contained in:
Daniel Stone 2007-08-01 06:55:36 +03:00
parent 0e0174d45e
commit 6b055e5d97

View File

@ -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;
}