Index: ui/views/win/hwnd_message_handler.cc |
diff --git a/ui/views/win/hwnd_message_handler.cc b/ui/views/win/hwnd_message_handler.cc |
index 8f243783480390b359bb61c892babb6e64ca6723..6dcd9d0010de5e516036f4a481ca921ffbd72d72 100644 |
--- a/ui/views/win/hwnd_message_handler.cc |
+++ b/ui/views/win/hwnd_message_handler.cc |
@@ -299,12 +299,6 @@ bool ProcessChildWindowMessage(UINT message, |
// The thickness of an auto-hide taskbar in pixels. |
const int kAutoHideTaskbarThicknessPx = 2; |
-// For windows with the standard frame removed, the client area needs to be |
-// different from the window area to avoid a "feature" in Windows's handling of |
-// WM_NCCALCSIZE data. See the comment near the bottom of GetClientAreaInsets |
-// for more details. |
-const int kClientAreaBottomInsetHack = -1; |
- |
} // namespace |
// A scoping class that prevents a window from being able to redraw in response |
@@ -786,11 +780,29 @@ void HWNDMessageHandler::FrameTypeChanged() { |
&policy, sizeof(DWMNCRENDERINGPOLICY)); |
} |
- ResetWindowRegion(true); |
+ // Don't redraw the window here, because we need to hide and show the window |
+ // which will also trigger a redraw. |
+ ResetWindowRegion(true, false); |
+ |
+ ::SetWindowPos(hwnd(), NULL, 0, 0, 0, 0, |
+ SWP_NOMOVE | SWP_NOSIZE | SWP_FRAMECHANGED); |
Peter Kasting
2013/11/12 01:47:03
Nit: All lines of args should begin at the same ho
|
// The non-client view needs to update too. |
Peter Kasting
2013/11/12 01:47:03
Does this explicitly need to happen before some of
|
delegate_->HandleFrameChanged(); |
+ // For some reason, we need to hide the window after we change the frame type. |
+ // If we don't, the client area will be filled with black. This is somehow |
+ // related to an interaction between SetWindowRgn and Dwm, but it's not clear |
+ // exactly what. |
+ if (IsVisible()) { |
+ SetWindowPos(hwnd(), NULL, 0, 0, 0, 0, |
+ SWP_NOMOVE | SWP_NOSIZE | SWP_HIDEWINDOW); |
+ SetWindowPos(hwnd(), NULL, 0, 0, 0, 0, |
+ SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW); |
Peter Kasting
2013/11/12 01:47:03
How are these calls different than what you could
|
+ } |
+ |
+ UpdateWindow(hwnd()); |
+ |
// WM_DWMCOMPOSITIONCHANGED is only sent to top level windows, however we want |
// to notify our children too, since we can have MDI child windows who need to |
// update their appearance. |
@@ -1043,22 +1055,10 @@ void HWNDMessageHandler::ClientAreaSizeChanged() { |
// In case of minimized window GetWindowRect can return normally unexpected |
// coordinates. |
if (!IsMinimized()) { |
- if (delegate_->WidgetSizeIsClientSize()) { |
+ if (delegate_->WidgetSizeIsClientSize()) |
GetClientRect(hwnd(), &r); |
- gfx::Insets insets; |
- bool got_insets = GetClientAreaInsets(&insets); |
- if (got_insets) { |
- // This is needed due to a hack that works around a "feature" in |
- // Windows's handling of WM_NCCALCSIZE. See the comment near the end of |
- // GetClientAreaInsets for more details. |
- if ((remove_standard_frame_ && !IsMaximized()) || |
- !fullscreen_handler_->fullscreen()) { |
- r.bottom += kClientAreaBottomInsetHack; |
- } |
- } |
- } else { |
+ else |
GetWindowRect(hwnd(), &r); |
- } |
} |
gfx::Size s(std::max(0, static_cast<int>(r.right - r.left)), |
std::max(0, static_cast<int>(r.bottom - r.top))); |
@@ -1090,46 +1090,11 @@ bool HWNDMessageHandler::GetClientAreaInsets(gfx::Insets* insets) const { |
return true; |
} |
- // Returning empty insets for a window with the standard frame removed seems |
- // to cause Windows to treat the window specially, treating black as |
- // transparent and changing around some of the painting logic. I suspect it's |
- // some sort of horrible backwards-compatability hack, but the upshot of it |
- // is that if the insets are empty then in certain conditions (it seems to |
- // be subtly related to timing), the contents of windows with the standard |
- // frame removed will flicker to transparent during resize. |
- // |
- // To work around this, we increase the size of the client area by 1px |
- // *beyond* the bottom of the window. This prevents Windows from having a |
- // hissy fit and flashing the window incessantly during resizes, but it also |
- // means that the client area is reported 1px larger than it really is, so |
- // user code has to compensate by making its content shorter if it wants |
- // everything to appear inside the window. |
- if (remove_standard_frame_) { |
- *insets = |
- gfx::Insets(0, 0, IsMaximized() ? 0 : kClientAreaBottomInsetHack, 0); |
- return true; |
- } |
- |
- // This is weird, but highly essential. If we don't offset the bottom edge |
- // of the client rect, the window client area and window area will match, |
- // and when returning to glass rendering mode from non-glass, the client |
- // area will not paint black as transparent. This is because (and I don't |
- // know why) the client area goes from matching the window rect to being |
- // something else. If the client area is not the window rect in both |
- // modes, the blackness doesn't occur. Because of this, we need to tell |
- // the RootView to lay out to fit the window rect, rather than the client |
- // rect when using the opaque frame. |
- // Note: this is only required for non-fullscreen windows. Note that |
- // fullscreen windows are in restored state, not maximized. |
- // Note that previously we used to inset by 1 instead of outset, but that |
- // doesn't work with Aura: http://crbug.com/172099 http://crbug.com/277228 |
- *insets = gfx::Insets( |
- 0, 0, |
- fullscreen_handler_->fullscreen() ? 0 : kClientAreaBottomInsetHack, 0); |
+ *insets = gfx::Insets(0, 0, 0, 0); |
Peter Kasting
2013/11/12 01:47:03
Nit: Just use gfx::Insets()
|
return true; |
} |
-void HWNDMessageHandler::ResetWindowRegion(bool force) { |
+void HWNDMessageHandler::ResetWindowRegion(bool force, bool redraw) { |
// A native frame uses the native window region, and we don't want to mess |
// with it. |
// WS_EX_COMPOSITED is used instead of WS_EX_LAYERED under aura. WS_EX_LAYERED |
@@ -1139,7 +1104,7 @@ void HWNDMessageHandler::ResetWindowRegion(bool force) { |
if ((window_ex_style() & WS_EX_COMPOSITED) == 0 && |
(!delegate_->IsUsingCustomFrame() || !delegate_->IsWidgetWindow())) { |
if (force) |
- SetWindowRgn(hwnd(), NULL, TRUE); |
+ SetWindowRgn(hwnd(), NULL, redraw); |
return; |
} |
@@ -1168,7 +1133,7 @@ void HWNDMessageHandler::ResetWindowRegion(bool force) { |
if (current_rgn_result == ERROR || !EqualRgn(current_rgn, new_region)) { |
// SetWindowRgn takes ownership of the HRGN created by CreateNativeRegion. |
- SetWindowRgn(hwnd(), new_region, TRUE); |
+ SetWindowRgn(hwnd(), new_region, redraw); |
} else { |
DeleteObject(new_region); |
} |
@@ -1381,12 +1346,7 @@ LRESULT HWNDMessageHandler::OnDwmCompositionChanged(UINT msg, |
SetMsgHandled(FALSE); |
return 0; |
} |
- // For some reason, we need to hide the window while we're changing the frame |
- // type only when we're changing it in response to WM_DWMCOMPOSITIONCHANGED. |
- // If we don't, the client area will be filled with black. I'm suspecting |
- // something skia-ey. |
- // Frame type toggling caused by the user (e.g. switching theme) doesn't seem |
- // to have this requirement. |
+ |
FrameTypeChanged(); |
return 0; |
} |
@@ -1417,11 +1377,6 @@ void HWNDMessageHandler::OnGetMinMaxInfo(MINMAXINFO* minmax_info) { |
CRect client_rect, window_rect; |
GetClientRect(hwnd(), &client_rect); |
GetWindowRect(hwnd(), &window_rect); |
- // Due to the client area bottom inset hack (detailed elsewhere), adjust |
- // the reported size of the client area in the case that the standard frame |
- // has been removed. |
- if (remove_standard_frame_) |
- client_rect.bottom += kClientAreaBottomInsetHack; |
window_rect -= client_rect; |
min_window_size.Enlarge(window_rect.Width(), window_rect.Height()); |
if (!max_window_size.IsEmpty()) |
@@ -2028,7 +1983,7 @@ void HWNDMessageHandler::OnSize(UINT param, const CSize& size) { |
RedrawWindow(hwnd(), NULL, NULL, RDW_INVALIDATE | RDW_ALLCHILDREN); |
// ResetWindowRegion is going to trigger WM_NCPAINT. By doing it after we've |
// invoked OnSize we ensure the RootView has been laid out. |
- ResetWindowRegion(false); |
+ ResetWindowRegion(false, true); |
} |
void HWNDMessageHandler::OnSysCommand(UINT notification_code, |