diff options
author | Daniel Stone <daniel@fooishbar.org> | 2007-08-01 06:55:36 +0300 |
---|---|---|
committer | Daniel Stone <daniel@fooishbar.org> | 2007-08-01 06:55:36 +0300 |
commit | 6b055e5d9751e3679ff98065e43225ec8a960053 (patch) | |
tree | e0c1a18deb141c823f6d159954675167aef38186 /dix | |
parent | 0e0174d45ecbeb7b6dddc4af53da9d6211038e0e (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.c | 54 |
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; } |