diff options
-rw-r--r-- | app/theme_provider.h | 4 | ||||
-rw-r--r-- | chrome/browser/browser_theme_provider.cc | 14 | ||||
-rw-r--r-- | chrome/browser/browser_theme_provider.h | 1 | ||||
-rw-r--r-- | chrome/browser/views/autocomplete/autocomplete_popup_contents_view.cc | 6 | ||||
-rw-r--r-- | chrome/browser/views/frame/browser_frame_win.cc | 2 | ||||
-rw-r--r-- | chrome/browser/views/frame/browser_view.cc | 2 | ||||
-rw-r--r-- | chrome/browser/views/tabs/tab_strip.cc | 2 | ||||
-rw-r--r-- | views/widget/default_theme_provider.cc | 12 | ||||
-rw-r--r-- | views/widget/default_theme_provider.h | 1 | ||||
-rw-r--r-- | views/widget/widget_win.cc | 2 | ||||
-rw-r--r-- | views/window/non_client_view.cc | 29 | ||||
-rw-r--r-- | views/window/non_client_view.h | 5 | ||||
-rw-r--r-- | views/window/window.h | 6 | ||||
-rw-r--r-- | views/window/window_win.cc | 92 | ||||
-rw-r--r-- | views/window/window_win.h | 5 |
15 files changed, 114 insertions, 69 deletions
diff --git a/app/theme_provider.h b/app/theme_provider.h index c01842c..132a121 100644 --- a/app/theme_provider.h +++ b/app/theme_provider.h @@ -34,6 +34,10 @@ class ThemeProvider { // Get the color specified by |id|. virtual SkColor GetColor(int id) = 0; + // Whether we should use the native system frame (typically Aero glass) or + // a custom frame. + virtual bool ShouldUseNativeFrame() = 0; + #if defined(OS_LINUX) && !defined(TOOLKIT_VIEWS) // Gets the GdkPixbuf with the specified |id|. Returns a pointer to a shared // instance of the GdkPixbuf. This shared GdkPixbuf is owned by the theme diff --git a/chrome/browser/browser_theme_provider.cc b/chrome/browser/browser_theme_provider.cc index f881ae7..80fa7f2 100644 --- a/chrome/browser/browser_theme_provider.cc +++ b/chrome/browser/browser_theme_provider.cc @@ -22,6 +22,10 @@ #include "skia/ext/skia_utils.h" #include "third_party/skia/include/core/SkBitmap.h" +#if defined(OS_WIN) +#include "app/win_util.h" +#endif + // Strings used by themes to identify colors for different parts of our UI. static const char* kColorFrame = "frame"; static const char* kColorFrameInactive = "frame_inactive"; @@ -216,6 +220,16 @@ SkColor BrowserThemeProvider::GetColor(int id) { return 0xffff0000; } +bool BrowserThemeProvider::ShouldUseNativeFrame() { + if (images_.find(IDR_THEME_FRAME) != images_.end()) + return false; +#if defined(OS_WIN) + return win_util::ShouldUseVistaFrame(); +#else + return false; +#endif +} + void BrowserThemeProvider::SetTheme(Extension* extension) { // Clear our image cache. FreeImages(); diff --git a/chrome/browser/browser_theme_provider.h b/chrome/browser/browser_theme_provider.h index c4138db..9565ad4 100644 --- a/chrome/browser/browser_theme_provider.h +++ b/chrome/browser/browser_theme_provider.h @@ -56,6 +56,7 @@ class BrowserThemeProvider : public base::RefCounted<BrowserThemeProvider>, // ThemeProvider implementation. virtual SkBitmap* GetBitmapNamed(int id); virtual SkColor GetColor(int id); + virtual bool ShouldUseNativeFrame(); #if defined(OS_LINUX) virtual GdkPixbuf* GetPixbufNamed(int id); #endif diff --git a/chrome/browser/views/autocomplete/autocomplete_popup_contents_view.cc b/chrome/browser/views/autocomplete/autocomplete_popup_contents_view.cc index 9443639..7ba39cc 100644 --- a/chrome/browser/views/autocomplete/autocomplete_popup_contents_view.cc +++ b/chrome/browser/views/autocomplete/autocomplete_popup_contents_view.cc @@ -14,7 +14,7 @@ #include "app/gfx/path.h" #include "app/l10n_util.h" #include "app/resource_bundle.h" -#include "app/win_util.h" +#include "app/theme_provider.h" #include "chrome/browser/autocomplete/autocomplete_edit_view_win.h" #include "chrome/browser/autocomplete/autocomplete_popup_model.h" #include "chrome/browser/views/autocomplete/autocomplete_popup_win.h" @@ -840,7 +840,7 @@ void AutocompletePopupContentsView::MakeContentsPath( void AutocompletePopupContentsView::UpdateBlurRegion() { // We only support background blurring on Vista with Aero-Glass enabled. - if (!win_util::ShouldUseVistaFrame() || !GetWidget()) + if (!GetThemeProvider()->ShouldUseNativeFrame() || !GetWidget()) return; // Provide a blurred background effect within the contents region of the @@ -868,7 +868,7 @@ void AutocompletePopupContentsView::MakeCanvasTransparent( gfx::Canvas* canvas) { // Allow the window blur effect to show through the popup background. SkPaint paint; - SkColor transparency = win_util::ShouldUseVistaFrame() ? + SkColor transparency = GetThemeProvider()->ShouldUseNativeFrame() ? kGlassPopupTransparency : kOpaquePopupTransparency; paint.setColor(SkColorSetARGB(transparency, 255, 255, 255)); paint.setPorterDuffXfermode(SkPorterDuff::kDstIn_Mode); diff --git a/chrome/browser/views/frame/browser_frame_win.cc b/chrome/browser/views/frame/browser_frame_win.cc index 505f28b..3e9d8d7 100644 --- a/chrome/browser/views/frame/browser_frame_win.cc +++ b/chrome/browser/views/frame/browser_frame_win.cc @@ -235,7 +235,7 @@ int BrowserFrameWin::GetShowState() const { } views::NonClientFrameView* BrowserFrameWin::CreateFrameViewForWindow() { - if (GetNonClientView()->UseNativeFrame()) + if (GetThemeProvider()->ShouldUseNativeFrame()) browser_frame_view_ = new GlassBrowserFrameView(this, browser_view_); else browser_frame_view_ = new OpaqueBrowserFrameView(this, browser_view_); diff --git a/chrome/browser/views/frame/browser_view.cc b/chrome/browser/views/frame/browser_view.cc index ac9201d..e7ffef4 100644 --- a/chrome/browser/views/frame/browser_view.cc +++ b/chrome/browser/views/frame/browser_view.cc @@ -880,7 +880,7 @@ void BrowserView::ShowHTMLDialog(HtmlDialogUIDelegate* delegate, } void BrowserView::UserChangedTheme() { - frame_->GetWindow()->GetNonClientView()->SetUseNativeFrame(false); + frame_->GetWindow()->FrameTypeChanged(); GetRootView()->ThemeChanged(); GetRootView()->SchedulePaint(); } diff --git a/chrome/browser/views/tabs/tab_strip.cc b/chrome/browser/views/tabs/tab_strip.cc index 47cc89d..1a2cf23 100644 --- a/chrome/browser/views/tabs/tab_strip.cc +++ b/chrome/browser/views/tabs/tab_strip.cc @@ -606,7 +606,7 @@ void TabStrip::PaintChildren(gfx::Canvas* canvas) { } } - if (GetWindow()->GetNonClientView()->UseNativeFrame()) { + if (GetThemeProvider()->ShouldUseNativeFrame()) { // Make sure unselected tabs are somewhat transparent. SkPaint paint; paint.setColor(SkColorSetARGB(200, 255, 255, 255)); diff --git a/views/widget/default_theme_provider.cc b/views/widget/default_theme_provider.cc index be348a9..d5b8e3d 100644 --- a/views/widget/default_theme_provider.cc +++ b/views/widget/default_theme_provider.cc @@ -6,6 +6,10 @@ #include "app/resource_bundle.h" +#if defined(OS_WIN) +#include "app/win_util.h" +#endif + namespace views { SkBitmap* DefaultThemeProvider::GetBitmapNamed(int id) { @@ -17,4 +21,12 @@ SkColor DefaultThemeProvider::GetColor(int id) { return 0xff0000ff; } +bool DefaultThemeProvider::ShouldUseNativeFrame() { +#if defined(OS_WIN) + return win_util::ShouldUseVistaFrame(); +#else + return false; +#endif +} + } // namespace views diff --git a/views/widget/default_theme_provider.h b/views/widget/default_theme_provider.h index 1060c8e..879034f 100644 --- a/views/widget/default_theme_provider.h +++ b/views/widget/default_theme_provider.h @@ -20,6 +20,7 @@ class DefaultThemeProvider : public ThemeProvider { // Overridden from ThemeProvider. virtual SkBitmap* GetBitmapNamed(int id); virtual SkColor GetColor(int id); + virtual bool ShouldUseNativeFrame(); private: DISALLOW_COPY_AND_ASSIGN(DefaultThemeProvider); diff --git a/views/widget/widget_win.cc b/views/widget/widget_win.cc index 2d4d3ac..adce4d9 100644 --- a/views/widget/widget_win.cc +++ b/views/widget/widget_win.cc @@ -202,7 +202,7 @@ void WidgetWin::Init(HWND parent, const gfx::Rect& bounds, // Windows special DWM window frame requires a special tooltip manager so // that window controls in Chrome windows don't flicker when you move your // mouse over them. See comment in aero_tooltip_manager.h. - if (win_util::ShouldUseVistaFrame()) { + if (GetThemeProvider()->ShouldUseNativeFrame()) { tooltip_manager_.reset(new AeroTooltipManager(this)); } else { tooltip_manager_.reset(new TooltipManagerWin(this)); diff --git a/views/window/non_client_view.cc b/views/window/non_client_view.cc index 923f85e..3edb614 100644 --- a/views/window/non_client_view.cc +++ b/views/window/non_client_view.cc @@ -4,15 +4,16 @@ #include "views/window/non_client_view.h" -#if defined(OS_WIN) -#include "app/win_util.h" -#endif +#include "app/theme_provider.h" #include "views/widget/root_view.h" #include "views/widget/widget.h" -#if defined(OS_LINUX) +#include "views/window/window.h" + +#if defined(OS_WIN) +#include "app/win_util.h" +#else #include "views/window/hit_test.h" #endif -#include "views/window/window.h" namespace views { @@ -31,12 +32,7 @@ static const int kClientViewIndex = 1; NonClientView::NonClientView(Window* frame) : frame_(frame), - client_view_(NULL), -#if defined(OS_WIN) - use_native_frame_(win_util::ShouldUseVistaFrame()) { -#else - use_native_frame_(false) { -#endif + client_view_(NULL) { } NonClientView::~NonClientView() { @@ -63,10 +59,7 @@ void NonClientView::WindowClosing() { client_view_->WindowClosing(); } -void NonClientView::SetUseNativeFrame(bool use_native_frame) { - if (use_native_frame == use_native_frame_) - return; - use_native_frame_ = use_native_frame; +void NonClientView::UpdateFrame() { SetFrameView(frame_->CreateFrameViewForWindow()); GetRootView()->ThemeChanged(); Layout(); @@ -76,9 +69,9 @@ void NonClientView::SetUseNativeFrame(bool use_native_frame) { bool NonClientView::UseNativeFrame() const { // The frame view may always require a custom frame, e.g. Constrained Windows. - bool always_use_custom_frame = - frame_view_.get() && frame_view_->AlwaysUseCustomFrame(); - return !always_use_custom_frame && use_native_frame_; + if (frame_view_.get() && frame_view_->AlwaysUseCustomFrame()) + return true; + return frame_->ShouldUseNativeFrame(); } void NonClientView::DisableInactiveRendering(bool disable) { diff --git a/views/window/non_client_view.h b/views/window/non_client_view.h index 847f604..6ac38ac 100644 --- a/views/window/non_client_view.h +++ b/views/window/non_client_view.h @@ -139,7 +139,7 @@ class NonClientView : public View { // Changes the frame from native to custom depending on the value of // |use_native_frame|. - void SetUseNativeFrame(bool use_native_frame); + void UpdateFrame(); // Returns true if the native window frame should be used, false if the // NonClientView provides its own frame implementation. @@ -214,9 +214,6 @@ class NonClientView : public View { // dynamically as the system settings change. scoped_ptr<NonClientFrameView> frame_view_; - // Whether or not we should use the native frame. - bool use_native_frame_; - DISALLOW_COPY_AND_ASSIGN(NonClientView); }; diff --git a/views/window/window.h b/views/window/window.h index b5a1f56..e80ef98 100644 --- a/views/window/window.h +++ b/views/window/window.h @@ -143,6 +143,12 @@ class Window { // Retrieves the Window's native window handle. virtual gfx::NativeWindow GetNativeWindow() const = 0; + + // Whether we should be using a native frame. + virtual bool ShouldUseNativeFrame() const = 0; + + // Tell the window that something caused the frame type to change. + virtual void FrameTypeChanged() = 0; }; } // namespace views diff --git a/views/window/window_win.cc b/views/window/window_win.cc index 3e52871..3759851 100644 --- a/views/window/window_win.cc +++ b/views/window/window_win.cc @@ -12,6 +12,7 @@ #include "app/gfx/path.h" #include "app/l10n_util.h" #include "app/resource_bundle.h" +#include "app/theme_provider.h" #include "app/win_util.h" #include "base/win_util.h" #include "views/widget/root_view.h" @@ -182,6 +183,48 @@ void WindowWin::ExecuteSystemMenuCommand(int command) { SendMessage(GetNativeView(), WM_SYSCOMMAND, command, 0); } +namespace { +static BOOL CALLBACK SendDwmCompositionChanged(HWND window, LPARAM param) { + SendMessage(window, WM_DWMCOMPOSITIONCHANGED, 0, 0); + return TRUE; +} +} // namespace + +void WindowWin::FrameTypeChanged() { + // 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. + 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); + + // 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. + EnumChildWindows(GetNativeView(), &SendDwmCompositionChanged, NULL); +} + // static int Window::GetLocalizedContentsWidth(int col_resource_id) { double chars = _wtof(l10n_util::GetString(col_resource_id).c_str()); @@ -408,7 +451,7 @@ void WindowWin::SetIsAlwaysOnTop(bool always_on_top) { } NonClientFrameView* WindowWin::CreateFrameViewForWindow() { - if (non_client_view_->UseNativeFrame()) + if (ShouldUseNativeFrame()) return new NativeFrameView(this); return new CustomFrameView(this); } @@ -434,6 +477,13 @@ gfx::NativeWindow WindowWin::GetNativeWindow() const { return GetNativeView(); } +bool WindowWin::ShouldUseNativeFrame() const { + ThemeProvider* tp = GetThemeProvider(); + if (!tp) + return win_util::ShouldUseVistaFrame(); + return tp->ShouldUseNativeFrame(); +} + /////////////////////////////////////////////////////////////////////////////// // WindowWin, protected: @@ -564,47 +614,9 @@ void WindowWin::OnDestroy() { WidgetWin::OnDestroy(); } -namespace { -static BOOL CALLBACK SendDwmCompositionChanged(HWND window, LPARAM param) { - SendMessage(window, WM_DWMCOMPOSITIONCHANGED, 0, 0); - return TRUE; -} -} // namespace - LRESULT WindowWin::OnDwmCompositionChanged(UINT msg, WPARAM w_param, LPARAM l_param) { - // 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. - non_client_view_->SetUseNativeFrame(win_util::ShouldUseVistaFrame()); - - // 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); - - // 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. - EnumChildWindows(GetNativeView(), &SendDwmCompositionChanged, NULL); + FrameTypeChanged(); return 0; } diff --git a/views/window/window_win.h b/views/window/window_win.h index 5be2319..f799ae7 100644 --- a/views/window/window_win.h +++ b/views/window/window_win.h @@ -44,6 +44,10 @@ class WindowWin : public WidgetWin, // Executes the specified SC_command. void ExecuteSystemMenuCommand(int command); + // Called when the frame type could possibly be changing (theme change or + // DWM composition change). + void FrameTypeChanged(); + // Accessors and setters for various properties. HWND owning_window() const { return owning_hwnd_; } void set_focus_on_creation(bool focus_on_creation) { @@ -81,6 +85,7 @@ class WindowWin : public WidgetWin, virtual NonClientView* GetNonClientView() const; virtual ClientView* GetClientView() const; virtual gfx::NativeWindow GetNativeWindow() const; + virtual bool ShouldUseNativeFrame() const; protected: friend Window; |