diff options
author | Jon TURNEY <jon.turney@dronecode.org.uk> | 2012-11-08 20:03:11 +0000 |
---|---|---|
committer | Jon TURNEY <jon.turney@dronecode.org.uk> | 2012-11-30 14:26:53 +0000 |
commit | 0d59ca6faadebf658641b1964dbc6e923ff993c4 (patch) | |
tree | 1410cd29c42012d4a3c11b2474fb677d0526271c | |
parent | 2cd75a6a80373fb77f0ffd77ac070897ed548a0f (diff) |
Workaround WS_EX_LAYERED drawing bugs on XP
It seems that XP starts drawing window contents in the wrong place and other
wise makes a mess of things if the border style of a WS_EX_LAYERED window
changes.
Work around this:
i/ Defer turning on WS_EX_LAYERED until we've done the initial style twiddling
for override-redirect windows
ii/ hide and show the window when it's style changes (which causes it to be
redrawn and thus the entire image re-fetched from the X server...)
-rw-r--r-- | src/wndproc.c | 30 |
1 files changed, 26 insertions, 4 deletions
diff --git a/src/wndproc.c b/src/wndproc.c index 55ed66f..e64599f 100644 --- a/src/wndproc.c +++ b/src/wndproc.c @@ -562,11 +562,28 @@ winApplyStyle(xcwm_window_t *window) DEBUG("winApplyStyle: id 0x%08x hints 0x%08x style 0x%08x exstyle 0x%08x\n", window->window_id, hint, style, exStyle); - /* Apply the updated window style, without changing it's show or activation state */ UINT flags = SWP_FRAMECHANGED | SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE; if (zstyle == HWND_NOTOPMOST) flags |= SWP_NOZORDER | SWP_NOOWNERZORDER; - SetWindowPos(hWnd, NULL, 0, 0, 0, 0, flags); + + if (!pDwmEnableBlurBehindWindow) + { + /* + On XP, it seems we have to do an elaborate, performance killing + dance when changing the style of a window with WS_EX_LAYERED set, + to ensure that the the windows contents are drawn in the right place... + */ + ShowWindow(hWnd, SW_HIDE); + SetWindowLongPtr(hWnd, GWL_EXSTYLE, exStyle & ~WS_EX_LAYERED); + SetWindowLongPtr(hWnd, GWL_EXSTYLE, exStyle | WS_EX_LAYERED); + SetWindowPos(hWnd, NULL, 0, 0, 0, 0, flags); + ShowWindow(hWnd, SW_SHOW); + } + else + { + /* Apply the updated window style, without changing it's show or activation state */ + SetWindowPos(hWnd, NULL, 0, 0, 0, 0, flags); + } } /* @@ -1196,7 +1213,7 @@ winCreateWindowsWindow(xcwm_window_t *window) /* Make it WS_OVERLAPPED in create call since WS_POPUP doesn't support */ /* CW_USEDEFAULT, change back to popup after creation */ dwStyle = WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS; - dwExStyle = WS_EX_TOOLWINDOW | WS_EX_LAYERED; + dwExStyle = WS_EX_TOOLWINDOW; /* Calculate the window coordinates containing the requested client area, @@ -1285,12 +1302,17 @@ winCreateWindowsWindow(xcwm_window_t *window) SetWindowPos(hWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE); } + /* + Don't turn on WS_EX_LAYERED until after we've done our WS_OVERLAPPED + to WS_POPUP dance to avoid rendering bugs in XP + */ + SetWindowLongPtr(hWnd, GWL_EXSTYLE, dwExStyle | WS_EX_LAYERED); + /* Apply all properties which effect the window appearance or behaviour */ UpdateName(window); /* UpdateIcon(); */ UpdateStyle(window); - /* Display the window without activating it */ ShowWindow(hWnd, SW_SHOWNOACTIVATE); } |