When a key is in the "pressed" state while switching console, repeated
KeyPress/KeyRelease events will be generated while switched away from the
server. If switching was caused by Alt-Ctrl-Fx, then at least the Fx key is
pressed and the focused application receives a continuous stream
of "XF86_Switch_VT_x" events -- this in itself is sufficiently annoying
already as various applications like to spew the logs when they encounter
this event and don't know how to handle it.
Things get even more unfriendly if console switching is initiated by chvt from
a background service (don't ask). I propose to change the current logic for
releasing keys on VT switch -- release them before switching away from the
server, instead of after switching back. Would a patch like the attached one
be acceptable?
Best regards
--
Dipl. Math.
Helge Bahmann
Berater
Geschäftsbereich Hochsicherheit
secunet Security Networks AG
Ammonstraße 74
01067 Dresden, Germany
Fon: +49 201 54 54-3586
Fax: +49 201 54 54-1323
Email: [email protected]
Sitz: Kronprinzenstraße 30, 45128 Essen
Amtsgericht Essen HRB 13615
Vorstand: Dr. Rainer Baumgart, Thomas Koelzer, Thomas Pleines
Aufsichtsratsvorsitzender: Dr. Karsten Ottenberg
diff --git a/hw/xfree86/common/xf86Events.c b/hw/xfree86/common/xf86Events.c
index 76c207a..1e2ff11 100644
--- a/hw/xfree86/common/xf86Events.c
+++ b/hw/xfree86/common/xf86Events.c
@@ -82,6 +82,8 @@
#include "mi.h"
#include "mipointer.h"
+#include "xkbsrv.h"
+
#ifdef XF86BIGFONT
#define _XF86BIGFONT_SERVER_
#include <X11/extensions/xf86bigfont.h>
@@ -594,17 +596,25 @@ xf86SigHandler(int signo)
}
static void
+set_key_up(DeviceIntPtr pDev, int key_code)
+{
+ pDev->key->postdown[key_code >> 3] &= ~(1 << (key_code & 7));
+}
+
+static void
xf86ReleaseKeys(DeviceIntPtr pDev)
{
KeyClassPtr keyc = NULL;
KeySym *map = NULL;
+ XkbSrvInfoPtr xkbi;
xEvent ke;
- int i = 0, j = 0, nevents = 0;
+ int i = 0;
if (!pDev || !pDev->key)
return;
keyc = pDev->key;
+ xkbi = keyc->xkbInfo;
map = keyc->curKeySyms.map;
/*
@@ -631,25 +641,21 @@ xf86ReleaseKeys(DeviceIntPtr pDev)
case XK_Kana_Lock:
break;
default:
- if (pDev == inputInfo.keyboard) {
- ke.u.keyButtonPointer.time = GetTimeInMillis();
- ke.u.keyButtonPointer.rootX = 0;
- ke.u.keyButtonPointer.rootY = 0;
+ ke.u.keyButtonPointer.time = GetTimeInMillis();
+ ke.u.keyButtonPointer.rootX = 0;
+ ke.u.keyButtonPointer.rootY = 0;
+ if (pDev == inputInfo.keyboard)
ke.u.u.type = KeyRelease;
- ke.u.u.detail = i;
- (*pDev->public.processInputProc) (&ke, pDev, 1);
- }
- else {
- int sigstate = xf86BlockSIGIO ();
- nevents = GetKeyboardEvents(xf86Events, pDev, KeyRelease, i);
- for (j = 0; j < nevents; j++)
- mieqEnqueue(pDev, xf86Events + j);
- xf86UnblockSIGIO(sigstate);
- }
- break;
+ else
+ ke.u.u.type = DeviceKeyRelease;
+ ke.u.u.detail = i;
+ (*pDev->public.processInputProc) (&ke, pDev, 1);
+ set_key_up(pDev, i);
}
}
}
+
+ AccessXCancelRepeatKey(xkbi, xkbi->repeatKey);
}
/*
@@ -698,10 +704,15 @@ xf86VTSwitch()
*/
pInfo = xf86InputDevs;
while (pInfo) {
- if (pInfo->dev)
- DisableDevice(pInfo->dev);
+ if (pInfo->dev) {
+ xf86ReleaseKeys(pInfo->dev);
+ DisableDevice(pInfo->dev);
+ }
pInfo = pInfo->next;
}
+ /* XXX HACK */
+ xf86ReleaseKeys(inputInfo.keyboard);
+
xf86EnterServerState(SETUP);
for (i = 0; i < xf86NumScreens; i++)
xf86Screens[i]->LeaveVT(i, 0);
@@ -711,6 +722,11 @@ xf86VTSwitch()
xf86AccessLeave(); /* We need this here, otherwise */
xf86AccessLeaveState(); /* console won't be restored */
+ /* new events may have been enqueued asynchronously in the time window
+ between deactivating devices and shutting down the SIGIO handler,
+ which will later lead to spurious events after switching back */
+ mieqDiscardInputEvents();
+
if (!xf86VTSwitchAway()) {
/*
* switch failed
@@ -737,14 +753,10 @@ xf86VTSwitch()
pInfo = xf86InputDevs;
while (pInfo) {
- if (pInfo->dev) {
- xf86ReleaseKeys(pInfo->dev);
+ if (pInfo->dev)
EnableDevice(pInfo->dev);
- }
pInfo = pInfo->next;
}
- /* XXX HACK */
- xf86ReleaseKeys(inputInfo.keyboard);
for (ih = InputHandlers; ih; ih = ih->next)
xf86EnableInputHandler(ih);
diff --git a/mi/mi.h b/mi/mi.h
index 8d8f488..9e0b886 100644
--- a/mi/mi.h
+++ b/mi/mi.h
@@ -166,6 +166,10 @@ extern void mieqProcessInputEvents(
void
);
+extern void mieqDiscardInputEvents(
+ void
+);
+
typedef void (*mieqHandler)(int, xEventPtr, DeviceIntPtr, int);
void mieqSetHandler(int event, mieqHandler handler);
diff --git a/mi/mieq.c b/mi/mieq.c
index 8037247..b202468 100644
--- a/mi/mieq.c
+++ b/mi/mieq.c
@@ -259,3 +259,9 @@ mieqProcessInputEvents(void)
}
}
}
+
+void
+mieqDiscardInputEvents(void)
+{
+ miEventQueue.head = miEventQueue.tail;
+}
_______________________________________________
xorg mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/xorg