Fix key repeats during VT switch.
Add keyc->postdown, which represents the key state as of the last mieqEnqueue call, and use it when we need to know the posted state, instead of the processed state (keyc->down). Add small functions to getevents.c to query and modify key state in postdown and use them all through, eliminating previously broken uses.
This commit is contained in:
parent
e332335241
commit
81c28ffd2b
|
@ -868,6 +868,7 @@ InitKeyClassDeviceStruct(DeviceIntPtr dev, KeySymsPtr pKeySyms, CARD8 pModifiers
|
||||||
else
|
else
|
||||||
bzero((char *)keyc->modifierMap, MAP_LENGTH);
|
bzero((char *)keyc->modifierMap, MAP_LENGTH);
|
||||||
bzero((char *)keyc->down, DOWN_LENGTH);
|
bzero((char *)keyc->down, DOWN_LENGTH);
|
||||||
|
bzero((char *)keyc->postdown, DOWN_LENGTH);
|
||||||
for (i = 0; i < 8; i++)
|
for (i = 0; i < 8; i++)
|
||||||
keyc->modifierKeyCount[i] = 0;
|
keyc->modifierKeyCount[i] = 0;
|
||||||
if (!SetKeySymsMap(&keyc->curKeySyms, pKeySyms) || !InitModMap(keyc))
|
if (!SetKeySymsMap(&keyc->curKeySyms, pKeySyms) || !InitModMap(keyc))
|
||||||
|
|
|
@ -80,6 +80,23 @@ GetMotionHistorySize(void)
|
||||||
return MOTION_HISTORY_SIZE;
|
return MOTION_HISTORY_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
set_key_down(DeviceIntPtr pDev, int key_code)
|
||||||
|
{
|
||||||
|
pDev->key->postdown[key_code >> 3] |= (1 << (key_code & 7));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
set_key_up(DeviceIntPtr pDev, int key_code)
|
||||||
|
{
|
||||||
|
pDev->key->postdown[key_code >> 3] &= ~(1 << (key_code & 7));
|
||||||
|
}
|
||||||
|
|
||||||
|
static Bool
|
||||||
|
key_is_down(DeviceIntPtr pDev, int key_code)
|
||||||
|
{
|
||||||
|
return pDev->key->postdown[key_code >> 3] >> (key_code & 7);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Allocate the motion history buffer.
|
* Allocate the motion history buffer.
|
||||||
|
@ -414,17 +431,15 @@ GetKeyboardValuatorEvents(xEvent *events, DeviceIntPtr pDev, int type,
|
||||||
case XK_Shift_Lock:
|
case XK_Shift_Lock:
|
||||||
if (type == KeyRelease)
|
if (type == KeyRelease)
|
||||||
return 0;
|
return 0;
|
||||||
else if (type == KeyPress &&
|
else if (type == KeyPress && key_is_down(pDev, key_code))
|
||||||
(pDev->key->down[key_code >> 3] & (key_code & 7)) & 1)
|
type = KeyRelease;
|
||||||
type = KeyRelease;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Handle core repeating, via press/release/press/release.
|
/* Handle core repeating, via press/release/press/release.
|
||||||
* FIXME: In theory, if you're repeating with two keyboards in non-XKB,
|
* FIXME: In theory, if you're repeating with two keyboards in non-XKB,
|
||||||
* you could get unbalanced events here. */
|
* you could get unbalanced events here. */
|
||||||
if (type == KeyPress &&
|
if (type == KeyPress && key_is_down(pDev, key_code)) {
|
||||||
(((pDev->key->down[key_code >> 3] & (key_code & 7))) & 1)) {
|
|
||||||
if (!pDev->kbdfeed->ctrl.autoRepeat ||
|
if (!pDev->kbdfeed->ctrl.autoRepeat ||
|
||||||
pDev->key->modifierMap[key_code] ||
|
pDev->key->modifierMap[key_code] ||
|
||||||
!(pDev->kbdfeed->ctrl.autoRepeats[key_code >> 3]
|
!(pDev->kbdfeed->ctrl.autoRepeats[key_code >> 3]
|
||||||
|
@ -449,6 +464,10 @@ GetKeyboardValuatorEvents(xEvent *events, DeviceIntPtr pDev, int type,
|
||||||
events->u.keyButtonPointer.time = ms;
|
events->u.keyButtonPointer.time = ms;
|
||||||
events->u.u.type = type;
|
events->u.u.type = type;
|
||||||
events->u.u.detail = key_code;
|
events->u.u.detail = key_code;
|
||||||
|
if (type == KeyPress)
|
||||||
|
set_key_down(inputInfo.keyboard, key_code);
|
||||||
|
else if (type == KeyRelease)
|
||||||
|
set_key_up(inputInfo.keyboard, key_code);
|
||||||
events++;
|
events++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -456,10 +475,14 @@ GetKeyboardValuatorEvents(xEvent *events, DeviceIntPtr pDev, int type,
|
||||||
kbp->time = ms;
|
kbp->time = ms;
|
||||||
kbp->deviceid = pDev->id;
|
kbp->deviceid = pDev->id;
|
||||||
kbp->detail = key_code;
|
kbp->detail = key_code;
|
||||||
if (type == KeyPress)
|
if (type == KeyPress) {
|
||||||
kbp->type = DeviceKeyPress;
|
kbp->type = DeviceKeyPress;
|
||||||
else if (type == KeyRelease)
|
set_key_down(pDev, key_code);
|
||||||
|
}
|
||||||
|
else if (type == KeyRelease) {
|
||||||
kbp->type = DeviceKeyRelease;
|
kbp->type = DeviceKeyRelease;
|
||||||
|
set_key_up(pDev, key_code);
|
||||||
|
}
|
||||||
|
|
||||||
events++;
|
events++;
|
||||||
if (num_valuators) {
|
if (num_valuators) {
|
||||||
|
|
|
@ -66,7 +66,7 @@
|
||||||
#define KanaMask Mod4Mask
|
#define KanaMask Mod4Mask
|
||||||
#define ScrollLockMask Mod5Mask
|
#define ScrollLockMask Mod5Mask
|
||||||
|
|
||||||
#define KeyPressed(k) (keyc->down[k >> 3] & (1 << (k & 7)))
|
#define KeyPressed(k) (keyc->postdown[k >> 3] & (1 << (k & 7)))
|
||||||
#define ModifierDown(k) ((keyc->state & (k)) == (k))
|
#define ModifierDown(k) ((keyc->state & (k)) == (k))
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -122,6 +122,7 @@ typedef struct _GrabRec {
|
||||||
|
|
||||||
typedef struct _KeyClassRec {
|
typedef struct _KeyClassRec {
|
||||||
CARD8 down[DOWN_LENGTH];
|
CARD8 down[DOWN_LENGTH];
|
||||||
|
CARD8 postdown[DOWN_LENGTH];
|
||||||
KeyCode *modifierKeyMap;
|
KeyCode *modifierKeyMap;
|
||||||
KeySymsRec curKeySyms;
|
KeySymsRec curKeySyms;
|
||||||
int modifierKeyCount[8];
|
int modifierKeyCount[8];
|
||||||
|
|
Loading…
Reference in New Issue