Re-enabled Xnest fix for focus in + modifier bug.
* See https://bugs.freedesktop.org/show_bug.cgi?id=3030
Signed-off-by: Xiaoyang Yu (Max) <max.a.yu@intel.com>
Reviewed-by: Mikhail Gusarov <dottedmag@dottedmag.net>
This takes the xnest way of working around this (see
5904ef2ccd
"xnest: restore
xnestUpdateModifierState") and copies it to Xephyr.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
This commit is contained in:
parent
505724c5f3
commit
db0d3d4e57
|
@ -38,6 +38,8 @@
|
||||||
#include "ephyrglxext.h"
|
#include "ephyrglxext.h"
|
||||||
#endif /* XF86DRI */
|
#endif /* XF86DRI */
|
||||||
|
|
||||||
|
#include "xkbsrv.h"
|
||||||
|
|
||||||
extern int KdTsPhyScreen;
|
extern int KdTsPhyScreen;
|
||||||
#ifdef GLXEXT
|
#ifdef GLXEXT
|
||||||
extern Bool noGlxVisualInit;
|
extern Bool noGlxVisualInit;
|
||||||
|
@ -748,75 +750,55 @@ ephyrScreenFini (KdScreenInfo *screen)
|
||||||
void
|
void
|
||||||
ephyrUpdateModifierState(unsigned int state)
|
ephyrUpdateModifierState(unsigned int state)
|
||||||
{
|
{
|
||||||
#if 0
|
|
||||||
DeviceIntPtr pkeydev;
|
|
||||||
KeyClassPtr keyc;
|
|
||||||
int i;
|
|
||||||
CARD8 mask;
|
|
||||||
|
|
||||||
pkeydev = inputInfo.keyboard;
|
DeviceIntPtr pDev = inputInfo.keyboard;
|
||||||
|
KeyClassPtr keyc = pDev->key;
|
||||||
if (!pkeydev)
|
int i;
|
||||||
return;
|
CARD8 mask;
|
||||||
|
int xkb_state;
|
||||||
|
|
||||||
/* This is pretty broken.
|
if (!pDev)
|
||||||
*
|
return;
|
||||||
* What should happen is that focus out should do as a VT switch does in
|
|
||||||
* traditional servers: fake releases for all keys (and buttons too, come
|
|
||||||
* to think of it) currently down. Then, on focus in, get the state from
|
|
||||||
* the host, and fake keypresses for everything currently down.
|
|
||||||
*
|
|
||||||
* So I'm leaving this broken for a little while. Sorry, folks.
|
|
||||||
*
|
|
||||||
* -daniels
|
|
||||||
*/
|
|
||||||
|
|
||||||
keyc = pkeydev->key;
|
xkb_state = XkbStateFieldFromRec(&pDev->key->xkbInfo->state);
|
||||||
|
|
||||||
state = state & 0xff;
|
state = state & 0xff;
|
||||||
|
|
||||||
if (keyc->state == state)
|
if (xkb_state == state)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for (i = 0, mask = 1; i < 8; i++, mask <<= 1)
|
|
||||||
{
|
|
||||||
int key;
|
|
||||||
|
|
||||||
/* Modifier is down, but shouldn't be */
|
for (i = 0, mask = 1; i < 8; i++, mask <<= 1) {
|
||||||
if ((keyc->state & mask) && !(state & mask))
|
int key;
|
||||||
{
|
|
||||||
int count = keyc->modifierKeyCount[i];
|
/* Modifier is down, but shouldn't be
|
||||||
|
*/
|
||||||
for (key = 0; key < MAP_LENGTH; key++)
|
if ((xkb_state & mask) && !(state & mask)) {
|
||||||
if (keyc->xkbInfo->desc->map->modmap[key] & mask)
|
int count = keyc->modifierKeyCount[i];
|
||||||
{
|
|
||||||
int bit;
|
for (key = 0; key < MAP_LENGTH; key++)
|
||||||
BYTE *kptr;
|
if (keyc->xkbInfo->desc->map->modmap[key] & mask) {
|
||||||
|
int bit;
|
||||||
kptr = &keyc->down[key >> 3];
|
BYTE *kptr;
|
||||||
bit = 1 << (key & 7);
|
|
||||||
|
kptr = &keyc->down[key >> 3];
|
||||||
if (*kptr & bit && ephyrKbd &&
|
bit = 1 << (key & 7);
|
||||||
((EphyrKbdPrivate *)ephyrKbd->driverPrivate)->enabled)
|
|
||||||
KdEnqueueKeyboardEvent(ephyrKbd, key, TRUE); /* release */
|
if (*kptr & bit)
|
||||||
|
KdEnqueueKeyboardEvent (ephyrKbd, key, TRUE);
|
||||||
if (--count == 0)
|
|
||||||
break;
|
if (--count == 0)
|
||||||
}
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Modifier shoud be down, but isn't */
|
|
||||||
if (!(keyc->state & mask) && (state & mask))
|
|
||||||
for (key = 0; key < MAP_LENGTH; key++)
|
|
||||||
if (keyc->xkbInfo->desc->map->modmap[key] & mask)
|
|
||||||
{
|
|
||||||
if (keyc->xkbInfo->desc->map->modmap[key] & mask && ephyrKbd &&
|
|
||||||
((EphyrKbdPrivate *)ephyrKbd->driverPrivate)->enabled)
|
|
||||||
KdEnqueueKeyboardEvent(ephyrKbd, key, FALSE); /* press */
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
/* Modifier shoud be down, but isn't
|
||||||
|
*/
|
||||||
|
if (!(xkb_state & mask) && (state & mask))
|
||||||
|
for (key = 0; key < MAP_LENGTH; key++)
|
||||||
|
if (keyc->xkbInfo->desc->map->modmap[key] & mask) {
|
||||||
|
KdEnqueueKeyboardEvent (ephyrKbd, key, FALSE);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -998,6 +980,7 @@ ephyrPoll(void)
|
||||||
if (!ephyrKbd ||
|
if (!ephyrKbd ||
|
||||||
!((EphyrKbdPrivate *)ephyrKbd->driverPrivate)->enabled)
|
!((EphyrKbdPrivate *)ephyrKbd->driverPrivate)->enabled)
|
||||||
continue;
|
continue;
|
||||||
|
ephyrUpdateModifierState(ev.key_state);
|
||||||
KdEnqueueKeyboardEvent (ephyrKbd, ev.data.key_up.scancode, TRUE);
|
KdEnqueueKeyboardEvent (ephyrKbd, ev.data.key_up.scancode, TRUE);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue