[PATCH] user32: Allow WM_CAPTURECHANGE indicating SetCapture() parameter.
Christopher Thielen
cthielen at gmail.com
Tue Jan 12 22:27:46 CST 2016
Attached is my analysis of Wine's usage of WM_CAPTURECHANGED as
requested by Alexandre.
Reading the code has revealed the same logic change I originally
proposed -- allowing a WM_CAPTURECHANGED message to be sent to a window
losing focus if it was also the window gaining focus -- is needed in the
Mac driver as well. The Mac driver logic looks copied out of
dlls/user32/input.c.
I would appreciate if someone could double-check my analysis in a few
areas based on expertise:
dlls/comctl32/toolbar.c
dlls/comctl32/trackbar.c
dlls/user32/button.c
programs/regedit/childwnd.c
If no one has any concerns after a few days, I'll resubmit my patch with
the additional change mimicked for the Mac driver.
On 11/25/2015 01:51 PM, Chris Thielen wrote:
> Thanks Alexandre, that seemswise.
>
> I'll get a review ready after 1.8.
>
> On Monday, November 23, 2015, Alexandre Julliard <julliard at winehq.org
> <mailto:julliard at winehq.org>> wrote:
>
> Christopher Thielen <cthielen at gmail.com <javascript:;>> writes:
>
> > Fixes https://bugs.winehq.org/show_bug.cgi?id=13683
> >
> > A window may be notified with WM_CAPTURECHANGED about itself
> > gaining mouse capture if it calls SetCapture() twice.
>
> You'd need to review all places where we handle that message, I don't
> think we've taken that behavior into account.
>
> Because of this risk, I'm afraid it will have to wait until after code
> freeze.
>
> --
> Alexandre Julliard
> julliard at winehq.org <javascript:;>
>
-------------- next part --------------
Analysis of WM_CAPTURECHANGED usage in Wine to predict if an incoming correctedness patch will cause any side-effects.
The patch creates additional WM_CAPTURECHANGED messages in the case where a window losing focus is the same as the window gaining focus. This more correctly mimics Windows' behavior. Wine did not previously do this, causing a long-standing though isolated bug.
dlls/user.exe16/message.c: case WM_CAPTURECHANGED:
OK. Code is simply specifying WM_CAPTURECHANGED to ensure it is ignored.
dlls/winemac.drv/window.c: SendMessageW(previous, WM_CAPTURECHANGED, 0, (LPARAM)hwnd);
Appears to be in need of the same patch as I'm suggesting. Any idea why this code appears duplicated? Something about OS X having a different window server than *nix?
dlls/comctl32/tests/button.c: { WM_CAPTURECHANGED, sent|wparam|defwinproc, 0 },
Should be fine. WM_CAPTURECHANGED is simply here as part of a test message sequence.
dlls/comctl32/tests/monthcal.c: { WM_CAPTURECHANGED, sent|wparam|lparam|defwinproc, 0, 0},
Same as above.
dlls/comctl32/toolbar.c: case WM_CAPTURECHANGED:
Probably fine? Appears to be a ToolbarProc translating window messages into toolbar-based equivalents.
dlls/comctl32/trackbar.c: case WM_CAPTURECHANGED:
Same as above (for trackbars).
dlls/user32/button.c: case WM_CAPTURECHANGED:
dlls/user32/button.c: TRACE("WM_CAPTURECHANGED %p\n", hWnd);
Both lines part of the same button procedure. WM_CAPTURECHANGED causes get_button_state() to be called here and, if the button is pressed, causes the state to gain BUTTON_NSTATES.
Somebody who knows user32/button.c may want to comment.
dlls/user32/tests/msg.c: { WM_CAPTURECHANGED, sent },
dlls/user32/tests/msg.c: { WM_CAPTURECHANGED, sent },
dlls/user32/tests/msg.c: { WM_CAPTURECHANGED, sent },
dlls/user32/tests/msg.c: { WM_CAPTURECHANGED, sent },
dlls/user32/tests/msg.c: { WM_CAPTURECHANGED, sent },
dlls/user32/tests/msg.c: { WM_CAPTURECHANGED, sent|wparam|defwinproc, 0 },
dlls/user32/tests/msg.c: { WM_CAPTURECHANGED, sent|wparam|defwinproc, 0 },
dlls/user32/tests/msg.c: { WM_CAPTURECHANGED, sent|wparam|defwinproc, 0 },
dlls/user32/tests/msg.c: { WM_CAPTURECHANGED, sent|defwinproc },
dlls/user32/tests/msg.c: { WM_CAPTURECHANGED, sent|defwinproc },
dlls/user32/tests/msg.c: { WM_CAPTURECHANGED, sent|defwinproc },
dlls/user32/tests/msg.c: { WM_CAPTURECHANGED, sent|defwinproc|wparam|lparam, 0, 0 },
dlls/user32/tests/msg.c: case WM_CAPTURECHANGED:
dlls/user32/tests/msg.c: { WM_CAPTURECHANGED, sent|wparam|lparam, 0, WND_POPUP_ID }, /* popup */
dlls/user32/tests/msg.c: { WM_CAPTURECHANGED, sent|defwinproc },
dlls/user32/tests/msg.c: { WM_CAPTURECHANGED, sent|defwinproc },
dlls/user32/tests/msg.c: { WM_CAPTURECHANGED, sent|wparam|lparam|defwinproc, 0, 0 },
dlls/user32/tests/msg.c: case WM_CAPTURECHANGED:
OK. All part of pre-defined message patterns with the exception of the two cases. user32 tests still pass with patch.
dlls/user32/tests/edit.c:static BOOL got_wm_capturechanged = FALSE;
dlls/user32/tests/edit.c: case WM_CAPTURECHANGED:
dlls/user32/tests/edit.c: got_wm_capturechanged = TRUE;
dlls/user32/tests/edit.c: ok(got_wm_capturechanged, "main window capture did not change\n");
OK? Test continues to pass.
dlls/user32/tests/win.c: case WM_CAPTURECHANGED:
OK? Test continues to pass.
dlls/user32/spy.c: "WM_CAPTURECHANGED",
OK. Just a definition.
dlls/user32/input.c: SendMessageW( previous, WM_CAPTURECHANGED, 0, (LPARAM)hwnd );
OK. This is what my original patch addressed.
include/winuser.rh:#define WM_CAPTURECHANGED 0x0215
OK. Just a definition.
programs/regedit/childwnd.c: case WM_CAPTURECHANGED:
Unsure. Looks innocuous to me but somebody who knows regedit better could attest.
programs/taskmgr/graph.c: case WM_CAPTURECHANGED:
OK. Simply filtering it out.
programs/taskmgr/graphctl.c: case WM_CAPTURECHANGED:
Same as above.
tools/winapi/winapi_module_user.pm: WM_CAPTURECHANGED => {
OK. Just a definition.
More information about the wine-devel
mailing list