summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorben@chromium.org <ben@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-07-18 05:11:33 +0000
committerben@chromium.org <ben@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-07-18 05:11:33 +0000
commitfb5547bb8b94a50560e6ea44f51872b6f47e8b0e (patch)
treec5cc3aedc040929087543685b48e41c0425a5ccf
parenta564815aed4c8bd1e2c187f9024320f8bb3d3379 (diff)
downloadchromium_src-fb5547bb8b94a50560e6ea44f51872b6f47e8b0e.zip
chromium_src-fb5547bb8b94a50560e6ea44f51872b6f47e8b0e.tar.gz
chromium_src-fb5547bb8b94a50560e6ea44f51872b6f47e8b0e.tar.bz2
Fix frame turning black when reseting theme. Also simplifies the frame
type changed code somewhat. It turns out the frame still needs to be hidden for WM_DWMCOMPOSITIONCHANGED message handlers however. Not sure why, but this is the simplest/least buggy this code has been so far so I can live with it. http://crbug.com/14578 TEST=see bug Review URL: http://codereview.chromium.org/159050 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@21045 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/browser/views/frame/browser_frame_win.cc22
-rw-r--r--chrome/browser/views/frame/browser_view.cc2
-rw-r--r--views/window/window_win.cc59
3 files changed, 37 insertions, 46 deletions
diff --git a/chrome/browser/views/frame/browser_frame_win.cc b/chrome/browser/views/frame/browser_frame_win.cc
index 206f05f..7fd9702 100644
--- a/chrome/browser/views/frame/browser_frame_win.cc
+++ b/chrome/browser/views/frame/browser_frame_win.cc
@@ -174,16 +174,6 @@ LRESULT BrowserFrameWin::OnNCActivate(BOOL active) {
if (browser_view_->ActivateAppModalDialog())
return TRUE;
- // Perform first time initialization of the DWM frame insets, only if we're
- // using the native frame.
- if (GetNonClientView()->UseNativeFrame() && !frame_initialized_) {
- if (browser_view_->IsBrowserTypeNormal()) {
- ::SetWindowPos(GetNativeView(), NULL, 0, 0, 0, 0,
- SWP_NOSIZE | SWP_NOMOVE | SWP_FRAMECHANGED);
- UpdateDWMFrame();
- }
- frame_initialized_ = true;
- }
browser_view_->ActivationChanged(!!active);
return WindowWin::OnNCActivate(active);
}
@@ -235,8 +225,6 @@ LRESULT BrowserFrameWin::OnNCCalcSize(BOOL mode, LPARAM l_param) {
client_rect->right -= border_thickness;
client_rect->bottom -= border_thickness;
- UpdateDWMFrame();
-
// We'd like to return WVR_REDRAW in some cases here, but because we almost
// always have nonclient area (except in fullscreen mode, where it doesn't
// matter), we can't. See comments in window.cc:OnNCCalcSize() for more info.
@@ -296,6 +284,8 @@ void BrowserFrameWin::OnWindowPosChanged(WINDOWPOS* window_pos) {
GetNonClientView()->SchedulePaint();
}
+ UpdateDWMFrame();
+
// Let the default window procedure handle - IMPORTANT!
WindowWin::OnWindowPosChanged(window_pos);
}
@@ -349,6 +339,14 @@ void BrowserFrameWin::UpdateDWMFrame() {
margins.cyTopHeight =
GetBoundsForTabStrip(browser_view_->tabstrip()).bottom();
}
+
+ // If DWM is supported, we may still not want to use the DWM frame if we're in
+ // opaque mode (e.g. showing a theme). In this case we want to reset the DWM
+ // frame extending.
+ if (!GetNonClientView()->UseNativeFrame()) {
+ margins.cxLeftWidth = margins.cxRightWidth = margins.cyTopHeight =
+ margins.cyBottomHeight = 0;
+ }
DwmExtendFrameIntoClientArea(GetNativeView(), &margins);
}
diff --git a/chrome/browser/views/frame/browser_view.cc b/chrome/browser/views/frame/browser_view.cc
index 3ba3b5e..9df6216 100644
--- a/chrome/browser/views/frame/browser_view.cc
+++ b/chrome/browser/views/frame/browser_view.cc
@@ -956,8 +956,6 @@ void BrowserView::ContinueDraggingDetachedTab(const gfx::Rect& tab_bounds) {
void BrowserView::UserChangedTheme() {
frame_->GetWindow()->FrameTypeChanged();
- GetRootView()->ThemeChanged();
- GetRootView()->SchedulePaint();
}
int BrowserView::GetExtraRenderViewHeight() const {
diff --git a/views/window/window_win.cc b/views/window/window_win.cc
index 03d3952..2cf833e 100644
--- a/views/window/window_win.cc
+++ b/views/window/window_win.cc
@@ -4,6 +4,7 @@
#include "views/window/window_win.h"
+#include <dwmapi.h>
#include <shellapi.h>
#include "app/gfx/canvas_paint.h"
@@ -189,40 +190,24 @@ static BOOL CALLBACK SendDwmCompositionChanged(HWND window, LPARAM param) {
} // namespace
void WindowWin::FrameTypeChanged() {
- // If we're not on Aero Glass, we don't care about doing any of the DWM stuff.
- // Just tell the NCV to update and leave it there.
- if (!win_util::ShouldUseVistaFrame()) {
- non_client_view_->UpdateFrame();
- return;
- }
-
- // The window may try to paint in SetUseNativeFrame, and as a result it can
- // get into a state where it is very unhappy with itself - rendering black
- // behind the entire client area. This is because for some reason the
- // SkPorterDuff::kClear_mode erase done in the RootView thinks the window is
- // still opaque. So, to work around this we hide the window as soon as we can
- // (now), saving off its placement so it can be properly restored once
- // everything has settled down.
- WINDOWPLACEMENT saved_window_placement;
- saved_window_placement.length = sizeof(WINDOWPLACEMENT);
- GetWindowPlacement(GetNativeView(), &saved_window_placement);
- Hide();
-
- // Important step: restore the window first, since our hiding hack doesn't
- // work for maximized windows! We tell the frame not to allow itself to be
- // made visible though, which removes the brief flicker.
- ++force_hidden_count_;
- ::ShowWindow(GetNativeView(), SW_RESTORE);
- --force_hidden_count_;
-
- // We respond to this in response to WM_DWMCOMPOSITIONCHANGED since that is
- // the only thing we care about - we don't actually respond to WM_THEMECHANGED
- // messages.
+ // Update the non-client view with the correct frame view for the active frame
+ // type.
non_client_view_->UpdateFrame();
- // Now that we've updated the frame, we'll want to restore our saved placement
- // since the display should have settled down and we can be properly rendered.
- SetWindowPlacement(GetNativeView(), &saved_window_placement);
+ // We need to toggle the rendering policy of the DWM/glass frame as we change
+ // from opaque to glass. The logic of these values seems inverted to me, but
+ // it works, so I'm not going to complain.
+ DWMNCRENDERINGPOLICY policy =
+ non_client_view_->UseNativeFrame() ? DWMNCRP_ENABLED
+ : DWMNCRP_DISABLED;
+ DwmSetWindowAttribute(GetNativeView(), DWMWA_NCRENDERING_POLICY,
+ &policy, sizeof(DWMNCRENDERINGPOLICY));
+
+ // Send a frame change notification, since the non-client metrics have
+ // changed.
+ SetWindowPos(NULL, 0, 0, 0, 0,
+ SWP_FRAMECHANGED | SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER |
+ SWP_NOOWNERZORDER | SWP_NOACTIVATE);
// 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
@@ -595,7 +580,17 @@ void WindowWin::OnDestroy() {
LRESULT WindowWin::OnDwmCompositionChanged(UINT msg, WPARAM w_param,
LPARAM l_param) {
+ // 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.
+ WINDOWPLACEMENT wp = {0};
+ GetWindowPlacement(GetNativeWindow(), &wp);
+ Hide();
FrameTypeChanged();
+ SetWindowPlacement(GetNativeWindow(), &wp);
return 0;
}