diff options
author | Jon TURNEY <jon.turney@dronecode.org.uk> | 2010-08-12 15:00:01 +0100 |
---|---|---|
committer | Jon TURNEY <jon.turney@dronecode.org.uk> | 2011-06-29 19:14:35 +0100 |
commit | e78628406f0428454983db1c51a8c828bf5684e5 (patch) | |
tree | d694d7bd9118f5e46de6478a0d9069d795857948 /hw/xwin/winmultiwindowwndproc.c | |
parent | 1d7f3a0031b4ae7d8aa984799ffa578788061ce4 (diff) |
Cygwin/X: Preserve client area size and position on Windows window style change
When the style changes, adjust the window size so the client area remains the same.
Otherwise the window size may change when sizing is reflected from Windows to X, and
some windows are drawn expecting them to be exactly the requested size (e.g. the
gmplayer control window)
Use DeferWindowPos to delay the resize to preserve client area on WM_STYLECHANGING
until after the style change has actually happened in WM_STYLECHANGED
As a consquence of this, we need to be more careful to create windows with exactly
the requested placement and client area initially, so the client area matches what
the X client requested
Also synchronize the X windows idea of the placement of a window which Windows is
allowed to place
Signed-off-by: Jon TURNEY <jon.turney@dronecode.org.uk>
Reviewed-by: Colin Harrison <colin.harrison@virgin.net>
Tested-by: Colin Harrison <colin.harrison@virgin.net>
Diffstat (limited to 'hw/xwin/winmultiwindowwndproc.c')
-rw-r--r-- | hw/xwin/winmultiwindowwndproc.c | 58 |
1 files changed, 58 insertions, 0 deletions
diff --git a/hw/xwin/winmultiwindowwndproc.c b/hw/xwin/winmultiwindowwndproc.c index b559cd8cf..1a3be78d5 100644 --- a/hw/xwin/winmultiwindowwndproc.c +++ b/hw/xwin/winmultiwindowwndproc.c @@ -1008,6 +1008,64 @@ winTopLevelWindowProc (HWND hwnd, UINT message, winAdjustXWindow (pWin, hwnd); return 0; /* end of WM_SIZE handler */ + case WM_STYLECHANGING: + /* + When the style changes, adjust the Windows window size so the client area remains the same size, + and adjust the Windows window position so that the client area remains in the same place. + */ + { + RECT newWinRect; + DWORD dwExStyle; + DWORD dwStyle; + DWORD newStyle = ((STYLESTRUCT *)lParam)->styleNew; + WINDOWINFO wi; + + dwExStyle = GetWindowLongPtr (hwnd, GWL_EXSTYLE); + dwStyle = GetWindowLongPtr (hwnd, GWL_STYLE); + + winDebug("winTopLevelWindowProc - WM_STYLECHANGING from %08x %08x\n", dwStyle, dwExStyle); + + if (wParam == GWL_EXSTYLE) + dwExStyle = newStyle; + + if (wParam == GWL_STYLE) + dwStyle = newStyle; + + winDebug("winTopLevelWindowProc - WM_STYLECHANGING to %08x %08x\n", dwStyle, dwExStyle); + + /* Get client rect in screen coordinates */ + wi.cbSize = sizeof(WINDOWINFO); + GetWindowInfo(hwnd, &wi); + + winDebug("winTopLevelWindowProc - WM_STYLECHANGING client area {%d, %d, %d, %d}, {%d x %d}\n", wi.rcClient.left, wi.rcClient.top, wi.rcClient.right, wi.rcClient.bottom, wi.rcClient.right - wi.rcClient.left, wi.rcClient.bottom - wi.rcClient.top); + + newWinRect = wi.rcClient; + if (!AdjustWindowRectEx(&newWinRect, dwStyle, FALSE, dwExStyle)) + winDebug("winTopLevelWindowProc - WM_STYLECHANGING AdjustWindowRectEx failed\n"); + + winDebug("winTopLevelWindowProc - WM_STYLECHANGING window area should be {%d, %d, %d, %d}, {%d x %d}\n", newWinRect.left, newWinRect.top, newWinRect.right, newWinRect.bottom, newWinRect.right - newWinRect.left, newWinRect.bottom - newWinRect.top); + + /* + Style change hasn't happened yet, so we can't adjust the window size yet, as the winAdjustXWindow() + which WM_SIZE does will use the current (unchanged) style. Instead make a note to change it when + WM_STYLECHANGED is received... + */ + pWinPriv->hDwp = BeginDeferWindowPos(1); + pWinPriv->hDwp = DeferWindowPos(pWinPriv->hDwp, hwnd, NULL, newWinRect.left, newWinRect.top, newWinRect.right - newWinRect.left, newWinRect.bottom - newWinRect.top, SWP_NOACTIVATE | SWP_NOZORDER); + } + return 0; + + case WM_STYLECHANGED: + { + if (pWinPriv->hDwp) + { + EndDeferWindowPos(pWinPriv->hDwp); + pWinPriv->hDwp = NULL; + } + winDebug("winTopLevelWindowProc - WM_STYLECHANGED done\n"); + } + return 0; + case WM_MOUSEACTIVATE: /* Check if this window needs to be made active when clicked */ |