aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--xorg-server/hw/xwin/winkeybd.c99
-rw-r--r--xorg-server/hw/xwin/winwndproc.c8
2 files changed, 62 insertions, 45 deletions
diff --git a/xorg-server/hw/xwin/winkeybd.c b/xorg-server/hw/xwin/winkeybd.c
index f82ef0d51..a02e22d74 100644
--- a/xorg-server/hw/xwin/winkeybd.c
+++ b/xorg-server/hw/xwin/winkeybd.c
@@ -343,8 +343,12 @@ winIsFakeCtrl_L (UINT message, WPARAM wParam, LPARAM lParam)
LONG lTime;
Bool fReturn;
+ static Bool lastWasControlL = FALSE;
+ static UINT lastMessage;
+ static LONG lastTime;
+
/*
- * Fake Ctrl_L presses will be followed by an Alt_R keypress
+ * Fake Ctrl_L presses will be followed by an Alt_R press
* with the same timestamp as the Ctrl_L press.
*/
if ((message == WM_KEYDOWN || message == WM_SYSKEYDOWN)
@@ -356,34 +360,31 @@ winIsFakeCtrl_L (UINT message, WPARAM wParam, LPARAM lParam)
/* Get time of current message */
lTime = GetMessageTime ();
- /* Look for fake Ctrl_L preceeding an Alt_R press. */
+ /* Look for next press message. */
fReturn = PeekMessage (&msgNext, NULL,
WM_KEYDOWN, WM_SYSKEYDOWN,
PM_NOREMOVE);
- /*
- * Try again if the first call fails.
- * NOTE: This usually happens when TweakUI is enabled.
- */
- if (!fReturn)
- {
- /* Voodoo to make sure that the Alt_R message has posted */
- Sleep (0);
-
- /* Look for fake Ctrl_L preceeding an Alt_R press. */
- fReturn = PeekMessage (&msgNext, NULL,
- WM_KEYDOWN, WM_SYSKEYDOWN,
- PM_NOREMOVE);
- }
- if (msgNext.message != WM_KEYDOWN && msgNext.message != WM_SYSKEYDOWN)
+ if (fReturn && msgNext.message != WM_KEYDOWN && msgNext.message != WM_SYSKEYDOWN)
fReturn = 0;
+ if (!fReturn)
+ {
+ lastWasControlL = TRUE;
+ lastMessage = message;
+ lastTime = lTime;
+ }
+ else
+ {
+ lastWasControlL = FALSE;
+ }
+
/* Is next press an Alt_R with the same timestamp? */
if (fReturn && msgNext.wParam == VK_MENU
&& msgNext.time == lTime
&& (HIWORD (msgNext.lParam) & KF_EXTENDED))
{
- /*
+ /*
* Next key press is Alt_R with same timestamp as current
* Ctrl_L message. Therefore, this Ctrl_L press is a fake
* event, so discard it.
@@ -391,12 +392,35 @@ winIsFakeCtrl_L (UINT message, WPARAM wParam, LPARAM lParam)
return TRUE;
}
}
+ /*
+ * Sometimes, the Alt_R press message is not yet posted when the
+ * fake Ctrl_L press message arrives (even though it has the
+ * same timestamp), so check for an Alt_R press message that has
+ * arrived since the last Ctrl_L message.
+ */
+ else if ((message == WM_KEYDOWN || message == WM_SYSKEYDOWN)
+ && wParam == VK_MENU
+ && (HIWORD (lParam) & KF_EXTENDED))
+ {
+ /* Got a Alt_R press */
- /*
+ if (lastWasControlL)
+ {
+ lTime = GetMessageTime ();
+
+ if (lastTime == lTime)
+ {
+ /* Undo the fake Ctrl_L press by sending a fake Ctrl_L release */
+ winSendKeyEvent (KEY_LCtrl, FALSE);
+ }
+ lastWasControlL = FALSE;
+ }
+ }
+ /*
* Fake Ctrl_L releases will be followed by an Alt_R release
* with the same timestamp as the Ctrl_L release.
*/
- if ((message == WM_KEYUP || message == WM_SYSKEYUP)
+ else if ((message == WM_KEYUP || message == WM_SYSKEYUP)
&& wParam == VK_CONTROL
&& (HIWORD (lParam) & KF_EXTENDED) == 0)
{
@@ -405,29 +429,16 @@ winIsFakeCtrl_L (UINT message, WPARAM wParam, LPARAM lParam)
/* Get time of current message */
lTime = GetMessageTime ();
- /* Look for fake Ctrl_L release preceeding an Alt_R release. */
+ /* Look for next release message. */
fReturn = PeekMessage (&msgNext, NULL,
- WM_KEYUP, WM_SYSKEYUP,
+ WM_KEYUP, WM_SYSKEYUP,
PM_NOREMOVE);
-
- /*
- * Try again if the first call fails.
- * NOTE: This usually happens when TweakUI is enabled.
- */
- if (!fReturn)
- {
- /* Voodoo to make sure that the Alt_R message has posted */
- Sleep (0);
-
- /* Look for fake Ctrl_L release preceeding an Alt_R release. */
- fReturn = PeekMessage (&msgNext, NULL,
- WM_KEYUP, WM_SYSKEYUP,
- PM_NOREMOVE);
- }
-
- if (msgNext.message != WM_KEYUP && msgNext.message != WM_SYSKEYUP)
+
+ if (fReturn && msgNext.message != WM_KEYUP && msgNext.message != WM_SYSKEYUP)
fReturn = 0;
-
+
+ lastWasControlL = FALSE;
+
/* Is next press an Alt_R with the same timestamp? */
if (fReturn
&& (msgNext.message == WM_KEYUP
@@ -444,7 +455,13 @@ winIsFakeCtrl_L (UINT message, WPARAM wParam, LPARAM lParam)
return TRUE;
}
}
-
+ else
+ {
+ /* On any other press or release message, we don't have a
+ potentially fake Ctrl_L to worry about anymore... */
+ lastWasControlL = FALSE;
+ }
+
/* Not a fake control left press/release */
return FALSE;
}
diff --git a/xorg-server/hw/xwin/winwndproc.c b/xorg-server/hw/xwin/winwndproc.c
index 8dbd90971..d4e3c4529 100644
--- a/xorg-server/hw/xwin/winwndproc.c
+++ b/xorg-server/hw/xwin/winwndproc.c
@@ -1063,6 +1063,10 @@ winWindowProc (HWND hwnd, UINT message,
if ((wParam == VK_LWIN || wParam == VK_RWIN) && !g_fKeyboardHookLL)
break;
+ /* Discard fake Ctrl_L events that precede AltGR on non-US keyboards */
+ if (winIsFakeCtrl_L (message, wParam, lParam))
+ return 0;
+
/*
* Discard presses generated from Windows auto-repeat
*/
@@ -1083,10 +1087,6 @@ winWindowProc (HWND hwnd, UINT message,
}
}
- /* Discard fake Ctrl_L presses that precede AltGR on non-US keyboards */
- if (winIsFakeCtrl_L (message, wParam, lParam))
- return 0;
-
/* Translate Windows key code to X scan code */
winTranslateKey (wParam, lParam, &iScanCode);