RFC: fix accelerators/Alt state on Alt+TAB window switch
Krzysztof Foltman
kfoltman at portal.onet.pl
Sat Mar 5 06:00:30 CST 2005
This patch fixes (or attempts to fix) a problem with Alt key being
partially stuck on switch to different window with Alt+TAB. Partially
means it doesn't interfere with normal characters, but it does interfere
with accelerator keys (ie. after switching windows Ctrl+C is reported
as Ctrl+Alt+C). This problem is said not to happen with some window
managers, although I don't see any mechanism that would
It does two things:
1. It sends WM_SYSKEYUP with VK_MENU on window switch. That's what
Windows does: it sends WM_SYSKEYUP just after WM_CANCELMODE, even if the
Alt key is still pressed.
For some reason, the WM_CANCELMODE and WM_SYSKEYDOWN/WM_SYSKEYUP aren't
sent to the same window in Windows. The possible explanation is that
WM_SYSKEY* are sent to the focused window, while WM_CANCELMODE is sent
to the top level window.
2. It resets the window menu flag on WM_CANCELMODE. The window menu flag
is responsible for activation of window menu bar by tapping Alt. The
change seems to be necessary on its own, however, it's essential for the
first patch to work correctly.
Without this patch, the window menu would be activated on every Alt+TAB,
because of WM_SYSKEYDOWN (Alt keypress in Alt+TAB)/WM_SYSKEYUP (the fake
one generated by the first patch).
Please test this patch, regardless if you have Alt+TAB related problems
or not. Comments or alternative solutions are welcome.
ChangeLog:
Krzysztof Foltman (krzysztof at foltman.com)
* WM_CANCELMODE resets menu flag in the default window procedure (so
that releasing Alt key won't bring the menu bar is WM_CANCELMODE was
received between WM_SYSKEYDOWN and WM_SYSKEYUP)
* Deactivating a window sends a fake Alt key release (that's what
Windows does immediately after deactivating a window, regardless if the
Alt key was really released or not)
Krzysztof
-------------- next part --------------
Index: dlls/x11drv/event.c
===================================================================
RCS file: /home/wine/wine/dlls/x11drv/event.c,v
retrieving revision 1.49
diff -u -r1.49 event.c
--- dlls/x11drv/event.c 1 Mar 2005 11:52:02 -0000 1.49
+++ dlls/x11drv/event.c 5 Mar 2005 11:18:08 -0000
@@ -479,8 +479,9 @@
wine_tsx11_unlock();
}
if (hwnd != GetForegroundWindow()) return;
+ TRACE("Sending WM_CANCELMODE\n");
SendMessageA( hwnd, WM_CANCELMODE, 0, 0 );
-
+
/* don't reset the foreground window, if the window which is
getting the focus is a Wine window */
@@ -505,6 +506,18 @@
SetForegroundWindow( 0 );
}
}
+ if (GetAsyncKeyState(VK_MENU)<0)
+ {
+ INPUT fake_alt_release;
+ fake_alt_release.type = INPUT_KEYBOARD;
+ fake_alt_release.ki.wVk = VK_MENU;
+ fake_alt_release.ki.wScan = 0;
+ fake_alt_release.ki.dwFlags = KEYEVENTF_KEYUP;
+ fake_alt_release.ki.time = GetTickCount(); /* is it really this kind of timestamp ? */
+ fake_alt_release.ki.dwExtraInfo = 0;
+ SendInput(1, &fake_alt_release, sizeof(INPUT));
+ }
+
}
Index: windows/defwnd.c
===================================================================
RCS file: /home/wine/wine/windows/defwnd.c,v
retrieving revision 1.104
diff -u -r1.104 defwnd.c
--- windows/defwnd.c 15 Feb 2005 21:51:06 -0000 1.104
+++ windows/defwnd.c 5 Mar 2005 11:18:10 -0000
@@ -591,6 +591,7 @@
}
case WM_CANCELMODE:
+ iMenuSysKey = 0;
if (!(GetWindowLongW( hwnd, GWL_STYLE ) & WS_CHILD)) EndMenu();
if (GetCapture() == hwnd) ReleaseCapture();
break;
More information about the wine-patches
mailing list