summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorben@chromium.org <ben@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-03-03 00:28:00 +0000
committerben@chromium.org <ben@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-03-03 00:28:00 +0000
commit32670b07a6c42634f446e3d471f42a9fb40090f2 (patch)
tree77b15435f3a436d54fcaa5cb4c0d4371a007fad6
parenta0e5688cc11f7f5e835b5c1a75c17ce4a28a1527 (diff)
downloadchromium_src-32670b07a6c42634f446e3d471f42a9fb40090f2.zip
chromium_src-32670b07a6c42634f446e3d471f42a9fb40090f2.tar.gz
chromium_src-32670b07a6c42634f446e3d471f42a9fb40090f2.tar.bz2
Support DWM switching.
This completes the collapsing of window types and browser frames around a single class: views::Window. CustomFrameWindow is removed with this change. The Browser window is represented by a single views::Window subclass: BrowserFrame, which replaces both AeroGlassFrame and OpaqueFrame. NonClientView is now a container of two sibling classes - the Window's ClientView (in the Browser's case, BrowserView), and a NonClientFrameView subclass, which provides the rendering for the non-client portions of the window. These Views are siblings rather than the ClientView a child of the NonClientFrameView because when the DWM is toggled, the ClientView would have to be re-parented. Many Views make the assumption they are only inserted into a View hierarchy once, and so this is problematic. By having the views be siblings, this is avoided. With this in mind, all of the former NonClientViews now become NonClientFrameView subclasses: DefaultNonClientView -> CustomFrameView (non-existent, NonClientView) -> NativeFrameView AeroGlassNonClientView -> GlassBrowserFrameView OpaqueNonClientView -> OpaqueBrowserFrameView The latter two derive from NonClientFrameView via BrowserNonClientFrameView, which adds some extras. I also had to modify the TabRenderer class to know how to drop its cache of tab background images when the theme changes since it uses different ones for Glass and non-Glass. This change also fixes a few non-client flicker issues relating to window non-client activation by using more ScopedRedrawLocks. (Touches info_bubble.cc, window.cc) Bugs fixed: http://crbug.com/153 http://crbug.com/747 http://crbug.com/2371 http://crbug.com/3264 http://crbug.com/8234 Plumbing for http://crbug.com/8247 Design docs: http://dev.chromium.org/developers/design-documents/views-windowing http://dev.chromium.org/developers/design-documents/browser-window Review URL: http://codereview.chromium.org/27317 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@10757 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/browser/browser_focus_uitest.cc2
-rw-r--r--chrome/browser/views/browser_views.vcproj26
-rw-r--r--chrome/browser/views/constrained_window_impl.cc183
-rw-r--r--chrome/browser/views/constrained_window_impl.h17
-rw-r--r--chrome/browser/views/frame/aero_glass_frame.cc243
-rw-r--r--chrome/browser/views/frame/aero_glass_frame.h95
-rw-r--r--chrome/browser/views/frame/browser_frame.cc191
-rw-r--r--chrome/browser/views/frame/browser_frame.h108
-rw-r--r--chrome/browser/views/frame/browser_view.cc70
-rw-r--r--chrome/browser/views/frame/browser_window_factory.cc50
-rw-r--r--chrome/browser/views/frame/glass_browser_frame_view.cc (renamed from chrome/browser/views/frame/aero_glass_non_client_view.cc)200
-rw-r--r--chrome/browser/views/frame/glass_browser_frame_view.h (renamed from chrome/browser/views/frame/aero_glass_non_client_view.h)70
-rw-r--r--chrome/browser/views/frame/opaque_browser_frame_view.cc (renamed from chrome/browser/views/frame/opaque_non_client_view.cc)170
-rw-r--r--chrome/browser/views/frame/opaque_browser_frame_view.h (renamed from chrome/browser/views/frame/opaque_non_client_view.h)51
-rw-r--r--chrome/browser/views/frame/opaque_frame.cc139
-rw-r--r--chrome/browser/views/frame/opaque_frame.h74
-rw-r--r--chrome/browser/views/hung_renderer_view.cc2
-rw-r--r--chrome/browser/views/info_bubble.cc3
-rw-r--r--chrome/browser/views/tabs/tab_renderer.cc54
-rw-r--r--chrome/browser/views/tabs/tab_renderer.h4
-rw-r--r--chrome/browser/views/tabs/tab_strip.cc3
-rw-r--r--chrome/browser/views/toolbar_view.cc12
-rw-r--r--chrome/browser/views/toolbar_view.h2
-rw-r--r--chrome/views/custom_frame_view.cc (renamed from chrome/views/default_non_client_view.cc)167
-rw-r--r--chrome/views/custom_frame_view.h (renamed from chrome/views/default_non_client_view.h)47
-rw-r--r--chrome/views/custom_frame_window.cc506
-rw-r--r--chrome/views/custom_frame_window.h103
-rw-r--r--chrome/views/native_frame_view.cc61
-rw-r--r--chrome/views/native_frame_view.h38
-rw-r--r--chrome/views/non_client_view.cc135
-rw-r--r--chrome/views/non_client_view.h186
-rw-r--r--chrome/views/root_view.cc4
-rw-r--r--chrome/views/root_view.h4
-rw-r--r--chrome/views/view.cc6
-rw-r--r--chrome/views/view.h8
-rw-r--r--chrome/views/views.vcproj20
-rw-r--r--chrome/views/widget.h8
-rw-r--r--chrome/views/widget_win.cc2
-rw-r--r--chrome/views/widget_win.h19
-rw-r--r--chrome/views/window.cc159
-rw-r--r--chrome/views/window.h76
41 files changed, 1375 insertions, 1943 deletions
diff --git a/chrome/browser/browser_focus_uitest.cc b/chrome/browser/browser_focus_uitest.cc
index 6ff0f35..d920a012 100644
--- a/chrome/browser/browser_focus_uitest.cc
+++ b/chrome/browser/browser_focus_uitest.cc
@@ -245,7 +245,7 @@ IN_PROC_BROWSER_TEST_F(BrowserFocusTest, BackgroundBrowserDontStealFocus) {
HWND hwnd = reinterpret_cast<HWND>(browser()->window()->GetNativeHandle());
BrowserView* browser_view = BrowserView::GetBrowserViewForHWND(hwnd);
ASSERT_TRUE(browser_view);
- EXPECT_TRUE(browser_view->frame()->GetWindow()->IsActive());
+ EXPECT_TRUE(browser_view->frame()->IsActive());
// Close the 2nd browser to avoid a DCHECK().
HWND hwnd2 = reinterpret_cast<HWND>(browser2->window()->GetNativeHandle());
diff --git a/chrome/browser/views/browser_views.vcproj b/chrome/browser/views/browser_views.vcproj
index 92d345d..41b7bb1 100644
--- a/chrome/browser/views/browser_views.vcproj
+++ b/chrome/browser/views/browser_views.vcproj
@@ -125,19 +125,7 @@
Name="Frame"
>
<File
- RelativePath=".\frame\aero_glass_frame.cc"
- >
- </File>
- <File
- RelativePath=".\frame\aero_glass_frame.h"
- >
- </File>
- <File
- RelativePath=".\frame\aero_glass_non_client_view.cc"
- >
- </File>
- <File
- RelativePath=".\frame\aero_glass_non_client_view.h"
+ RelativePath=".\frame\browser_frame.cc"
>
</File>
<File
@@ -153,23 +141,19 @@
>
</File>
<File
- RelativePath=".\frame\browser_window_factory.cc"
- >
- </File>
- <File
- RelativePath=".\frame\opaque_frame.cc"
+ RelativePath=".\frame\glass_browser_frame_view.cc"
>
</File>
<File
- RelativePath=".\frame\opaque_frame.h"
+ RelativePath=".\frame\glass_browser_frame_view.h"
>
</File>
<File
- RelativePath=".\frame\opaque_non_client_view.cc"
+ RelativePath=".\frame\opaque_browser_frame_view.cc"
>
</File>
<File
- RelativePath=".\frame\opaque_non_client_view.h"
+ RelativePath=".\frame\opaque_browser_frame_view.h"
>
</File>
</Filter>
diff --git a/chrome/browser/views/constrained_window_impl.cc b/chrome/browser/views/constrained_window_impl.cc
index 8b57d18..8005457 100644
--- a/chrome/browser/views/constrained_window_impl.cc
+++ b/chrome/browser/views/constrained_window_impl.cc
@@ -184,22 +184,22 @@ SkBitmap* VistaWindowResources::bitmaps_[];
SkBitmap* OTRWindowResources::bitmaps_[];
////////////////////////////////////////////////////////////////////////////////
-// ConstrainedWindowNonClientView
+// ConstrainedWindowFrameView
-class ConstrainedWindowNonClientView
- : public views::NonClientView,
+class ConstrainedWindowFrameView
+ : public views::NonClientFrameView,
public views::BaseButton::ButtonListener {
public:
- ConstrainedWindowNonClientView(ConstrainedWindowImpl* container,
- TabContents* owner);
- virtual ~ConstrainedWindowNonClientView();
+ explicit ConstrainedWindowFrameView(ConstrainedWindowImpl* container);
+ virtual ~ConstrainedWindowFrameView();
void UpdateWindowTitle();
- // Overridden from views::NonClientView:
- virtual gfx::Rect CalculateClientAreaBounds(int width, int height) const;
- virtual gfx::Size CalculateWindowSizeForClientSize(int width,
- int height) const;
+ // Overridden from views::NonClientFrameView:
+ virtual gfx::Rect GetBoundsForClientView() const;
+ virtual bool AlwaysUseCustomFrame() const;
+ virtual gfx::Rect GetWindowBoundsForClientBounds(
+ const gfx::Rect& client_bounds) const;
virtual gfx::Point GetSystemMenuPoint() const;
virtual int NonClientHitTest(const gfx::Point& point);
virtual void GetWindowMask(const gfx::Size& size, gfx::Path* window_mask);
@@ -209,7 +209,7 @@ class ConstrainedWindowNonClientView
// Overridden from views::View:
virtual void Paint(ChromeCanvas* canvas);
virtual void Layout();
- virtual void ViewHierarchyChanged(bool is_add, View *parent, View *child);
+ virtual void ThemeChanged();
// Overridden from views::BaseButton::ButtonListener:
virtual void ButtonPressed(views::BaseButton* sender);
@@ -242,11 +242,17 @@ class ConstrainedWindowNonClientView
void LayoutTitleBar();
void LayoutClientView();
+ // Returns the bounds of the client area for the specified view size.
+ gfx::Rect CalculateClientAreaBounds(int width, int height) const;
+
SkColor GetTitleColor() const {
return (container_->owner()->profile()->IsOffTheRecord() ||
!win_util::ShouldUseVistaFrame()) ? SK_ColorWHITE : SK_ColorBLACK;
}
+ // Loads the appropriate set of WindowResources for the frame view.
+ void InitWindowResources();
+
ConstrainedWindowImpl* container_;
scoped_ptr<views::WindowResources> resources_;
@@ -255,15 +261,18 @@ class ConstrainedWindowNonClientView
views::Button* close_button_;
+ // The bounds of the ClientView.
+ gfx::Rect client_view_bounds_;
+
static void InitClass();
// The font to be used to render the titlebar text.
static ChromeFont title_font_;
- DISALLOW_EVIL_CONSTRUCTORS(ConstrainedWindowNonClientView);
+ DISALLOW_EVIL_CONSTRUCTORS(ConstrainedWindowFrameView);
};
-ChromeFont ConstrainedWindowNonClientView::title_font_;
+ChromeFont ConstrainedWindowFrameView::title_font_;
namespace {
// The frame border is only visible in restored mode and is hardcoded to 4 px on
@@ -294,23 +303,15 @@ const SkColor kContentsBorderColor = SkColorSetRGB(219, 235, 255);
}
////////////////////////////////////////////////////////////////////////////////
-// ConstrainedWindowNonClientView, public:
+// ConstrainedWindowFrameView, public:
-ConstrainedWindowNonClientView::ConstrainedWindowNonClientView(
- ConstrainedWindowImpl* container, TabContents* owner)
- : NonClientView(),
+ConstrainedWindowFrameView::ConstrainedWindowFrameView(
+ ConstrainedWindowImpl* container)
+ : NonClientFrameView(),
container_(container),
close_button_(new views::Button) {
InitClass();
- if (owner->profile()->IsOffTheRecord()) {
- resources_.reset(new OTRWindowResources);
- } else {
- if (win_util::ShouldUseVistaFrame()) {
- resources_.reset(new VistaWindowResources);
- } else {
- resources_.reset(new XPWindowResources);
- }
- }
+ InitWindowResources();
close_button_->SetImage(views::Button::BS_NORMAL,
resources_->GetPartBitmap(FRAME_CLOSE_BUTTON_ICON));
@@ -324,35 +325,37 @@ ConstrainedWindowNonClientView::ConstrainedWindowNonClientView(
AddChildView(close_button_);
}
-ConstrainedWindowNonClientView::~ConstrainedWindowNonClientView() {
+ConstrainedWindowFrameView::~ConstrainedWindowFrameView() {
}
-void ConstrainedWindowNonClientView::UpdateWindowTitle() {
+void ConstrainedWindowFrameView::UpdateWindowTitle() {
SchedulePaint(title_bounds_, false);
}
////////////////////////////////////////////////////////////////////////////////
-// ConstrainedWindowNonClientView, views::NonClientView implementation:
+// ConstrainedWindowFrameView, views::NonClientFrameView implementation:
-gfx::Rect ConstrainedWindowNonClientView::CalculateClientAreaBounds(
- int width,
- int height) const {
- int top_height = NonClientTopBorderHeight();
- int border_thickness = NonClientBorderThickness();
- return gfx::Rect(border_thickness, top_height,
- std::max(0, width - (2 * border_thickness)),
- std::max(0, height - top_height - border_thickness));
+gfx::Rect ConstrainedWindowFrameView::GetBoundsForClientView() const {
+ return client_view_bounds_;
}
-gfx::Size ConstrainedWindowNonClientView::CalculateWindowSizeForClientSize(
- int width,
- int height) const {
+bool ConstrainedWindowFrameView::AlwaysUseCustomFrame() const {
+ // Constrained windows always use the custom frame - they just have a
+ // different set of bitmaps.
+ return true;
+}
+
+gfx::Rect ConstrainedWindowFrameView::GetWindowBoundsForClientBounds(
+ const gfx::Rect& client_bounds) const {
+ int top_height = NonClientTopBorderHeight();
int border_thickness = NonClientBorderThickness();
- return gfx::Size(width + (2 * border_thickness),
- height + NonClientTopBorderHeight() + border_thickness);
+ return gfx::Rect(std::max(0, client_bounds.x() - border_thickness),
+ std::max(0, client_bounds.y() - top_height),
+ client_bounds.width() + (2 * border_thickness),
+ client_bounds.height() + top_height + border_thickness);
}
-gfx::Point ConstrainedWindowNonClientView::GetSystemMenuPoint() const {
+gfx::Point ConstrainedWindowFrameView::GetSystemMenuPoint() const {
// Doesn't really matter, since we never show system menus on constrained
// windows...
gfx::Point system_menu_point(FrameBorderThickness(),
@@ -361,7 +364,7 @@ gfx::Point ConstrainedWindowNonClientView::GetSystemMenuPoint() const {
return system_menu_point;
}
-int ConstrainedWindowNonClientView::NonClientHitTest(const gfx::Point& point) {
+int ConstrainedWindowFrameView::NonClientHitTest(const gfx::Point& point) {
if (!bounds().Contains(point))
return HTNOWHERE;
@@ -380,8 +383,8 @@ int ConstrainedWindowNonClientView::NonClientHitTest(const gfx::Point& point) {
return (window_component == HTNOWHERE) ? HTCAPTION : window_component;
}
-void ConstrainedWindowNonClientView::GetWindowMask(const gfx::Size& size,
- gfx::Path* window_mask) {
+void ConstrainedWindowFrameView::GetWindowMask(const gfx::Size& size,
+ gfx::Path* window_mask) {
DCHECK(window_mask);
// Redefine the window visible region for the new size.
@@ -403,60 +406,55 @@ void ConstrainedWindowNonClientView::GetWindowMask(const gfx::Size& size,
window_mask->close();
}
-void ConstrainedWindowNonClientView::EnableClose(bool enable) {
+void ConstrainedWindowFrameView::EnableClose(bool enable) {
close_button_->SetEnabled(enable);
}
////////////////////////////////////////////////////////////////////////////////
-// ConstrainedWindowNonClientView, views::View implementation:
+// ConstrainedWindowFrameView, views::View implementation:
-void ConstrainedWindowNonClientView::Paint(ChromeCanvas* canvas) {
+void ConstrainedWindowFrameView::Paint(ChromeCanvas* canvas) {
PaintFrameBorder(canvas);
PaintTitleBar(canvas);
PaintClientEdge(canvas);
}
-void ConstrainedWindowNonClientView::Layout() {
+void ConstrainedWindowFrameView::Layout() {
LayoutWindowControls();
LayoutTitleBar();
LayoutClientView();
}
-void ConstrainedWindowNonClientView::ViewHierarchyChanged(bool is_add,
- View *parent,
- View *child) {
- // Add our Client View as we are added to the Container so that if we are
- // subsequently resized all the parent-child relationships are established.
- if (is_add && GetWidget() && child == this)
- AddChildView(container_->client_view());
+void ConstrainedWindowFrameView::ThemeChanged() {
+ InitWindowResources();
}
////////////////////////////////////////////////////////////////////////////////
-// ConstrainedWindowNonClientView, views::BaseButton::Button
+// ConstrainedWindowFrameView, views::BaseButton::Button
// implementation:
-void ConstrainedWindowNonClientView::ButtonPressed(views::BaseButton* sender) {
+void ConstrainedWindowFrameView::ButtonPressed(views::BaseButton* sender) {
if (sender == close_button_)
container_->ExecuteSystemMenuCommand(SC_CLOSE);
}
////////////////////////////////////////////////////////////////////////////////
-// ConstrainedWindowNonClientView, private:
+// ConstrainedWindowFrameView, private:
-int ConstrainedWindowNonClientView::FrameBorderThickness() const {
+int ConstrainedWindowFrameView::FrameBorderThickness() const {
return kFrameBorderThickness;
}
-int ConstrainedWindowNonClientView::NonClientBorderThickness() const {
+int ConstrainedWindowFrameView::NonClientBorderThickness() const {
return FrameBorderThickness() + kClientEdgeThickness;
}
-int ConstrainedWindowNonClientView::NonClientTopBorderHeight() const {
+int ConstrainedWindowFrameView::NonClientTopBorderHeight() const {
int title_top_spacing, title_thickness;
return TitleCoordinates(&title_top_spacing, &title_thickness);
}
-int ConstrainedWindowNonClientView::TitleCoordinates(
+int ConstrainedWindowFrameView::TitleCoordinates(
int* title_top_spacing,
int* title_thickness) const {
int frame_thickness = FrameBorderThickness();
@@ -470,7 +468,7 @@ int ConstrainedWindowNonClientView::TitleCoordinates(
return *title_top_spacing + *title_thickness + title_bottom_spacing;
}
-void ConstrainedWindowNonClientView::PaintFrameBorder(ChromeCanvas* canvas) {
+void ConstrainedWindowFrameView::PaintFrameBorder(ChromeCanvas* canvas) {
SkBitmap* top_left_corner = resources_->GetPartBitmap(FRAME_TOP_LEFT_CORNER);
SkBitmap* top_right_corner =
resources_->GetPartBitmap(FRAME_TOP_RIGHT_CORNER);
@@ -514,13 +512,13 @@ void ConstrainedWindowNonClientView::PaintFrameBorder(ChromeCanvas* canvas) {
height() - top_left_corner->height() - bottom_left_corner->height());
}
-void ConstrainedWindowNonClientView::PaintTitleBar(ChromeCanvas* canvas) {
+void ConstrainedWindowFrameView::PaintTitleBar(ChromeCanvas* canvas) {
canvas->DrawStringInt(container_->GetWindowTitle(), title_font_,
GetTitleColor(), MirroredLeftPointForRect(title_bounds_),
title_bounds_.y(), title_bounds_.width(), title_bounds_.height());
}
-void ConstrainedWindowNonClientView::PaintClientEdge(ChromeCanvas* canvas) {
+void ConstrainedWindowFrameView::PaintClientEdge(ChromeCanvas* canvas) {
gfx::Rect client_edge_bounds(CalculateClientAreaBounds(width(), height()));
client_edge_bounds.Inset(-kClientEdgeThickness, -kClientEdgeThickness);
gfx::Rect frame_shadow_bounds(client_edge_bounds);
@@ -535,7 +533,7 @@ void ConstrainedWindowNonClientView::PaintClientEdge(ChromeCanvas* canvas) {
client_edge_bounds.height());
}
-void ConstrainedWindowNonClientView::LayoutWindowControls() {
+void ConstrainedWindowFrameView::LayoutWindowControls() {
gfx::Size close_button_size = close_button_->GetPreferredSize();
close_button_->SetBounds(
width() - close_button_size.width() - FrameBorderThickness(),
@@ -543,7 +541,7 @@ void ConstrainedWindowNonClientView::LayoutWindowControls() {
close_button_size.height());
}
-void ConstrainedWindowNonClientView::LayoutTitleBar() {
+void ConstrainedWindowFrameView::LayoutTitleBar() {
// Size the title.
int title_x = FrameBorderThickness() + kIconLeftSpacing;
int title_top_spacing, title_thickness;
@@ -554,13 +552,34 @@ void ConstrainedWindowNonClientView::LayoutTitleBar() {
title_font_.height());
}
-void ConstrainedWindowNonClientView::LayoutClientView() {
- container_->client_view()->SetBounds(CalculateClientAreaBounds(width(),
- height()));
+void ConstrainedWindowFrameView::LayoutClientView() {
+ client_view_bounds_ = CalculateClientAreaBounds(width(), height());
+}
+
+gfx::Rect ConstrainedWindowFrameView::CalculateClientAreaBounds(
+ int width,
+ int height) const {
+ int top_height = NonClientTopBorderHeight();
+ int border_thickness = NonClientBorderThickness();
+ return gfx::Rect(border_thickness, top_height,
+ std::max(0, width - (2 * border_thickness)),
+ std::max(0, height - top_height - border_thickness));
+}
+
+void ConstrainedWindowFrameView::InitWindowResources() {
+ if (container_->owner()->profile()->IsOffTheRecord()) {
+ resources_.reset(new OTRWindowResources);
+ } else {
+ if (win_util::ShouldUseVistaFrame()) {
+ resources_.reset(new VistaWindowResources);
+ } else {
+ resources_.reset(new XPWindowResources);
+ }
+ }
}
// static
-void ConstrainedWindowNonClientView::InitClass() {
+void ConstrainedWindowFrameView::InitClass() {
static bool initialized = false;
if (!initialized) {
title_font_ = win_util::GetWindowTitleFont();
@@ -583,8 +602,8 @@ ConstrainedWindowImpl::~ConstrainedWindowImpl() {
////////////////////////////////////////////////////////////////////////////////
// ConstrainedWindowImpl, ConstrainedWindow implementation:
-ConstrainedWindowNonClientView* ConstrainedWindowImpl::non_client_view() {
- return static_cast<ConstrainedWindowNonClientView*>(non_client_view_);
+views::NonClientFrameView* ConstrainedWindowImpl::CreateFrameViewForWindow() {
+ return new ConstrainedWindowFrameView(this);
}
void ConstrainedWindowImpl::UpdateWindowTitle() {
@@ -652,13 +671,13 @@ const gfx::Rect& ConstrainedWindowImpl::GetCurrentBounds() const {
ConstrainedWindowImpl::ConstrainedWindowImpl(
TabContents* owner,
views::WindowDelegate* window_delegate)
- : CustomFrameWindow(window_delegate,
- new ConstrainedWindowNonClientView(this, owner)) {
- Init(owner);
+ : Window(window_delegate),
+ owner_(owner) {
+ non_client_view_->SetFrameView(CreateFrameViewForWindow());
+ Init();
}
-void ConstrainedWindowImpl::Init(TabContents* owner) {
- owner_ = owner;
+void ConstrainedWindowImpl::Init() {
focus_restoration_disabled_ = false;
set_window_style(WS_CHILD | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_CAPTION |
WS_THICKFRAME | WS_SYSMENU);
@@ -666,13 +685,13 @@ void ConstrainedWindowImpl::Init(TabContents* owner) {
}
void ConstrainedWindowImpl::InitAsDialog(const gfx::Rect& initial_bounds) {
- CustomFrameWindow::Init(owner_->GetNativeView(), initial_bounds);
+ Window::Init(owner_->GetNativeView(), initial_bounds);
ActivateConstrainedWindow();
}
void ConstrainedWindowImpl::UpdateUI(unsigned int changed_flags) {
if (changed_flags & TabContents::INVALIDATE_TITLE)
- non_client_view()->UpdateWindowTitle();
+ UpdateWindowTitle();
}
////////////////////////////////////////////////////////////////////////////////
diff --git a/chrome/browser/views/constrained_window_impl.h b/chrome/browser/views/constrained_window_impl.h
index 229555e..30e6303 100644
--- a/chrome/browser/views/constrained_window_impl.h
+++ b/chrome/browser/views/constrained_window_impl.h
@@ -8,11 +8,11 @@
#include "base/gfx/rect.h"
#include "chrome/browser/tab_contents/constrained_window.h"
#include "chrome/browser/tab_contents/tab_contents_delegate.h"
-#include "chrome/views/custom_frame_window.h"
+#include "chrome/views/window.h"
class ConstrainedTabContentsWindowDelegate;
class ConstrainedWindowAnimation;
-class ConstrainedWindowNonClientView;
+class ConstrainedWindowFrameView;
namespace views {
class HWNDView;
class WindowDelegate;
@@ -25,20 +25,15 @@ class WindowDelegate;
// a child HWND with a custom window frame.
//
class ConstrainedWindowImpl : public ConstrainedWindow,
- public views::CustomFrameWindow {
+ public views::Window {
public:
virtual ~ConstrainedWindowImpl();
// Returns the TabContents that constrains this Constrained Window.
TabContents* owner() const { return owner_; }
- // Returns the non-client view inside this Constrained Window.
- // NOTE: Defining the function body here would require pulling in the
- // declarations of ConstrainedWindowNonClientView, as well as all the classes
- // it depends on, from the .cc file; the benefit isn't worth it.
- ConstrainedWindowNonClientView* non_client_view();
-
- // Overridden from views::CustomFrameWindow:
+ // Overridden from views::Window:
+ virtual views::NonClientFrameView* CreateFrameViewForWindow();
virtual void UpdateWindowTitle();
// Overridden from ConstrainedWindow:
@@ -64,7 +59,7 @@ class ConstrainedWindowImpl : public ConstrainedWindow,
// ConstrainedWindow.
ConstrainedWindowImpl(TabContents* owner,
views::WindowDelegate* window_delegate);
- void Init(TabContents* owner);
+ void Init();
// Initialize the Constrained Window as a Constrained Dialog containing a
// views::View client area.
diff --git a/chrome/browser/views/frame/aero_glass_frame.cc b/chrome/browser/views/frame/aero_glass_frame.cc
deleted file mode 100644
index bc9b0f2..0000000
--- a/chrome/browser/views/frame/aero_glass_frame.cc
+++ /dev/null
@@ -1,243 +0,0 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/views/frame/aero_glass_frame.h"
-
-#include <dwmapi.h>
-
-#include "chrome/browser/browser_list.h"
-#include "chrome/browser/views/frame/browser_view.h"
-#include "chrome/browser/views/frame/aero_glass_non_client_view.h"
-#include "chrome/common/resource_bundle.h"
-#include "chrome/views/window_delegate.h"
-#include "grit/theme_resources.h"
-
-// static
-
-static const int kClientEdgeThickness = 3;
-
-HICON AeroGlassFrame::throbber_icons_[AeroGlassFrame::kThrobberIconCount];
-
-///////////////////////////////////////////////////////////////////////////////
-// AeroGlassFrame, public:
-
-AeroGlassFrame::AeroGlassFrame(BrowserView* browser_view)
- : Window(browser_view),
- browser_view_(browser_view),
- frame_initialized_(false),
- throbber_running_(false),
- throbber_frame_(0) {
- non_client_view_ = new AeroGlassNonClientView(this, browser_view);
- browser_view_->set_frame(this);
-
- if (window_delegate()->ShouldShowWindowIcon())
- InitThrobberIcons();
-}
-
-AeroGlassFrame::~AeroGlassFrame() {
-}
-
-void AeroGlassFrame::Init() {
- Window::Init(NULL, gfx::Rect());
-}
-
-int AeroGlassFrame::GetMinimizeButtonOffset() const {
- TITLEBARINFOEX titlebar_info;
- titlebar_info.cbSize = sizeof(TITLEBARINFOEX);
- SendMessage(GetHWND(), WM_GETTITLEBARINFOEX, 0, (WPARAM)&titlebar_info);
-
- CPoint minimize_button_corner(titlebar_info.rgrect[2].left,
- titlebar_info.rgrect[2].top);
- MapWindowPoints(HWND_DESKTOP, GetHWND(), &minimize_button_corner, 1);
-
- return minimize_button_corner.x;
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// AeroGlassFrame, BrowserFrame implementation:
-
-gfx::Rect AeroGlassFrame::GetWindowBoundsForClientBounds(
- const gfx::Rect& client_bounds) {
- RECT rect = client_bounds.ToRECT();
- AdjustWindowRectEx(&rect, window_style(), FALSE, window_ex_style());
- return gfx::Rect(rect);
-}
-
-gfx::Rect AeroGlassFrame::GetBoundsForTabStrip(TabStrip* tabstrip) const {
- return GetAeroGlassNonClientView()->GetBoundsForTabStrip(tabstrip);
-}
-
-void AeroGlassFrame::UpdateThrobber(bool running) {
- if (throbber_running_) {
- if (running) {
- DisplayNextThrobberFrame();
- } else {
- StopThrobber();
- }
- } else if (running) {
- StartThrobber();
- }
-}
-
-views::Window* AeroGlassFrame::GetWindow() {
- return this;
-}
-
-const views::Window* AeroGlassFrame::GetWindow() const {
- return this;
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// AeroGlassFrame, views::WidgetWin overrides:
-
-bool AeroGlassFrame::AcceleratorPressed(views::Accelerator* accelerator) {
- return browser_view_->AcceleratorPressed(*accelerator);
-}
-
-bool AeroGlassFrame::GetAccelerator(int cmd_id,
- views::Accelerator* accelerator) {
- return browser_view_->GetAccelerator(cmd_id, accelerator);
-}
-
-void AeroGlassFrame::OnInitMenuPopup(HMENU menu, UINT position,
- BOOL is_system_menu) {
- browser_view_->PrepareToRunSystemMenu(menu);
-}
-
-void AeroGlassFrame::OnEnterSizeMove() {
- browser_view_->WindowMoveOrResizeStarted();
-}
-
-void AeroGlassFrame::OnEndSession(BOOL ending, UINT logoff) {
- BrowserList::WindowsSessionEnding();
-}
-
-LRESULT AeroGlassFrame::OnMouseActivate(HWND window, UINT hittest_code,
- UINT message) {
- return browser_view_->ActivateAppModalDialog() ? MA_NOACTIVATEANDEAT
- : MA_ACTIVATE;
-}
-
-void AeroGlassFrame::OnMove(const CPoint& point) {
- browser_view_->WindowMoved();
-}
-
-void AeroGlassFrame::OnMoving(UINT param, const RECT* new_bounds) {
- browser_view_->WindowMoved();
-}
-
-LRESULT AeroGlassFrame::OnNCActivate(BOOL active) {
- if (browser_view_->ActivateAppModalDialog())
- return TRUE;
-
- if (!frame_initialized_) {
- if (browser_view_->IsBrowserTypeNormal()) {
- ::SetWindowPos(GetHWND(), NULL, 0, 0, 0, 0,
- SWP_NOSIZE | SWP_NOMOVE | SWP_FRAMECHANGED);
- UpdateDWMFrame();
- }
- frame_initialized_ = true;
- }
- browser_view_->ActivationChanged(!!active);
- SetMsgHandled(false);
- return TRUE;
-}
-
-LRESULT AeroGlassFrame::OnNCCalcSize(BOOL mode, LPARAM l_param) {
- if (!browser_view_->IsBrowserTypeNormal() || !mode) {
- SetMsgHandled(FALSE);
- return 0;
- }
-
- // In fullscreen mode, we make the whole window client area.
- if (!browser_view_->IsFullscreen()) {
- NCCALCSIZE_PARAMS* params = reinterpret_cast<NCCALCSIZE_PARAMS*>(l_param);
- int border_thickness = GetSystemMetrics(SM_CXSIZEFRAME);
- params->rgrc[0].left += (border_thickness - kClientEdgeThickness);
- params->rgrc[0].right -= (border_thickness - kClientEdgeThickness);
- params->rgrc[0].bottom -= (border_thickness - kClientEdgeThickness);
- }
-
- UpdateDWMFrame();
-
- SetMsgHandled(TRUE);
- return 0;
-}
-
-LRESULT AeroGlassFrame::OnNCHitTest(const CPoint& pt) {
- LRESULT result;
- if (DwmDefWindowProc(GetHWND(), WM_NCHITTEST, 0, MAKELPARAM(pt.x, pt.y),
- &result)) {
- return result;
- }
- return Window::OnNCHitTest(pt);
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// AeroGlassFrame, views::CustomFrameWindow overrides:
-
-int AeroGlassFrame::GetShowState() const {
- return browser_view_->GetShowState();
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// AeroGlassFrame, private:
-
-void AeroGlassFrame::UpdateDWMFrame() {
- // Nothing to do yet.
- if (!client_view())
- return;
-
- // In fullscreen mode, we don't extend glass into the client area at all,
- // because the GDI-drawn text in the web content composited over it will
- // become semi-transparent over any glass area.
- MARGINS margins = { 0 };
- if (!browser_view_->IsFullscreen()) {
- margins.cxLeftWidth = kClientEdgeThickness + 1;
- margins.cxRightWidth = kClientEdgeThickness + 1;
- margins.cyTopHeight =
- GetBoundsForTabStrip(browser_view_->tabstrip()).bottom();
- margins.cyBottomHeight = kClientEdgeThickness + 1;
- }
- DwmExtendFrameIntoClientArea(GetHWND(), &margins);
-}
-
-AeroGlassNonClientView* AeroGlassFrame::GetAeroGlassNonClientView() const {
- // We can safely assume that this conversion is true.
- return static_cast<AeroGlassNonClientView*>(non_client_view_);
-}
-
-void AeroGlassFrame::StartThrobber() {
- if (!throbber_running_) {
- throbber_running_ = true;
- throbber_frame_ = 0;
- InitThrobberIcons();
- ::SendMessage(GetHWND(), WM_SETICON, static_cast<WPARAM>(ICON_SMALL),
- reinterpret_cast<LPARAM>(throbber_icons_[throbber_frame_]));
- }
-}
-
-void AeroGlassFrame::StopThrobber() {
- if (throbber_running_)
- throbber_running_ = false;
-}
-
-void AeroGlassFrame::DisplayNextThrobberFrame() {
- throbber_frame_ = (throbber_frame_ + 1) % kThrobberIconCount;
- ::SendMessage(GetHWND(), WM_SETICON, static_cast<WPARAM>(ICON_SMALL),
- reinterpret_cast<LPARAM>(throbber_icons_[throbber_frame_]));
-}
-
-// static
-void AeroGlassFrame::InitThrobberIcons() {
- static bool initialized = false;
- if (!initialized) {
- ResourceBundle &rb = ResourceBundle::GetSharedInstance();
- for (int i = 0; i < kThrobberIconCount; ++i) {
- throbber_icons_[i] = rb.LoadThemeIcon(IDR_THROBBER_01 + i);
- DCHECK(throbber_icons_[i]);
- }
- initialized = true;
- }
-}
diff --git a/chrome/browser/views/frame/aero_glass_frame.h b/chrome/browser/views/frame/aero_glass_frame.h
deleted file mode 100644
index 4c7e2f8..0000000
--- a/chrome/browser/views/frame/aero_glass_frame.h
+++ /dev/null
@@ -1,95 +0,0 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROME_BROWSER_VIEWS_FRAME_AERO_GLASS_FRAME_H_
-#define CHROME_BROWSER_VIEWS_FRAME_AERO_GLASS_FRAME_H_
-
-#include "chrome/browser/views/frame/browser_frame.h"
-#include "chrome/views/window.h"
-
-class AeroGlassNonClientView;
-class BrowserView;
-
-///////////////////////////////////////////////////////////////////////////////
-// AeroGlassFrame
-//
-// AeroGlassFrame is a Window subclass that provides the window frame on
-// Windows Vista with DWM desktop compositing enabled. The window's non-client
-// areas are drawn by the system.
-//
-class AeroGlassFrame : public BrowserFrame,
- public views::Window {
- public:
- explicit AeroGlassFrame(BrowserView* browser_view);
- virtual ~AeroGlassFrame();
-
- void Init();
-
- // Determine the distance of the left edge of the minimize button from the
- // left edge of the window. Used in our Non-Client View's Layout.
- int GetMinimizeButtonOffset() const;
-
- // Overridden from BrowserFrame:
- virtual gfx::Rect GetWindowBoundsForClientBounds(
- const gfx::Rect& client_bounds);
- virtual void SizeToContents(const gfx::Rect& contents_bounds) {}
- virtual gfx::Rect GetBoundsForTabStrip(TabStrip* tabstrip) const;
- virtual void UpdateThrobber(bool running);
- virtual views::Window* GetWindow();
- virtual const views::Window* GetWindow() const;
-
- protected:
- // Overridden from views::WidgetWin:
- virtual bool AcceleratorPressed(views::Accelerator* accelerator);
- virtual bool GetAccelerator(int cmd_id, views::Accelerator* accelerator);
- virtual void OnInitMenuPopup(HMENU menu, UINT position, BOOL is_system_menu);
- virtual void OnEnterSizeMove();
- virtual void OnEndSession(BOOL ending, UINT logoff);
- virtual LRESULT OnMouseActivate(HWND window,
- UINT hittest_code,
- UINT message);
- virtual void OnMove(const CPoint& point);
- virtual void OnMoving(UINT param, const RECT* new_bounds);
- virtual LRESULT OnNCActivate(BOOL active);
- virtual LRESULT OnNCCalcSize(BOOL mode, LPARAM l_param);
- virtual LRESULT OnNCHitTest(const CPoint& pt);
-
- // Overridden from views::Window:
- virtual int GetShowState() const;
- virtual bool IsAppWindow() const { return true; }
-
- private:
- // Updates the DWM with the frame bounds.
- void UpdateDWMFrame();
-
- // Return a pointer to the concrete type of our non-client view.
- AeroGlassNonClientView* GetAeroGlassNonClientView() const;
-
- // Starts/Stops the window throbber running.
- void StartThrobber();
- void StopThrobber();
-
- // Displays the next throbber frame.
- void DisplayNextThrobberFrame();
-
- // The BrowserView is our ClientView. This is a pointer to it.
- BrowserView* browser_view_;
-
- bool frame_initialized_;
-
- // Whether or not the window throbber is currently animating.
- bool throbber_running_;
-
- // The index of the current frame of the throbber animation.
- int throbber_frame_;
-
- static const int kThrobberIconCount = 24;
- static HICON throbber_icons_[kThrobberIconCount];
- static void InitThrobberIcons();
-
- DISALLOW_EVIL_CONSTRUCTORS(AeroGlassFrame);
-};
-
-#endif // #ifndef CHROME_BROWSER_VIEWS_FRAME_AERO_GLASS_FRAME_H_
-
diff --git a/chrome/browser/views/frame/browser_frame.cc b/chrome/browser/views/frame/browser_frame.cc
new file mode 100644
index 0000000..ac7f2d5
--- /dev/null
+++ b/chrome/browser/views/frame/browser_frame.cc
@@ -0,0 +1,191 @@
+// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/views/frame/browser_frame.h"
+
+#include <dwmapi.h>
+
+#include "chrome/browser/browser_list.h"
+#include "chrome/browser/views/frame/browser_view.h"
+#include "chrome/browser/views/frame/glass_browser_frame_view.h"
+#include "chrome/browser/views/frame/opaque_browser_frame_view.h"
+#include "chrome/common/resource_bundle.h"
+#include "chrome/common/win_util.h"
+#include "chrome/views/window_delegate.h"
+#include "grit/theme_resources.h"
+
+// static
+static const int kClientEdgeThickness = 3;
+
+///////////////////////////////////////////////////////////////////////////////
+// BrowserFrame, public:
+
+BrowserFrame::BrowserFrame(BrowserView* browser_view)
+ : Window(browser_view),
+ browser_view_(browser_view),
+ frame_initialized_(false) {
+ browser_view_->set_frame(this);
+ non_client_view_->SetFrameView(CreateFrameViewForWindow());
+}
+
+BrowserFrame::~BrowserFrame() {
+}
+
+void BrowserFrame::Init() {
+ Window::Init(NULL, gfx::Rect());
+}
+
+int BrowserFrame::GetMinimizeButtonOffset() const {
+ TITLEBARINFOEX titlebar_info;
+ titlebar_info.cbSize = sizeof(TITLEBARINFOEX);
+ SendMessage(GetHWND(), WM_GETTITLEBARINFOEX, 0, (WPARAM)&titlebar_info);
+
+ CPoint minimize_button_corner(titlebar_info.rgrect[2].left,
+ titlebar_info.rgrect[2].top);
+ MapWindowPoints(HWND_DESKTOP, GetHWND(), &minimize_button_corner, 1);
+
+ return minimize_button_corner.x;
+}
+
+gfx::Rect BrowserFrame::GetBoundsForTabStrip(TabStrip* tabstrip) const {
+ return browser_frame_view_->GetBoundsForTabStrip(tabstrip);
+}
+
+void BrowserFrame::UpdateThrobber(bool running) {
+ browser_frame_view_->UpdateThrobber(running);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// BrowserFrame, views::WidgetWin overrides:
+
+bool BrowserFrame::AcceleratorPressed(views::Accelerator* accelerator) {
+ return browser_view_->AcceleratorPressed(*accelerator);
+}
+
+bool BrowserFrame::GetAccelerator(int cmd_id, views::Accelerator* accelerator) {
+ return browser_view_->GetAccelerator(cmd_id, accelerator);
+}
+
+void BrowserFrame::OnEndSession(BOOL ending, UINT logoff) {
+ BrowserList::WindowsSessionEnding();
+}
+
+void BrowserFrame::OnEnterSizeMove() {
+ browser_view_->WindowMoveOrResizeStarted();
+}
+
+void BrowserFrame::OnInitMenuPopup(HMENU menu, UINT position,
+ BOOL is_system_menu) {
+ browser_view_->PrepareToRunSystemMenu(menu);
+}
+
+LRESULT BrowserFrame::OnMouseActivate(HWND window, UINT hittest_code,
+ UINT message) {
+ return browser_view_->ActivateAppModalDialog() ? MA_NOACTIVATEANDEAT
+ : MA_ACTIVATE;
+}
+
+void BrowserFrame::OnMove(const CPoint& point) {
+ browser_view_->WindowMoved();
+}
+
+void BrowserFrame::OnMoving(UINT param, const RECT* new_bounds) {
+ browser_view_->WindowMoved();
+}
+
+LRESULT BrowserFrame::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 (non_client_view_->UseNativeFrame() && !frame_initialized_) {
+ if (browser_view_->IsBrowserTypeNormal()) {
+ ::SetWindowPos(GetHWND(), NULL, 0, 0, 0, 0,
+ SWP_NOSIZE | SWP_NOMOVE | SWP_FRAMECHANGED);
+ UpdateDWMFrame();
+ }
+ frame_initialized_ = true;
+ }
+ browser_view_->ActivationChanged(!!active);
+ return Window::OnNCActivate(active);
+}
+
+LRESULT BrowserFrame::OnNCCalcSize(BOOL mode, LPARAM l_param) {
+ // We don't adjust the client area unless we're a tabbed browser window and
+ // are using the native frame.
+ if (!non_client_view_->UseNativeFrame() ||
+ !browser_view_->IsBrowserTypeNormal() || !mode) {
+ return Window::OnNCCalcSize(mode, l_param);
+ }
+
+ // In fullscreen mode, we make the whole window client area.
+ if (!browser_view_->IsFullscreen()) {
+ NCCALCSIZE_PARAMS* params = reinterpret_cast<NCCALCSIZE_PARAMS*>(l_param);
+ int border_thickness = GetSystemMetrics(SM_CXSIZEFRAME);
+ params->rgrc[0].left += (border_thickness - kClientEdgeThickness);
+ params->rgrc[0].right -= (border_thickness - kClientEdgeThickness);
+ params->rgrc[0].bottom -= (border_thickness - kClientEdgeThickness);
+ }
+
+ UpdateDWMFrame();
+
+ SetMsgHandled(TRUE);
+ return 0;
+}
+
+LRESULT BrowserFrame::OnNCHitTest(const CPoint& pt) {
+ // Only do DWM hit-testing when we are using the native frame.
+ if (non_client_view_->UseNativeFrame()) {
+ LRESULT result;
+ if (DwmDefWindowProc(GetHWND(), WM_NCHITTEST, 0, MAKELPARAM(pt.x, pt.y),
+ &result)) {
+ return result;
+ }
+ }
+ return Window::OnNCHitTest(pt);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// BrowserFrame, views::CustomFrameWindow overrides:
+
+int BrowserFrame::GetShowState() const {
+ return browser_view_->GetShowState();
+}
+
+views::NonClientFrameView* BrowserFrame::CreateFrameViewForWindow() {
+ if (non_client_view_->UseNativeFrame())
+ browser_frame_view_ = new GlassBrowserFrameView(this, browser_view_);
+ else
+ browser_frame_view_ = new OpaqueBrowserFrameView(this, browser_view_);
+ return browser_frame_view_;
+}
+
+void BrowserFrame::UpdateFrameAfterFrameChange() {
+ Window::UpdateFrameAfterFrameChange();
+ UpdateDWMFrame();
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// BrowserFrame, private:
+
+void BrowserFrame::UpdateDWMFrame() {
+ // Nothing to do yet.
+ if (!client_view())
+ return;
+
+ // In fullscreen mode, we don't extend glass into the client area at all,
+ // because the GDI-drawn text in the web content composited over it will
+ // become semi-transparent over any glass area.
+ MARGINS margins = { 0 };
+ if (!browser_view_->IsFullscreen()) {
+ margins.cxLeftWidth = kClientEdgeThickness + 1;
+ margins.cxRightWidth = kClientEdgeThickness + 1;
+ margins.cyTopHeight =
+ GetBoundsForTabStrip(browser_view_->tabstrip()).bottom();
+ margins.cyBottomHeight = kClientEdgeThickness + 1;
+ }
+ DwmExtendFrameIntoClientArea(GetHWND(), &margins);
+}
+
diff --git a/chrome/browser/views/frame/browser_frame.h b/chrome/browser/views/frame/browser_frame.h
index ee908b5..c7efcab 100644
--- a/chrome/browser/views/frame/browser_frame.h
+++ b/chrome/browser/views/frame/browser_frame.h
@@ -2,63 +2,91 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef CHROME_BROWSER_VIEWS_FRAME_BROWSER_FRAME_H_
-#define CHROME_BROWSER_VIEWS_FRAME_BROWSER_FRAME_H_
+#ifndef CHROME_BROWSER_VIEWS_FRAME_BROWSER_FRAME_
+#define CHROME_BROWSER_VIEWS_FRAME_BROWSER_FRAME_
+#include "chrome/views/window.h"
+
+class AeroGlassNonClientView;
class BrowserView;
-namespace views {
-class Window;
-}
-namespace gfx {
-class Rect;
-}
+class NonClientFrameView;
class TabStrip;
+// A specialization of the NonClientFrameView object that provides additional
+// Browser-specific methods.
+class BrowserNonClientFrameView : public views::NonClientFrameView {
+ public:
+ BrowserNonClientFrameView() : NonClientFrameView() {}
+ virtual ~BrowserNonClientFrameView() {}
+
+ // Returns the bounds within which the TabStrip should be laid out.
+ virtual gfx::Rect GetBoundsForTabStrip(TabStrip* tabstrip) const = 0;
+
+ // Updates the throbber.
+ virtual void UpdateThrobber(bool running) = 0;
+};
+
///////////////////////////////////////////////////////////////////////////////
// BrowserFrame
//
-// BrowserFrame is an interface that represents a top level browser window
-// frame. Implementations of this interface exist to supply the browser window
-// for specific environments, e.g. Vista with Aero Glass enabled.
+// BrowserFrame is a Window subclass that provides the window frame for the
+// Chrome browser window.
//
-class BrowserFrame {
+class BrowserFrame : public views::Window {
public:
- // TODO(beng): We should _not_ have to expose this method here... it's only
- // because BrowserView needs it to implement BrowserWindow
- // because we're doing popup setup in browser.cc when we
- // shouldn't be...
- virtual gfx::Rect GetWindowBoundsForClientBounds(
- const gfx::Rect& client_bounds) = 0;
+ explicit BrowserFrame(BrowserView* browser_view);
+ virtual ~BrowserFrame();
- // Sizes the frame assuming the contents view's bounds are as specified.
- virtual void SizeToContents(const gfx::Rect& contents_bounds) = 0;
+ // Initialize the frame. Creates the Window.
+ void Init();
- // Retrieve the bounds for the specified |tabstrip|, in window coordinates.
- virtual gfx::Rect GetBoundsForTabStrip(TabStrip* tabstrip) const = 0;
+ // Determine the distance of the left edge of the minimize button from the
+ // left edge of the window. Used in our Non-Client View's Layout.
+ int GetMinimizeButtonOffset() const;
- // Updates the current frame of the Throbber animation, if applicable.
- // |running| is whether or not the throbber should be running.
- virtual void UpdateThrobber(bool running) = 0;
+ // Retrieves the bounds, in non-client view coordinates for the specified
+ // TabStrip.
+ gfx::Rect GetBoundsForTabStrip(TabStrip* tabstrip) const;
+
+ // Tells the frame to update the throbber.
+ void UpdateThrobber(bool running);
+
+ protected:
+ // Overridden from views::WidgetWin:
+ virtual bool AcceleratorPressed(views::Accelerator* accelerator);
+ virtual bool GetAccelerator(int cmd_id, views::Accelerator* accelerator);
+ virtual void OnInitMenuPopup(HMENU menu, UINT position, BOOL is_system_menu);
+ virtual void OnEnterSizeMove();
+ virtual void OnEndSession(BOOL ending, UINT logoff);
+ virtual LRESULT OnMouseActivate(HWND window,
+ UINT hittest_code,
+ UINT message);
+ virtual void OnMove(const CPoint& point);
+ virtual void OnMoving(UINT param, const RECT* new_bounds);
+ virtual LRESULT OnNCActivate(BOOL active);
+ virtual LRESULT OnNCCalcSize(BOOL mode, LPARAM l_param);
+ virtual LRESULT OnNCHitTest(const CPoint& pt);
+
+ // Overridden from views::Window:
+ virtual int GetShowState() const;
+ virtual bool IsAppWindow() const { return true; }
+ virtual views::NonClientFrameView* CreateFrameViewForWindow();
+ virtual void UpdateFrameAfterFrameChange();
- // Returns the views::Window associated with this frame.
- virtual views::Window* GetWindow() = 0;
- virtual const views::Window* GetWindow() const = 0;
+ private:
+ // Updates the DWM with the frame bounds.
+ void UpdateDWMFrame();
- enum FrameType {
- FRAMETYPE_OPAQUE,
- FRAMETYPE_AERO_GLASS
- };
+ // The BrowserView is our ClientView. This is a pointer to it.
+ BrowserView* browser_view_;
- // Returns the FrameType that should be constructed given the current system
- // settings.
- static FrameType GetActiveFrameType();
+ // A pointer to our NonClientFrameView as a BrowserNonClientFrameView.
+ BrowserNonClientFrameView* browser_frame_view_;
- // Creates a BrowserFrame instance for the specified FrameType and
- // BrowserView.
- static BrowserFrame* CreateForBrowserView(FrameType type,
- BrowserView* browser_view);
+ bool frame_initialized_;
+ DISALLOW_EVIL_CONSTRUCTORS(BrowserFrame);
};
-#endif // #ifndef CHROME_BROWSER_VIEWS_FRAME_BROWSER_FRAME_H_
+#endif // #ifndef CHROME_BROWSER_VIEWS_FRAME_BROWSER_FRAME_
diff --git a/chrome/browser/views/frame/browser_view.cc b/chrome/browser/views/frame/browser_view.cc
index f287485..72e8e8f 100644
--- a/chrome/browser/views/frame/browser_view.cc
+++ b/chrome/browser/views/frame/browser_view.cc
@@ -2,10 +2,9 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "base/command_line.h"
-
#include "chrome/browser/views/frame/browser_view.h"
+#include "base/command_line.h"
#include "base/file_version_info.h"
#include "base/time.h"
#include "chrome/app/chrome_dll_resource.h"
@@ -367,19 +366,6 @@ bool BrowserView::GetAccelerator(int cmd_id, views::Accelerator* accelerator) {
return false;
}
-bool BrowserView::SystemCommandReceived(UINT notification_code,
- const gfx::Point& point) {
- bool handled = false;
-
- if (browser_->command_updater()->SupportsCommand(notification_code) &&
- browser_->command_updater()->IsCommandEnabled(notification_code)) {
- browser_->ExecuteCommand(notification_code);
- handled = true;
- }
-
- return handled;
-}
-
void BrowserView::AddViewToDropList(views::View* view) {
dropable_views_.insert(view);
}
@@ -489,8 +475,8 @@ void BrowserView::Init() {
void BrowserView::Show() {
// If the window is already visible, just activate it.
- if (frame_->GetWindow()->IsVisible()) {
- frame_->GetWindow()->Activate();
+ if (frame_->IsVisible()) {
+ frame_->Activate();
return;
}
@@ -508,32 +494,29 @@ void BrowserView::Show() {
if (selected_tab_contents)
selected_tab_contents->RestoreFocus();
- frame_->GetWindow()->Show();
- int show_state = frame_->GetWindow()->GetShowState();
- if (show_state == SW_SHOWNORMAL || show_state == SW_SHOWMAXIMIZED)
- frame_->GetWindow()->Activate();
+ frame_->Show();
}
void BrowserView::SetBounds(const gfx::Rect& bounds) {
- frame_->GetWindow()->SetBounds(bounds);
+ frame_->SetBounds(bounds);
}
void BrowserView::Close() {
- frame_->GetWindow()->Close();
+ frame_->Close();
}
void BrowserView::Activate() {
- frame_->GetWindow()->Activate();
+ frame_->Activate();
}
bool BrowserView::IsActive() const {
- return frame_->GetWindow()->IsActive();
+ return frame_->IsActive();
}
void BrowserView::FlashFrame() {
FLASHWINFO fwi;
fwi.cbSize = sizeof(fwi);
- fwi.hwnd = frame_->GetWindow()->GetHWND();
+ fwi.hwnd = frame_->GetHWND();
fwi.dwFlags = FLASHW_ALL;
fwi.uCount = 4;
fwi.dwTimeout = 0;
@@ -564,9 +547,9 @@ void BrowserView::SelectedTabToolbarSizeChanged(bool is_animating) {
}
void BrowserView::UpdateTitleBar() {
- frame_->GetWindow()->UpdateWindowTitle();
+ frame_->UpdateWindowTitle();
if (ShouldShowWindowIcon())
- frame_->GetWindow()->UpdateWindowIcon();
+ frame_->UpdateWindowIcon();
}
void BrowserView::UpdateLoadingAnimations(bool should_animate) {
@@ -598,13 +581,13 @@ gfx::Rect BrowserView::GetNormalBounds() const {
WINDOWPLACEMENT wp;
wp.length = sizeof(wp);
- const bool ret = !!GetWindowPlacement(frame_->GetWindow()->GetHWND(), &wp);
+ const bool ret = !!GetWindowPlacement(frame_->GetHWND(), &wp);
DCHECK(ret);
return gfx::Rect(wp.rcNormalPosition);
}
bool BrowserView::IsMaximized() const {
- return frame_->GetWindow()->IsMaximized();
+ return frame_->IsMaximized();
}
void BrowserView::SetFullscreen(bool fullscreen) {
@@ -637,7 +620,7 @@ void BrowserView::SetFullscreen(bool fullscreen) {
// taskbar if the window is in the maximized state.
saved_window_info_.maximized = IsMaximized();
if (saved_window_info_.maximized)
- frame_->GetWindow()->ExecuteSystemMenuCommand(SC_RESTORE);
+ frame_->ExecuteSystemMenuCommand(SC_RESTORE);
saved_window_info_.style = GetWindowLong(hwnd, GWL_STYLE);
saved_window_info_.ex_style = GetWindowLong(hwnd, GWL_EXSTYLE);
GetWindowRect(hwnd, &saved_window_info_.window_rect);
@@ -667,7 +650,7 @@ void BrowserView::SetFullscreen(bool fullscreen) {
new_rect.height(),
SWP_NOZORDER | SWP_NOACTIVATE | SWP_FRAMECHANGED);
if (saved_window_info_.maximized)
- frame_->GetWindow()->ExecuteSystemMenuCommand(SC_MAXIMIZE);
+ frame_->ExecuteSystemMenuCommand(SC_MAXIMIZE);
}
// Turn fullscreen bubble on or off.
@@ -999,6 +982,8 @@ bool BrowserView::ShouldShowWindowIcon() const {
}
bool BrowserView::ExecuteWindowsCommand(int command_id) {
+ // This function handles WM_SYSCOMMAND, WM_APPCOMMAND, and WM_COMMAND.
+
// Translate WM_APPCOMMAND command ids into a command id that the browser
// knows how to handle.
int command_id_from_app_command = GetCommandIDForAppCommandID(command_id);
@@ -1047,7 +1032,8 @@ bool BrowserView::GetSavedWindowBounds(gfx::Rect* bounds) const {
bounds->height() + toolbar_->GetPreferredSize().height());
}
- gfx::Rect window_rect = frame_->GetWindowBoundsForClientBounds(*bounds);
+ gfx::Rect window_rect =
+ frame_->GetWindowBoundsForClientBounds(*bounds);
window_rect.set_origin(bounds->origin());
// When we are given x/y coordinates of 0 on a created popup window,
@@ -1102,7 +1088,7 @@ bool BrowserView::CanClose() const {
// Tab strip isn't empty. Hide the frame (so it appears to have closed
// immediately) and close all the tabs, allowing the renderers to shut
// down. When the tab strip is empty we'll be called back again.
- frame_->GetWindow()->Hide();
+ frame_->Hide();
browser_->OnWindowClosing();
return false;
}
@@ -1110,7 +1096,7 @@ bool BrowserView::CanClose() const {
// Empty TabStripModel, it's now safe to allow the Window to be closed.
NotificationService::current()->Notify(
NotificationType::WINDOW_CLOSED,
- Source<HWND>(frame_->GetWindow()->GetHWND()),
+ Source<HWND>(frame_->GetHWND()),
NotificationService::NoDetails());
return true;
}
@@ -1123,7 +1109,7 @@ int BrowserView::NonClientHitTest(const gfx::Point& point) {
if (CanCurrentlyResize()) {
CRect client_rect;
- ::GetClientRect(frame_->GetWindow()->GetHWND(), &client_rect);
+ ::GetClientRect(frame_->GetHWND(), &client_rect);
gfx::Size resize_corner_size = ResizeCorner::GetSize();
gfx::Rect resize_corner_rect(client_rect.right - resize_corner_size.width(),
client_rect.bottom - resize_corner_size.height(),
@@ -1283,7 +1269,7 @@ int BrowserView::OnPerformDrop(const views::DropTargetEvent& event) {
// BrowserView, private:
void BrowserView::InitSystemMenu() {
- HMENU system_menu = GetSystemMenu(frame_->GetWindow()->GetHWND(), FALSE);
+ HMENU system_menu = GetSystemMenu(frame_->GetHWND(), FALSE);
system_menu_.reset(new Menu(system_menu));
int insertion_index = std::max(0, system_menu_->ItemCount() - 1);
// We add the menu items in reverse order so that insertion_index never needs
@@ -1434,7 +1420,7 @@ void BrowserView::LayoutStatusBubble(int top) {
// In restored mode, the client area has a client edge between it and the
// frame.
int overlap = kStatusBubbleOverlap +
- (IsMaximized() ? 0 : views::NonClientView::kClientEdgeThickness);
+ (IsMaximized() ? 0 : views::NonClientFrameView::kClientEdgeThickness);
gfx::Point origin(-overlap, top - kStatusBubbleHeight + overlap);
ConvertPointToView(this, GetParent(), &origin);
status_bubble_->SetBounds(origin.x(), origin.y(), width() / 3,
@@ -1679,3 +1665,11 @@ void BrowserView::InitClass() {
initialized = true;
}
}
+
+// static
+BrowserWindow* BrowserWindow::CreateBrowserWindow(Browser* browser) {
+ BrowserView* browser_view = new BrowserView(browser);
+ (new BrowserFrame(browser_view))->Init();
+ return browser_view;
+}
+
diff --git a/chrome/browser/views/frame/browser_window_factory.cc b/chrome/browser/views/frame/browser_window_factory.cc
deleted file mode 100644
index 9a6853b..0000000
--- a/chrome/browser/views/frame/browser_window_factory.cc
+++ /dev/null
@@ -1,50 +0,0 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "base/command_line.h"
-#include "chrome/browser/browser.h"
-#include "chrome/browser/browser_process.h" // TODO(beng): remove once done.
-#include "chrome/browser/browser_window.h"
-#include "chrome/browser/views/frame/aero_glass_frame.h"
-#include "chrome/browser/views/frame/browser_frame.h"
-#include "chrome/browser/views/frame/browser_view.h"
-#include "chrome/browser/views/frame/opaque_frame.h"
-#include "chrome/common/win_util.h"
-
-///////////////////////////////////////////////////////////////////////////////
-// BrowserWindow, public:
-
-// static
-BrowserWindow* BrowserWindow::CreateBrowserWindow(Browser* browser) {
- BrowserView* browser_view = new BrowserView(browser);
- BrowserFrame::CreateForBrowserView(BrowserFrame::GetActiveFrameType(),
- browser_view);
- return browser_view;
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// BrowserFrame, public:
-
-// static
-BrowserFrame::FrameType BrowserFrame::GetActiveFrameType() {
- return win_util::ShouldUseVistaFrame() ? BrowserFrame::FRAMETYPE_AERO_GLASS
- : BrowserFrame::FRAMETYPE_OPAQUE;
-}
-
-// static
-BrowserFrame* BrowserFrame::CreateForBrowserView(BrowserFrame::FrameType type,
- BrowserView* browser_view) {
- if (type == FRAMETYPE_OPAQUE) {
- OpaqueFrame* frame = new OpaqueFrame(browser_view);
- frame->Init();
- return frame;
- } else if (type == FRAMETYPE_AERO_GLASS) {
- AeroGlassFrame* frame = new AeroGlassFrame(browser_view);
- frame->Init();
- return frame;
- }
- NOTREACHED() << "Unsupported frame type";
- return NULL;
-}
-
diff --git a/chrome/browser/views/frame/aero_glass_non_client_view.cc b/chrome/browser/views/frame/glass_browser_frame_view.cc
index 93031d1..54982d7 100644
--- a/chrome/browser/views/frame/aero_glass_non_client_view.cc
+++ b/chrome/browser/views/frame/glass_browser_frame_view.cc
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "chrome/browser/views/frame/aero_glass_non_client_view.h"
+#include "chrome/browser/views/frame/glass_browser_frame_view.h"
#include "chrome/browser/views/frame/browser_view.h"
#include "chrome/browser/views/tabs/tab_strip.h"
@@ -27,12 +27,12 @@ enum {
FRAME_PART_BITMAP_COUNT // Must be last.
};
-class AeroGlassWindowResources {
+class GlassBrowserWindowResources {
public:
- AeroGlassWindowResources() {
+ GlassBrowserWindowResources() {
InitClass();
}
- virtual ~AeroGlassWindowResources() { }
+ virtual ~GlassBrowserWindowResources() { }
virtual SkBitmap* GetPartBitmap(views::FramePartBitmap part) const {
return standard_frame_bitmaps_[part];
@@ -59,14 +59,15 @@ class AeroGlassWindowResources {
static SkBitmap* standard_frame_bitmaps_[FRAME_PART_BITMAP_COUNT];
- DISALLOW_EVIL_CONSTRUCTORS(AeroGlassWindowResources);
+ DISALLOW_EVIL_CONSTRUCTORS(GlassBrowserWindowResources);
};
// static
-SkBitmap* AeroGlassWindowResources::standard_frame_bitmaps_[];
+SkBitmap* GlassBrowserWindowResources::standard_frame_bitmaps_[];
-AeroGlassWindowResources* AeroGlassNonClientView::resources_ = NULL;
-SkBitmap* AeroGlassNonClientView::distributor_logo_ = NULL;
+GlassBrowserWindowResources* GlassBrowserFrameView::resources_ = NULL;
+SkBitmap* GlassBrowserFrameView::distributor_logo_ = NULL;
+HICON GlassBrowserFrameView::throbber_icons_[GlassBrowserFrameView::kThrobberIconCount];
namespace {
// There are 3 px of client edge drawn inside the outer frame borders.
@@ -103,19 +104,28 @@ const int kLogoCaptionSpacing = 7;
}
///////////////////////////////////////////////////////////////////////////////
-// AeroGlassNonClientView, public:
-
-AeroGlassNonClientView::AeroGlassNonClientView(AeroGlassFrame* frame,
- BrowserView* browser_view)
- : frame_(frame),
- browser_view_(browser_view) {
+// GlassBrowserFrameView, public:
+
+GlassBrowserFrameView::GlassBrowserFrameView(BrowserFrame* frame,
+ BrowserView* browser_view)
+ : BrowserNonClientFrameView(),
+ frame_(frame),
+ browser_view_(browser_view),
+ throbber_running_(false),
+ throbber_frame_(0) {
InitClass();
+ if (frame_->window_delegate()->ShouldShowWindowIcon())
+ InitThrobberIcons();
}
-AeroGlassNonClientView::~AeroGlassNonClientView() {
+GlassBrowserFrameView::~GlassBrowserFrameView() {
}
-gfx::Rect AeroGlassNonClientView::GetBoundsForTabStrip(TabStrip* tabstrip) {
+///////////////////////////////////////////////////////////////////////////////
+// GlassBrowserFrameView, BrowserNonClientFrameView implementation:
+
+gfx::Rect GlassBrowserFrameView::GetBoundsForTabStrip(
+ TabStrip* tabstrip) const {
int tabstrip_x = browser_view_->ShouldShowOffTheRecordAvatar() ?
(otr_avatar_bounds_.right() + kOTRSideSpacing) :
NonClientBorderThickness();
@@ -126,43 +136,56 @@ gfx::Rect AeroGlassNonClientView::GetBoundsForTabStrip(TabStrip* tabstrip) {
std::max(0, tabstrip_width), tabstrip->GetPreferredHeight());
}
-///////////////////////////////////////////////////////////////////////////////
-// AeroGlassNonClientView, views::NonClientView implementation:
+void GlassBrowserFrameView::UpdateThrobber(bool running) {
+ if (throbber_running_) {
+ if (running) {
+ DisplayNextThrobberFrame();
+ } else {
+ StopThrobber();
+ }
+ } else if (running) {
+ StartThrobber();
+ }
+}
-gfx::Rect AeroGlassNonClientView::CalculateClientAreaBounds(int width,
- int height) const {
- if (!browser_view_->IsTabStripVisible())
- return gfx::Rect(0, 0, this->width(), this->height());
+///////////////////////////////////////////////////////////////////////////////
+// GlassBrowserFrameView, views::NonClientFrameView implementation:
- int top_height = NonClientTopBorderHeight();
- int border_thickness = NonClientBorderThickness();
- return gfx::Rect(border_thickness, top_height,
- std::max(0, width - (2 * border_thickness)),
- std::max(0, height - top_height - border_thickness));
+gfx::Rect GlassBrowserFrameView::GetBoundsForClientView() const {
+ return client_view_bounds_;
}
-gfx::Size AeroGlassNonClientView::CalculateWindowSizeForClientSize(
- int width,
- int height) const {
- if (!browser_view_->IsTabStripVisible())
- return gfx::Size(width, height);
+gfx::Rect GlassBrowserFrameView::GetWindowBoundsForClientBounds(
+ const gfx::Rect& client_bounds) const {
+ if (!browser_view_->IsTabStripVisible()) {
+ // If we don't have a tabstrip, we're either a popup or an app window, in
+ // which case we have a standard size non-client area and can just use
+ // AdjustWindowRectEx to obtain it.
+ RECT rect = client_bounds.ToRECT();
+ AdjustWindowRectEx(&rect, frame_->window_style(), FALSE,
+ frame_->window_ex_style());
+ return gfx::Rect(rect);
+ }
+ int top_height = NonClientTopBorderHeight();
int border_thickness = NonClientBorderThickness();
- return gfx::Size(width + (2 * border_thickness),
- height + NonClientTopBorderHeight() + border_thickness);
+ return gfx::Rect(std::max(0, client_bounds.x() - border_thickness),
+ std::max(0, client_bounds.y() - top_height),
+ client_bounds.width() + (2 * border_thickness),
+ client_bounds.height() + top_height + border_thickness);
}
-gfx::Point AeroGlassNonClientView::GetSystemMenuPoint() const {
+gfx::Point GlassBrowserFrameView::GetSystemMenuPoint() const {
gfx::Point system_menu_point;
if (browser_view_->IsBrowserTypeNormal()) {
- // The X coordinate conditional is because in maximized mode the frame edge
+ // The maximized mode bit here is because in maximized mode the frame edge
// and the client edge are both offscreen, whereas in the opaque frame
// (where we don't do this trick) maximized windows have no client edge and
// only the frame edge is offscreen.
system_menu_point.SetPoint(NonClientBorderThickness() -
- (browser_view_->CanCurrentlyResize() ? kClientEdgeThickness : 0),
+ (frame_->IsMaximized() ? 0 : kClientEdgeThickness),
NonClientTopBorderHeight() + browser_view_->GetTabStripHeight() -
- (browser_view_->IsFullscreen() ? 0 : kClientEdgeThickness));
+ kClientEdgeThickness);
} else {
system_menu_point.SetPoint(0, -kFrameShadowThickness);
}
@@ -170,7 +193,7 @@ gfx::Point AeroGlassNonClientView::GetSystemMenuPoint() const {
return system_menu_point;
}
-int AeroGlassNonClientView::NonClientHitTest(const gfx::Point& point) {
+int GlassBrowserFrameView::NonClientHitTest(const gfx::Point& point) {
// If the browser isn't in normal mode, we haven't customized the frame, so
// Windows can figure this out. If the point isn't within our bounds, then
// it's in the native portion of the frame, so again Windows can figure it
@@ -192,9 +215,9 @@ int AeroGlassNonClientView::NonClientHitTest(const gfx::Point& point) {
}
///////////////////////////////////////////////////////////////////////////////
-// AeroGlassNonClientView, views::View overrides:
+// GlassBrowserFrameView, views::View overrides:
-void AeroGlassNonClientView::Paint(ChromeCanvas* canvas) {
+void GlassBrowserFrameView::Paint(ChromeCanvas* canvas) {
if (!browser_view_->IsTabStripVisible())
return; // Nothing is visible, so don't bother to paint.
@@ -204,39 +227,29 @@ void AeroGlassNonClientView::Paint(ChromeCanvas* canvas) {
PaintClientEdge(canvas);
}
-void AeroGlassNonClientView::Layout() {
+void GlassBrowserFrameView::Layout() {
LayoutDistributorLogo();
LayoutOTRAvatar();
LayoutClientView();
}
-void AeroGlassNonClientView::ViewHierarchyChanged(bool is_add,
- views::View* parent,
- views::View* child) {
- if (is_add && child == this) {
- DCHECK(GetWidget());
- DCHECK(frame_->client_view()->GetParent() != this);
- AddChildView(frame_->client_view());
- }
-}
-
///////////////////////////////////////////////////////////////////////////////
-// AeroGlassNonClientView, private:
+// GlassBrowserFrameView, private:
-int AeroGlassNonClientView::FrameBorderThickness() const {
- return browser_view_->IsFullscreen() ? 0 : GetSystemMetrics(SM_CXSIZEFRAME);
+int GlassBrowserFrameView::FrameBorderThickness() const {
+ return GetSystemMetrics(SM_CXSIZEFRAME);
}
-int AeroGlassNonClientView::NonClientBorderThickness() const {
- return browser_view_->IsFullscreen() ? 0 : kNonClientBorderThickness;
+int GlassBrowserFrameView::NonClientBorderThickness() const {
+ return kNonClientBorderThickness;
}
-int AeroGlassNonClientView::NonClientTopBorderHeight() const {
- return FrameBorderThickness() + (browser_view_->CanCurrentlyResize() ?
- kNonClientRestoredExtraThickness : 0);
+int GlassBrowserFrameView::NonClientTopBorderHeight() const {
+ return FrameBorderThickness() +
+ (frame_->IsMaximized() ? 0 : kNonClientRestoredExtraThickness);
}
-void AeroGlassNonClientView::PaintDistributorLogo(ChromeCanvas* canvas) {
+void GlassBrowserFrameView::PaintDistributorLogo(ChromeCanvas* canvas) {
// The distributor logo is only painted when the frame is not maximized and
// when we actually have a logo.
if (!frame_->IsMaximized() && distributor_logo_) {
@@ -248,7 +261,7 @@ void AeroGlassNonClientView::PaintDistributorLogo(ChromeCanvas* canvas) {
}
}
-void AeroGlassNonClientView::PaintToolbarBackground(ChromeCanvas* canvas) {
+void GlassBrowserFrameView::PaintToolbarBackground(ChromeCanvas* canvas) {
gfx::Rect toolbar_bounds(browser_view_->GetToolbarBounds());
gfx::Point toolbar_origin(toolbar_bounds.origin());
View::ConvertPointToView(frame_->client_view(), this, &toolbar_origin);
@@ -269,7 +282,7 @@ void AeroGlassNonClientView::PaintToolbarBackground(ChromeCanvas* canvas) {
toolbar_bounds.right(), toolbar_bounds.y());
}
-void AeroGlassNonClientView::PaintOTRAvatar(ChromeCanvas* canvas) {
+void GlassBrowserFrameView::PaintOTRAvatar(ChromeCanvas* canvas) {
if (!browser_view_->ShouldShowOffTheRecordAvatar())
return;
@@ -281,7 +294,7 @@ void AeroGlassNonClientView::PaintOTRAvatar(ChromeCanvas* canvas) {
otr_avatar_bounds_.width(), otr_avatar_bounds_.height(), false);
}
-void AeroGlassNonClientView::PaintClientEdge(ChromeCanvas* canvas) {
+void GlassBrowserFrameView::PaintClientEdge(ChromeCanvas* canvas) {
// The client edges start below the toolbar upper corner images regardless
// of how tall the toolbar itself is.
int client_area_top =
@@ -315,7 +328,7 @@ void AeroGlassNonClientView::PaintClientEdge(ChromeCanvas* canvas) {
client_area_top, left->width(), client_area_height);
}
-void AeroGlassNonClientView::LayoutDistributorLogo() {
+void GlassBrowserFrameView::LayoutDistributorLogo() {
if (distributor_logo_) {
logo_bounds_.SetRect(frame_->GetMinimizeButtonOffset() -
distributor_logo_->width() - kLogoCaptionSpacing, kLogoTopSpacing,
@@ -326,7 +339,7 @@ void AeroGlassNonClientView::LayoutDistributorLogo() {
}
}
-void AeroGlassNonClientView::LayoutOTRAvatar() {
+void GlassBrowserFrameView::LayoutOTRAvatar() {
SkBitmap otr_avatar_icon = browser_view_->GetOTRAvatarIcon();
int top_height = NonClientTopBorderHeight();
int tabstrip_height, otr_height;
@@ -343,16 +356,61 @@ void AeroGlassNonClientView::LayoutOTRAvatar() {
otr_avatar_icon.width(), otr_height);
}
-void AeroGlassNonClientView::LayoutClientView() {
- frame_->client_view()->SetBounds(CalculateClientAreaBounds(width(),
- height()));
+void GlassBrowserFrameView::LayoutClientView() {
+ client_view_bounds_ = CalculateClientAreaBounds(width(), height());
+}
+
+gfx::Rect GlassBrowserFrameView::CalculateClientAreaBounds(int width,
+ int height) const {
+ if (!browser_view_->IsTabStripVisible())
+ return gfx::Rect(0, 0, this->width(), this->height());
+
+ int top_height = NonClientTopBorderHeight();
+ int border_thickness = NonClientBorderThickness();
+ return gfx::Rect(border_thickness, top_height,
+ std::max(0, width - (2 * border_thickness)),
+ std::max(0, height - top_height - border_thickness));
+}
+
+void GlassBrowserFrameView::StartThrobber() {
+ if (!throbber_running_) {
+ throbber_running_ = true;
+ throbber_frame_ = 0;
+ InitThrobberIcons();
+ SendMessage(frame_->GetHWND(), WM_SETICON, static_cast<WPARAM>(ICON_SMALL),
+ reinterpret_cast<LPARAM>(throbber_icons_[throbber_frame_]));
+ }
+}
+
+void GlassBrowserFrameView::StopThrobber() {
+ if (throbber_running_)
+ throbber_running_ = false;
+}
+
+void GlassBrowserFrameView::DisplayNextThrobberFrame() {
+ throbber_frame_ = (throbber_frame_ + 1) % kThrobberIconCount;
+ SendMessage(frame_->GetHWND(), WM_SETICON, static_cast<WPARAM>(ICON_SMALL),
+ reinterpret_cast<LPARAM>(throbber_icons_[throbber_frame_]));
+}
+
+// static
+void GlassBrowserFrameView::InitThrobberIcons() {
+ static bool initialized = false;
+ if (!initialized) {
+ ResourceBundle &rb = ResourceBundle::GetSharedInstance();
+ for (int i = 0; i < kThrobberIconCount; ++i) {
+ throbber_icons_[i] = rb.LoadThemeIcon(IDR_THROBBER_01 + i);
+ DCHECK(throbber_icons_[i]);
+ }
+ initialized = true;
+ }
}
// static
-void AeroGlassNonClientView::InitClass() {
+void GlassBrowserFrameView::InitClass() {
static bool initialized = false;
if (!initialized) {
- resources_ = new AeroGlassWindowResources;
+ resources_ = new GlassBrowserWindowResources;
#if defined(GOOGLE_CHROME_BUILD)
distributor_logo_ = ResourceBundle::GetSharedInstance().
diff --git a/chrome/browser/views/frame/aero_glass_non_client_view.h b/chrome/browser/views/frame/glass_browser_frame_view.h
index 5023ea0..f325dde 100644
--- a/chrome/browser/views/frame/aero_glass_non_client_view.h
+++ b/chrome/browser/views/frame/glass_browser_frame_view.h
@@ -2,43 +2,40 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef CHROME_BROWSER_VIEWS_FRAME_AERO_GLASS_NON_CLIENT_VIEW_H_
-#define CHROME_BROWSER_VIEWS_FRAME_AERO_GLASS_NON_CLIENT_VIEW_H_
+#ifndef CHROME_BROWSER_VIEWS_FRAME_GLASS_BROWSER_FRAME_VIEW_H_
+#define CHROME_BROWSER_VIEWS_FRAME_GLASS_BROWSER_FRAME_VIEW_H_
-#include "chrome/browser/views/frame/aero_glass_frame.h"
+#include "chrome/browser/views/frame/browser_frame.h"
#include "chrome/views/non_client_view.h"
#include "chrome/views/button.h"
class BrowserView;
-class AeroGlassWindowResources;
+class GlassBrowserWindowResources;
-class AeroGlassNonClientView : public views::NonClientView {
+class GlassBrowserFrameView : public BrowserNonClientFrameView {
public:
- // Constructs a non-client view for an AeroGlassFrame.
- AeroGlassNonClientView(AeroGlassFrame* frame, BrowserView* browser_view);
- virtual ~AeroGlassNonClientView();
-
- // Retrieve the bounds for the specified |tabstrip|, in the coordinate system
- // of the non-client view (which whould be window coordinates).
- gfx::Rect GetBoundsForTabStrip(TabStrip* tabstrip);
-
- protected:
- // Overridden from views::NonClientView:
- virtual gfx::Rect CalculateClientAreaBounds(int width, int height) const;
- virtual gfx::Size CalculateWindowSizeForClientSize(int width,
- int height) const;
+ // Constructs a non-client view for an BrowserFrame.
+ GlassBrowserFrameView(BrowserFrame* frame, BrowserView* browser_view);
+ virtual ~GlassBrowserFrameView();
+
+ // Overridden from BrowserNonClientFrameView:
+ virtual gfx::Rect GetBoundsForTabStrip(TabStrip* tabstrip) const;
+ virtual void UpdateThrobber(bool running);
+
+ // Overridden from views::NonClientFrameView:
+ virtual gfx::Rect GetBoundsForClientView() const;
+ virtual gfx::Rect GetWindowBoundsForClientBounds(
+ const gfx::Rect& client_bounds) const;
virtual gfx::Point GetSystemMenuPoint() const;
virtual int NonClientHitTest(const gfx::Point& point);
virtual void GetWindowMask(const gfx::Size& size, gfx::Path* window_mask) { }
virtual void EnableClose(bool enable) { }
virtual void ResetWindowControls() { }
+ protected:
// Overridden from views::View:
virtual void Paint(ChromeCanvas* canvas);
virtual void Layout();
- virtual void ViewHierarchyChanged(bool is_add,
- views::View* parent,
- views::View* child);
private:
// Returns the thickness of the border that makes up the window frame edges.
@@ -63,7 +60,17 @@ class AeroGlassNonClientView : public views::NonClientView {
void LayoutDistributorLogo();
void LayoutOTRAvatar();
void LayoutClientView();
+
+ // Returns the bounds of the client area for the specified view size.
+ gfx::Rect CalculateClientAreaBounds(int width, int height) const;
+ // Starts/Stops the window throbber running.
+ void StartThrobber();
+ void StopThrobber();
+
+ // Displays the next throbber frame.
+ void DisplayNextThrobberFrame();
+
// The layout rect of the distributor logo, if visible.
gfx::Rect logo_bounds_;
@@ -71,17 +78,30 @@ class AeroGlassNonClientView : public views::NonClientView {
gfx::Rect otr_avatar_bounds_;
// The frame that hosts this view.
- AeroGlassFrame* frame_;
+ BrowserFrame* frame_;
// The BrowserView hosted within this View.
BrowserView* browser_view_;
+ // The bounds of the ClientView.
+ gfx::Rect client_view_bounds_;
+
+ // Whether or not the window throbber is currently animating.
+ bool throbber_running_;
+
+ // The index of the current frame of the throbber animation.
+ int throbber_frame_;
+
static void InitClass();
static SkBitmap* distributor_logo_;
- static AeroGlassWindowResources* resources_;
+ static GlassBrowserWindowResources* resources_;
+
+ static const int kThrobberIconCount = 24;
+ static HICON throbber_icons_[kThrobberIconCount];
+ static void InitThrobberIcons();
- DISALLOW_EVIL_CONSTRUCTORS(AeroGlassNonClientView);
+ DISALLOW_EVIL_CONSTRUCTORS(GlassBrowserFrameView);
};
-#endif // #ifndef CHROME_BROWSER_VIEWS_FRAME_AERO_GLASS_NON_CLIENT_VIEW_H_
+#endif // #ifndef CHROME_BROWSER_VIEWS_FRAME_GLASS_BROWSER_FRAME_VIEW_H_
diff --git a/chrome/browser/views/frame/opaque_non_client_view.cc b/chrome/browser/views/frame/opaque_browser_frame_view.cc
index 2ed23f8..98a71c3 100644
--- a/chrome/browser/views/frame/opaque_non_client_view.cc
+++ b/chrome/browser/views/frame/opaque_browser_frame_view.cc
@@ -2,8 +2,9 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "chrome/browser/views/frame/opaque_non_client_view.h"
+#include "chrome/browser/views/frame/opaque_browser_frame_view.h"
+#include "chrome/browser/views/frame/browser_frame.h"
#include "chrome/browser/views/frame/browser_view.h"
#include "chrome/browser/views/tabs/tab_strip.h"
#include "chrome/common/gfx/chrome_canvas.h"
@@ -252,12 +253,12 @@ SkBitmap* InactiveWindowResources::standard_frame_bitmaps_[];
SkBitmap* OTRActiveWindowResources::standard_frame_bitmaps_[];
SkBitmap* OTRInactiveWindowResources::standard_frame_bitmaps_[];
-views::WindowResources* OpaqueNonClientView::active_resources_ = NULL;
-views::WindowResources* OpaqueNonClientView::inactive_resources_ = NULL;
-views::WindowResources* OpaqueNonClientView::active_otr_resources_ = NULL;
-views::WindowResources* OpaqueNonClientView::inactive_otr_resources_ = NULL;
-SkBitmap* OpaqueNonClientView::distributor_logo_ = NULL;
-ChromeFont OpaqueNonClientView::title_font_;
+views::WindowResources* OpaqueBrowserFrameView::active_resources_ = NULL;
+views::WindowResources* OpaqueBrowserFrameView::inactive_resources_ = NULL;
+views::WindowResources* OpaqueBrowserFrameView::active_otr_resources_ = NULL;
+views::WindowResources* OpaqueBrowserFrameView::inactive_otr_resources_ = NULL;
+SkBitmap* OpaqueBrowserFrameView::distributor_logo_ = NULL;
+ChromeFont OpaqueBrowserFrameView::title_font_;
namespace {
// The frame border is only visible in restored mode and is hardcoded to 4 px on
@@ -326,11 +327,11 @@ const int kCaptionTopSpacing = 1;
}
///////////////////////////////////////////////////////////////////////////////
-// OpaqueNonClientView, public:
+// OpaqueBrowserFrameView, public:
-OpaqueNonClientView::OpaqueNonClientView(OpaqueFrame* frame,
- BrowserView* browser_view)
- : NonClientView(),
+OpaqueBrowserFrameView::OpaqueBrowserFrameView(BrowserFrame* frame,
+ BrowserView* browser_view)
+ : BrowserNonClientFrameView(),
minimize_button_(new views::Button),
maximize_button_(new views::Button),
restore_button_(new views::Button),
@@ -421,20 +422,14 @@ OpaqueNonClientView::OpaqueNonClientView(OpaqueFrame* frame,
InitAppWindowResources();
}
-OpaqueNonClientView::~OpaqueNonClientView() {
+OpaqueBrowserFrameView::~OpaqueBrowserFrameView() {
}
-gfx::Rect OpaqueNonClientView::GetWindowBoundsForClientBounds(
- const gfx::Rect& client_bounds) {
- int top_height = NonClientTopBorderHeight();
- int border_thickness = NonClientBorderThickness();
- return gfx::Rect(std::max(0, client_bounds.x() - border_thickness),
- std::max(0, client_bounds.y() - top_height),
- client_bounds.width() + (2 * border_thickness),
- client_bounds.height() + top_height + border_thickness);
-}
+///////////////////////////////////////////////////////////////////////////////
+// OpaqueBrowserFrameView, BrowserNonClientFrameView implementation:
-gfx::Rect OpaqueNonClientView::GetBoundsForTabStrip(TabStrip* tabstrip) {
+gfx::Rect OpaqueBrowserFrameView::GetBoundsForTabStrip(
+ TabStrip* tabstrip) const {
int tabstrip_x = browser_view_->ShouldShowOffTheRecordAvatar() ?
(otr_avatar_bounds_.right() + kOTRSideSpacing) :
NonClientBorderThickness();
@@ -445,40 +440,37 @@ gfx::Rect OpaqueNonClientView::GetBoundsForTabStrip(TabStrip* tabstrip) {
std::max(0, tabstrip_width), tabstrip->GetPreferredHeight());
}
-void OpaqueNonClientView::UpdateWindowIcon() {
+void OpaqueBrowserFrameView::UpdateThrobber(bool running) {
if (window_icon_)
window_icon_->Update();
}
///////////////////////////////////////////////////////////////////////////////
-// OpaqueNonClientView, views::NonClientView implementation:
+// OpaqueBrowserFrameView, views::NonClientFrameView implementation:
-gfx::Rect OpaqueNonClientView::CalculateClientAreaBounds(int width,
- int height) const {
- int top_height = NonClientTopBorderHeight();
- int border_thickness = NonClientBorderThickness();
- return gfx::Rect(border_thickness, top_height,
- std::max(0, width - (2 * border_thickness)),
- std::max(0, height - top_height - border_thickness));
+gfx::Rect OpaqueBrowserFrameView::GetBoundsForClientView() const {
+ return client_view_bounds_;
}
-gfx::Size OpaqueNonClientView::CalculateWindowSizeForClientSize(
- int width,
- int height) const {
+gfx::Rect OpaqueBrowserFrameView::GetWindowBoundsForClientBounds(
+ const gfx::Rect& client_bounds) const {
+ int top_height = NonClientTopBorderHeight();
int border_thickness = NonClientBorderThickness();
- return gfx::Size(width + (2 * border_thickness),
- height + NonClientTopBorderHeight() + border_thickness);
+ return gfx::Rect(std::max(0, client_bounds.x() - border_thickness),
+ std::max(0, client_bounds.y() - top_height),
+ client_bounds.width() + (2 * border_thickness),
+ client_bounds.height() + top_height + border_thickness);
}
-gfx::Point OpaqueNonClientView::GetSystemMenuPoint() const {
+gfx::Point OpaqueBrowserFrameView::GetSystemMenuPoint() const {
gfx::Point system_menu_point(FrameBorderThickness(),
NonClientTopBorderHeight() + browser_view_->GetTabStripHeight() -
- (browser_view_->IsFullscreen() ? 0 : kClientEdgeThickness));
+ kClientEdgeThickness);
ConvertPointToScreen(this, &system_menu_point);
return system_menu_point;
}
-int OpaqueNonClientView::NonClientHitTest(const gfx::Point& point) {
+int OpaqueBrowserFrameView::NonClientHitTest(const gfx::Point& point) {
if (!bounds().Contains(point))
return HTNOWHERE;
@@ -509,8 +501,8 @@ int OpaqueNonClientView::NonClientHitTest(const gfx::Point& point) {
return (window_component == HTNOWHERE) ? HTCAPTION : window_component;
}
-void OpaqueNonClientView::GetWindowMask(const gfx::Size& size,
- gfx::Path* window_mask) {
+void OpaqueBrowserFrameView::GetWindowMask(const gfx::Size& size,
+ gfx::Path* window_mask) {
DCHECK(window_mask);
if (browser_view_->IsFullscreen())
@@ -535,11 +527,11 @@ void OpaqueNonClientView::GetWindowMask(const gfx::Size& size,
window_mask->close();
}
-void OpaqueNonClientView::EnableClose(bool enable) {
+void OpaqueBrowserFrameView::EnableClose(bool enable) {
close_button_->SetEnabled(enable);
}
-void OpaqueNonClientView::ResetWindowControls() {
+void OpaqueBrowserFrameView::ResetWindowControls() {
restore_button_->SetState(views::Button::BS_NORMAL);
minimize_button_->SetState(views::Button::BS_NORMAL);
maximize_button_->SetState(views::Button::BS_NORMAL);
@@ -547,9 +539,9 @@ void OpaqueNonClientView::ResetWindowControls() {
}
///////////////////////////////////////////////////////////////////////////////
-// OpaqueNonClientView, views::View overrides:
+// OpaqueBrowserFrameView, views::View overrides:
-void OpaqueNonClientView::Paint(ChromeCanvas* canvas) {
+void OpaqueBrowserFrameView::Paint(ChromeCanvas* canvas) {
if (browser_view_->IsFullscreen())
return; // Nothing is visible, so don't bother to paint.
@@ -565,7 +557,7 @@ void OpaqueNonClientView::Paint(ChromeCanvas* canvas) {
PaintRestoredClientEdge(canvas);
}
-void OpaqueNonClientView::Layout() {
+void OpaqueBrowserFrameView::Layout() {
LayoutWindowControls();
LayoutDistributorLogo();
LayoutTitleBar();
@@ -573,8 +565,8 @@ void OpaqueNonClientView::Layout() {
LayoutClientView();
}
-views::View* OpaqueNonClientView::GetViewForPoint(const gfx::Point& point,
- bool can_create_floating) {
+views::View* OpaqueBrowserFrameView::GetViewForPoint(const gfx::Point& point,
+ bool can_create_floating) {
// We override this function because the ClientView can overlap the non -
// client view, making it impossible to click on the window controls. We need
// to ensure the window controls are checked _first_.
@@ -590,14 +582,10 @@ views::View* OpaqueNonClientView::GetViewForPoint(const gfx::Point& point,
return View::GetViewForPoint(point, can_create_floating);
}
-void OpaqueNonClientView::ViewHierarchyChanged(bool is_add,
- views::View* parent,
- views::View* child) {
+void OpaqueBrowserFrameView::ViewHierarchyChanged(bool is_add,
+ views::View* parent,
+ views::View* child) {
if (is_add && child == this) {
- DCHECK(GetWidget());
- DCHECK(frame_->client_view()->GetParent() != this);
- AddChildView(frame_->client_view());
-
// The Accessibility glue looks for the product name on these two views to
// determine if this is in fact a Chrome window.
GetRootView()->SetAccessibleName(l10n_util::GetString(IDS_PRODUCT_NAME));
@@ -605,7 +593,7 @@ void OpaqueNonClientView::ViewHierarchyChanged(bool is_add,
}
}
-bool OpaqueNonClientView::GetAccessibleRole(VARIANT* role) {
+bool OpaqueBrowserFrameView::GetAccessibleRole(VARIANT* role) {
DCHECK(role);
// We aren't actually the client area of the window, but we act like it as
// far as MSAA and the UI tests are concerned.
@@ -614,7 +602,7 @@ bool OpaqueNonClientView::GetAccessibleRole(VARIANT* role) {
return true;
}
-bool OpaqueNonClientView::GetAccessibleName(std::wstring* name) {
+bool OpaqueBrowserFrameView::GetAccessibleName(std::wstring* name) {
if (!accessible_name_.empty()) {
*name = accessible_name_;
return true;
@@ -622,14 +610,14 @@ bool OpaqueNonClientView::GetAccessibleName(std::wstring* name) {
return false;
}
-void OpaqueNonClientView::SetAccessibleName(const std::wstring& name) {
+void OpaqueBrowserFrameView::SetAccessibleName(const std::wstring& name) {
accessible_name_ = name;
}
///////////////////////////////////////////////////////////////////////////////
-// OpaqueNonClientView, views::BaseButton::ButtonListener implementation:
+// OpaqueBrowserFrameView, views::BaseButton::ButtonListener implementation:
-void OpaqueNonClientView::ButtonPressed(views::BaseButton* sender) {
+void OpaqueBrowserFrameView::ButtonPressed(views::BaseButton* sender) {
if (sender == minimize_button_)
frame_->ExecuteSystemMenuCommand(SC_MINIMIZE);
else if (sender == maximize_button_)
@@ -641,9 +629,9 @@ void OpaqueNonClientView::ButtonPressed(views::BaseButton* sender) {
}
///////////////////////////////////////////////////////////////////////////////
-// OpaqueNonClientView, TabIconView::TabContentsProvider implementation:
+// OpaqueBrowserFrameView, TabIconView::TabContentsProvider implementation:
-bool OpaqueNonClientView::ShouldTabIconViewAnimate() const {
+bool OpaqueBrowserFrameView::ShouldTabIconViewAnimate() const {
// This function is queried during the creation of the window as the
// TabIconView we host is initialized, so we need to NULL check the selected
// TabContents because in this condition there is not yet a selected tab.
@@ -651,31 +639,31 @@ bool OpaqueNonClientView::ShouldTabIconViewAnimate() const {
return current_tab ? current_tab->is_loading() : false;
}
-SkBitmap OpaqueNonClientView::GetFavIconForTabIconView() {
+SkBitmap OpaqueBrowserFrameView::GetFavIconForTabIconView() {
return frame_->window_delegate()->GetWindowIcon();
}
///////////////////////////////////////////////////////////////////////////////
-// OpaqueNonClientView, private:
+// OpaqueBrowserFrameView, private:
-int OpaqueNonClientView::FrameBorderThickness() const {
+int OpaqueBrowserFrameView::FrameBorderThickness() const {
if (browser_view_->IsFullscreen())
return 0;
return frame_->IsMaximized() ?
GetSystemMetrics(SM_CXSIZEFRAME) : kFrameBorderThickness;
}
-int OpaqueNonClientView::TopResizeHeight() const {
+int OpaqueBrowserFrameView::TopResizeHeight() const {
return FrameBorderThickness() - kTopResizeAdjust;
}
-int OpaqueNonClientView::NonClientBorderThickness() const {
+int OpaqueBrowserFrameView::NonClientBorderThickness() const {
// When we fill the screen, we don't show a client edge.
return FrameBorderThickness() +
(browser_view_->CanCurrentlyResize() ? kClientEdgeThickness : 0);
}
-int OpaqueNonClientView::NonClientTopBorderHeight() const {
+int OpaqueBrowserFrameView::NonClientTopBorderHeight() const {
if (frame_->window_delegate()->ShouldShowWindowTitle()) {
int title_top_spacing, title_thickness;
return TitleCoordinates(&title_top_spacing, &title_thickness);
@@ -685,7 +673,7 @@ int OpaqueNonClientView::NonClientTopBorderHeight() const {
kNonClientRestoredExtraThickness : 0);
}
-int OpaqueNonClientView::UnavailablePixelsAtBottomOfNonClientHeight() const {
+int OpaqueBrowserFrameView::UnavailablePixelsAtBottomOfNonClientHeight() const {
// Tricky: When a toolbar is edging the titlebar, it not only draws its own
// shadow and client edge, but an extra, light "shadow" pixel as well, which
// is treated as available space. Thus the nonclient area actually _fails_ to
@@ -697,8 +685,8 @@ int OpaqueNonClientView::UnavailablePixelsAtBottomOfNonClientHeight() const {
(frame_->IsMaximized() ? 0 : kClientEdgeThickness);
}
-int OpaqueNonClientView::TitleCoordinates(int* title_top_spacing,
- int* title_thickness) const {
+int OpaqueBrowserFrameView::TitleCoordinates(int* title_top_spacing,
+ int* title_thickness) const {
int frame_thickness = FrameBorderThickness();
int min_titlebar_height = kTitlebarMinimumHeight + frame_thickness;
*title_top_spacing = frame_thickness + kTitleTopSpacing;
@@ -724,7 +712,7 @@ int OpaqueNonClientView::TitleCoordinates(int* title_top_spacing,
UnavailablePixelsAtBottomOfNonClientHeight();
}
-void OpaqueNonClientView::PaintRestoredFrameBorder(ChromeCanvas* canvas) {
+void OpaqueBrowserFrameView::PaintRestoredFrameBorder(ChromeCanvas* canvas) {
SkBitmap* top_left_corner = resources()->GetPartBitmap(FRAME_TOP_LEFT_CORNER);
SkBitmap* top_right_corner =
resources()->GetPartBitmap(FRAME_TOP_RIGHT_CORNER);
@@ -772,7 +760,7 @@ void OpaqueNonClientView::PaintRestoredFrameBorder(ChromeCanvas* canvas) {
height() - top_left_corner->height() - bottom_left_corner->height());
}
-void OpaqueNonClientView::PaintMaximizedFrameBorder(ChromeCanvas* canvas) {
+void OpaqueBrowserFrameView::PaintMaximizedFrameBorder(ChromeCanvas* canvas) {
SkBitmap* top_edge = resources()->GetPartBitmap(FRAME_TOP_EDGE);
canvas->TileImageInt(*top_edge, 0, FrameBorderThickness(), width(),
top_edge->height());
@@ -789,7 +777,7 @@ void OpaqueNonClientView::PaintMaximizedFrameBorder(ChromeCanvas* canvas) {
}
}
-void OpaqueNonClientView::PaintDistributorLogo(ChromeCanvas* canvas) {
+void OpaqueBrowserFrameView::PaintDistributorLogo(ChromeCanvas* canvas) {
// The distributor logo is only painted when the frame is not maximized and
// when we actually have a logo.
if (!frame_->IsMaximized() && distributor_logo_) {
@@ -798,7 +786,7 @@ void OpaqueNonClientView::PaintDistributorLogo(ChromeCanvas* canvas) {
}
}
-void OpaqueNonClientView::PaintTitleBar(ChromeCanvas* canvas) {
+void OpaqueBrowserFrameView::PaintTitleBar(ChromeCanvas* canvas) {
// The window icon is painted by the TabIconView.
views::WindowDelegate* d = frame_->window_delegate();
if (d->ShouldShowWindowTitle()) {
@@ -814,7 +802,7 @@ void OpaqueNonClientView::PaintTitleBar(ChromeCanvas* canvas) {
}
}
-void OpaqueNonClientView::PaintToolbarBackground(ChromeCanvas* canvas) {
+void OpaqueBrowserFrameView::PaintToolbarBackground(ChromeCanvas* canvas) {
if (!browser_view_->IsToolbarVisible())
return;
@@ -848,7 +836,7 @@ void OpaqueNonClientView::PaintToolbarBackground(ChromeCanvas* canvas) {
toolbar_bounds.right(), toolbar_bounds.y());
}
-void OpaqueNonClientView::PaintOTRAvatar(ChromeCanvas* canvas) {
+void OpaqueBrowserFrameView::PaintOTRAvatar(ChromeCanvas* canvas) {
if (!browser_view_->ShouldShowOffTheRecordAvatar())
return;
@@ -860,7 +848,7 @@ void OpaqueNonClientView::PaintOTRAvatar(ChromeCanvas* canvas) {
otr_avatar_bounds_.width(), otr_avatar_bounds_.height(), false);
}
-void OpaqueNonClientView::PaintRestoredClientEdge(ChromeCanvas* canvas) {
+void OpaqueBrowserFrameView::PaintRestoredClientEdge(ChromeCanvas* canvas) {
int client_area_top = frame_->client_view()->y();
gfx::Rect client_area_bounds = CalculateClientAreaBounds(width(), height());
@@ -916,7 +904,7 @@ void OpaqueNonClientView::PaintRestoredClientEdge(ChromeCanvas* canvas) {
client_area_top, left->width(), client_area_height);
}
-void OpaqueNonClientView::LayoutWindowControls() {
+void OpaqueBrowserFrameView::LayoutWindowControls() {
close_button_->SetImageAlignment(views::Button::ALIGN_LEFT,
views::Button::ALIGN_BOTTOM);
// Maximized buttons start at window top so that even if their images aren't
@@ -965,7 +953,7 @@ void OpaqueNonClientView::LayoutWindowControls() {
minimize_button_size.height() + top_extra_height);
}
-void OpaqueNonClientView::LayoutDistributorLogo() {
+void OpaqueBrowserFrameView::LayoutDistributorLogo() {
// Always lay out the logo, even when it's not present, so we can lay out the
// window title based on its position.
if (distributor_logo_) {
@@ -977,7 +965,7 @@ void OpaqueNonClientView::LayoutDistributorLogo() {
}
}
-void OpaqueNonClientView::LayoutTitleBar() {
+void OpaqueBrowserFrameView::LayoutTitleBar() {
// Always lay out the icon, even when it's not present, so we can lay out the
// window title based on its position.
int frame_thickness = FrameBorderThickness();
@@ -1023,7 +1011,7 @@ void OpaqueNonClientView::LayoutTitleBar() {
}
}
-void OpaqueNonClientView::LayoutOTRAvatar() {
+void OpaqueBrowserFrameView::LayoutOTRAvatar() {
SkBitmap otr_avatar_icon = browser_view_->GetOTRAvatarIcon();
int top_height = NonClientTopBorderHeight();
int tabstrip_height, otr_height;
@@ -1040,13 +1028,21 @@ void OpaqueNonClientView::LayoutOTRAvatar() {
otr_avatar_icon.width(), otr_height);
}
-void OpaqueNonClientView::LayoutClientView() {
- frame_->client_view()->SetBounds(CalculateClientAreaBounds(width(),
- height()));
+void OpaqueBrowserFrameView::LayoutClientView() {
+ client_view_bounds_ = CalculateClientAreaBounds(width(), height());
+}
+
+gfx::Rect OpaqueBrowserFrameView::CalculateClientAreaBounds(int width,
+ int height) const {
+ int top_height = NonClientTopBorderHeight();
+ int border_thickness = NonClientBorderThickness();
+ return gfx::Rect(border_thickness, top_height,
+ std::max(0, width - (2 * border_thickness)),
+ std::max(0, height - top_height - border_thickness));
}
// static
-void OpaqueNonClientView::InitClass() {
+void OpaqueBrowserFrameView::InitClass() {
static bool initialized = false;
if (!initialized) {
active_resources_ = new ActiveWindowResources;
@@ -1062,7 +1058,7 @@ void OpaqueNonClientView::InitClass() {
}
// static
-void OpaqueNonClientView::InitAppWindowResources() {
+void OpaqueBrowserFrameView::InitAppWindowResources() {
static bool initialized = false;
if (!initialized) {
title_font_ = win_util::GetWindowTitleFont();
diff --git a/chrome/browser/views/frame/opaque_non_client_view.h b/chrome/browser/views/frame/opaque_browser_frame_view.h
index 6160b9d..7eed20d 100644
--- a/chrome/browser/views/frame/opaque_non_client_view.h
+++ b/chrome/browser/views/frame/opaque_browser_frame_view.h
@@ -2,48 +2,41 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef CHROME_BROWSER_VIEWS_FRAME_OPAQUE_NON_CLIENT_VIEW_H_
-#define CHROME_BROWSER_VIEWS_FRAME_OPAQUE_NON_CLIENT_VIEW_H_
+#ifndef CHROME_BROWSER_VIEWS_FRAME_OPAQUE_BROWSER_FRAME_VIEW_H_
+#define CHROME_BROWSER_VIEWS_FRAME_OPAQUE_BROWSER_FRAME_VIEW_H_
-#include "chrome/browser/views/frame/opaque_frame.h"
+#include "chrome/browser/views/frame/browser_frame.h"
#include "chrome/browser/views/tab_icon_view.h"
#include "chrome/views/non_client_view.h"
#include "chrome/views/button.h"
class BrowserView;
class ChromeFont;
-class OpaqueFrame;
class TabContents;
class TabStrip;
namespace views {
class WindowResources;
}
-class OpaqueNonClientView : public views::NonClientView,
- public views::BaseButton::ButtonListener,
- public TabIconView::TabIconViewModel {
+class OpaqueBrowserFrameView : public BrowserNonClientFrameView,
+ public views::BaseButton::ButtonListener,
+ public TabIconView::TabIconViewModel {
public:
- // Constructs a non-client view for an OpaqueFrame. |is_otr| specifies if the
+ // Constructs a non-client view for an BrowserFrame. |is_otr| specifies if the
// frame was created "off-the-record" and as such different bitmaps should be
// used to render the frame.
- OpaqueNonClientView(OpaqueFrame* frame, BrowserView* browser_view);
- virtual ~OpaqueNonClientView();
+ OpaqueBrowserFrameView(BrowserFrame* frame, BrowserView* browser_view);
+ virtual ~OpaqueBrowserFrameView();
- // Retrieve the bounds of the window for the specified contents bounds.
- gfx::Rect GetWindowBoundsForClientBounds(const gfx::Rect& client_bounds);
-
- // Retrieve the bounds for the specified |tabstrip|, in the coordinate system
- // of the non-client view (which whould be window coordinates).
- gfx::Rect GetBoundsForTabStrip(TabStrip* tabstrip);
-
- // Updates the window icon/throbber.
- void UpdateWindowIcon();
+ // Overridden from BrowserNonClientFrameView:
+ virtual gfx::Rect GetBoundsForTabStrip(TabStrip* tabstrip) const;
+ virtual void UpdateThrobber(bool running);
protected:
- // Overridden from views::NonClientView:
- virtual gfx::Rect CalculateClientAreaBounds(int width, int height) const;
- virtual gfx::Size CalculateWindowSizeForClientSize(int width,
- int height) const;
+ // Overridden from views::NonClientFrameView:
+ virtual gfx::Rect GetBoundsForClientView() const;
+ virtual gfx::Rect GetWindowBoundsForClientBounds(
+ const gfx::Rect& client_bounds) const;
virtual gfx::Point GetSystemMenuPoint() const;
virtual int NonClientHitTest(const gfx::Point& point);
virtual void GetWindowMask(const gfx::Size& size, gfx::Path* window_mask);
@@ -115,6 +108,9 @@ class OpaqueNonClientView : public views::NonClientView,
void LayoutOTRAvatar();
void LayoutClientView();
+ // Returns the bounds of the client area for the specified view size.
+ gfx::Rect CalculateClientAreaBounds(int width, int height) const;
+
// Returns the set of resources to use to paint this view.
views::WindowResources* resources() const {
return frame_->is_active() || paint_as_active() ?
@@ -140,11 +136,14 @@ class OpaqueNonClientView : public views::NonClientView,
TabIconView* window_icon_;
// The frame that hosts this view.
- OpaqueFrame* frame_;
+ BrowserFrame* frame_;
// The BrowserView hosted within this View.
BrowserView* browser_view_;
+ // The bounds of the ClientView.
+ gfx::Rect client_view_bounds_;
+
// The resources currently used to paint this view.
views::WindowResources* current_active_resources_;
views::WindowResources* current_inactive_resources_;
@@ -161,8 +160,8 @@ class OpaqueNonClientView : public views::NonClientView,
static views::WindowResources* inactive_otr_resources_;
static ChromeFont title_font_;
- DISALLOW_EVIL_CONSTRUCTORS(OpaqueNonClientView);
+ DISALLOW_EVIL_CONSTRUCTORS(OpaqueBrowserFrameView);
};
-#endif // #ifndef CHROME_BROWSER_VIEWS_FRAME_OPAQUE_NON_CLIENT_VIEW_H_
+#endif // #ifndef CHROME_BROWSER_VIEWS_FRAME_OPAQUE_BROWSER_FRAME_VIEW_H_
diff --git a/chrome/browser/views/frame/opaque_frame.cc b/chrome/browser/views/frame/opaque_frame.cc
deleted file mode 100644
index 066bcad..0000000
--- a/chrome/browser/views/frame/opaque_frame.cc
+++ /dev/null
@@ -1,139 +0,0 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/views/frame/opaque_frame.h"
-
-#include "chrome/browser/browser_list.h"
-#include "chrome/browser/views/frame/browser_view.h"
-#include "chrome/browser/views/frame/opaque_non_client_view.h"
-#include "chrome/browser/views/tabs/tab_strip.h"
-#include "chrome/views/window_delegate.h"
-
-///////////////////////////////////////////////////////////////////////////////
-// OpaqueFrame, public:
-
-OpaqueFrame::OpaqueFrame(BrowserView* browser_view)
- : CustomFrameWindow(browser_view, new OpaqueNonClientView(this,
- browser_view)),
- browser_view_(browser_view) {
- browser_view_->set_frame(this);
-}
-
-OpaqueFrame::~OpaqueFrame() {
-}
-
-void OpaqueFrame::Init() {
- CustomFrameWindow::Init(NULL, gfx::Rect());
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// OpaqueFrame, BrowserFrame implementation:
-
-gfx::Rect OpaqueFrame::GetWindowBoundsForClientBounds(
- const gfx::Rect& client_bounds) {
- return GetOpaqueNonClientView()->GetWindowBoundsForClientBounds(
- client_bounds);
-}
-
-void OpaqueFrame::SizeToContents(const gfx::Rect& contents_bounds) {
- gfx::Rect window_bounds = GetOpaqueNonClientView()->
- GetWindowBoundsForClientBounds(contents_bounds);
- SetBounds(window_bounds);
-}
-
-gfx::Rect OpaqueFrame::GetBoundsForTabStrip(TabStrip* tabstrip) const {
- return GetOpaqueNonClientView()->GetBoundsForTabStrip(tabstrip);
-}
-
-void OpaqueFrame::UpdateThrobber(bool running) {
- // TODO(beng): pass |running| through rather than letting
- // OpaqueNonClientView's TabIconView try and figure it out.
- // The throbber doesn't run in the Windows TaskBar, so we just update the
- // non-client view. Updating the taskbar is muy expensivo.
- GetOpaqueNonClientView()->UpdateWindowIcon();
-}
-
-views::Window* OpaqueFrame::GetWindow() {
- return this;
-}
-
-const views::Window* OpaqueFrame::GetWindow() const {
- return this;
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// OpaqueFrame, views::CustomFrameWindow overrides:
-
-void OpaqueFrame::UpdateWindowIcon() {
- CustomFrameWindow::UpdateWindowIcon();
- GetOpaqueNonClientView()->UpdateWindowIcon();
-}
-
-int OpaqueFrame::GetShowState() const {
- return browser_view_->GetShowState();
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// OpaqueFrame, views::WidgetWin overrides:
-
-bool OpaqueFrame::AcceleratorPressed(views::Accelerator* accelerator) {
- return browser_view_->AcceleratorPressed(*accelerator);
-}
-
-bool OpaqueFrame::GetAccelerator(int cmd_id, views::Accelerator* accelerator) {
- return browser_view_->GetAccelerator(cmd_id, accelerator);
-}
-
-void OpaqueFrame::OnEndSession(BOOL ending, UINT logoff) {
- BrowserList::WindowsSessionEnding();
-}
-
-void OpaqueFrame::OnEnterSizeMove() {
- browser_view_->WindowMoveOrResizeStarted();
-}
-
-void OpaqueFrame::OnInitMenuPopup(HMENU menu, UINT position,
- BOOL is_system_menu) {
- browser_view_->PrepareToRunSystemMenu(menu);
-}
-
-LRESULT OpaqueFrame::OnMouseActivate(HWND window, UINT hittest_code,
- UINT message) {
- return browser_view_->ActivateAppModalDialog() ? MA_NOACTIVATEANDEAT
- : MA_ACTIVATE;
-}
-
-void OpaqueFrame::OnMove(const CPoint& point) {
- browser_view_->WindowMoved();
-}
-
-void OpaqueFrame::OnMoving(UINT param, const RECT* new_bounds) {
- browser_view_->WindowMoved();
-}
-
-LRESULT OpaqueFrame::OnNCActivate(BOOL active) {
- if (browser_view_->ActivateAppModalDialog())
- return TRUE;
-
- CustomFrameWindow::OnNCActivate(active);
- browser_view_->ActivationChanged(!!active);
- return TRUE;
-}
-
-void OpaqueFrame::OnSysCommand(UINT notification_code, CPoint click) {
- if (!browser_view_->SystemCommandReceived(notification_code,
- gfx::Point(click))) {
- // Use the default implementation for any other command.
- CustomFrameWindow::OnSysCommand(notification_code, click);
- }
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// OpaqueFrame, private:
-
-OpaqueNonClientView* OpaqueFrame::GetOpaqueNonClientView() const {
- // We can safely assume that this conversion is true.
- return static_cast<OpaqueNonClientView*>(non_client_view_);
-}
-
diff --git a/chrome/browser/views/frame/opaque_frame.h b/chrome/browser/views/frame/opaque_frame.h
deleted file mode 100644
index 7042002..0000000
--- a/chrome/browser/views/frame/opaque_frame.h
+++ /dev/null
@@ -1,74 +0,0 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROME_BROWSER_VIEWS_FRAME_OPAQUE_FRAME_H_
-#define CHROME_BROWSER_VIEWS_FRAME_OPAQUE_FRAME_H_
-
-#include "chrome/browser/views/frame/browser_frame.h"
-#include "chrome/views/custom_frame_window.h"
-
-class BrowserView;
-namespace views {
-class Window;
-}
-class OpaqueNonClientView;
-class TabStrip;
-
-///////////////////////////////////////////////////////////////////////////////
-// OpaqueFrame
-//
-// OpaqueFrame is a CustomFrameWindow subclass that in conjunction with
-// OpaqueNonClientView provides the window frame on Windows XP and on Windows
-// Vista when DWM desktop compositing is disabled. The window title and
-// borders are provided with bitmaps.
-//
-class OpaqueFrame : public BrowserFrame,
- public views::CustomFrameWindow {
- public:
- explicit OpaqueFrame(BrowserView* browser_view);
- virtual ~OpaqueFrame();
-
- void Init();
-
- protected:
- // Overridden from BrowserFrame:
- virtual gfx::Rect GetWindowBoundsForClientBounds(
- const gfx::Rect& client_bounds);
- virtual void SizeToContents(const gfx::Rect& contents_bounds);
- virtual gfx::Rect GetBoundsForTabStrip(TabStrip* tabstrip) const;
- virtual void UpdateThrobber(bool running);
- virtual views::Window* GetWindow();
- virtual const views::Window* GetWindow() const;
-
- // Overridden from views::CustomFrameWindow:
- virtual void UpdateWindowIcon();
- virtual int GetShowState() const;
- virtual bool IsAppWindow() const { return true; }
-
- // Overridden from views::WidgetWin:
- virtual bool AcceleratorPressed(views::Accelerator* accelerator);
- virtual bool GetAccelerator(int cmd_id, views::Accelerator* accelerator);
- virtual void OnEnterSizeMove();
- virtual void OnEndSession(BOOL ending, UINT logoff);
- virtual void OnInitMenuPopup(HMENU menu, UINT position, BOOL is_system_menu);
- virtual LRESULT OnMouseActivate(HWND window,
- UINT hittest_code,
- UINT message);
- virtual void OnMove(const CPoint& point);
- virtual void OnMoving(UINT param, const RECT* new_bounds);
- virtual LRESULT OnNCActivate(BOOL active);
- virtual void OnSysCommand(UINT notification_code, CPoint click);
-
- private:
- // Return a pointer to the concrete type of our non-client view.
- OpaqueNonClientView* GetOpaqueNonClientView() const;
-
- // The BrowserView is our ClientView. This is a pointer to it.
- BrowserView* browser_view_;
-
- DISALLOW_EVIL_CONSTRUCTORS(OpaqueFrame);
-};
-
-#endif // #ifndef CHROME_BROWSER_VIEWS_FRAME_OPAQUE_FRAME_H_
-
diff --git a/chrome/browser/views/hung_renderer_view.cc b/chrome/browser/views/hung_renderer_view.cc
index a539ea8..a293bb9 100644
--- a/chrome/browser/views/hung_renderer_view.cc
+++ b/chrome/browser/views/hung_renderer_view.cc
@@ -16,13 +16,13 @@
#include "chrome/common/logging_chrome.h"
#include "chrome/common/resource_bundle.h"
#include "chrome/views/client_view.h"
-#include "chrome/views/custom_frame_window.h"
#include "chrome/views/dialog_delegate.h"
#include "chrome/views/grid_layout.h"
#include "chrome/views/group_table_view.h"
#include "chrome/views/image_view.h"
#include "chrome/views/label.h"
#include "chrome/views/native_button.h"
+#include "chrome/views/window.h"
#include "grit/chromium_strings.h"
#include "grit/generated_resources.h"
#include "grit/theme_resources.h"
diff --git a/chrome/browser/views/info_bubble.cc b/chrome/browser/views/info_bubble.cc
index 3ab8ec0..8c030d6 100644
--- a/chrome/browser/views/info_bubble.cc
+++ b/chrome/browser/views/info_bubble.cc
@@ -100,7 +100,7 @@ void InfoBubble::Init(HWND parent_hwnd,
DCHECK(BrowserView::GetBrowserViewForHWND(owning_frame_hwnd));
parent_ = reinterpret_cast<views::Window*>(win_util::GetWindowUserData(
owning_frame_hwnd));
- parent_->DisableInactiveRendering(true);
+ parent_->DisableInactiveRendering();
if (kInfoBubbleCornerTopLeft == NULL) {
kInfoBubbleCornerTopLeft = ResourceBundle::GetSharedInstance()
@@ -207,7 +207,6 @@ void InfoBubble::Close(bool closed_by_escape) {
// We don't fade out because it looks terrible.
if (delegate_)
delegate_->InfoBubbleClosing(this, closed_by_escape);
- parent_->DisableInactiveRendering(false);
closed_ = true;
WidgetWin::Close();
}
diff --git a/chrome/browser/views/tabs/tab_renderer.cc b/chrome/browser/views/tabs/tab_renderer.cc
index cc7cf4c..1580d05 100644
--- a/chrome/browser/views/tabs/tab_renderer.cc
+++ b/chrome/browser/views/tabs/tab_renderer.cc
@@ -15,6 +15,7 @@
#include "chrome/common/l10n_util.h"
#include "chrome/common/resource_bundle.h"
#include "chrome/common/win_util.h"
+#include "chrome/views/window.h"
#include "grit/generated_resources.h"
#include "grit/theme_resources.h"
#include "skia/ext/image_operations.h"
@@ -78,6 +79,31 @@ static int download_icon_height = 0;
namespace {
+// Loads the images to be used for the tab background. Uses the images for
+// Vista if |use_vista_images| is true.
+void LoadTabImages(bool use_vista_images) {
+ ResourceBundle& rb = ResourceBundle::GetSharedInstance();
+ if (use_vista_images) {
+ tab_inactive_l = rb.GetBitmapNamed(IDR_TAB_INACTIVE_LEFT_V);
+ tab_inactive_c = rb.GetBitmapNamed(IDR_TAB_INACTIVE_CENTER_V);
+ tab_inactive_r = rb.GetBitmapNamed(IDR_TAB_INACTIVE_RIGHT_V);
+
+ // Our Vista frame doesn't change background color to show OTR,
+ // so we continue to use the existing background tabs.
+ tab_inactive_otr_l = rb.GetBitmapNamed(IDR_TAB_INACTIVE_LEFT_V);
+ tab_inactive_otr_c = rb.GetBitmapNamed(IDR_TAB_INACTIVE_CENTER_V);
+ tab_inactive_otr_r = rb.GetBitmapNamed(IDR_TAB_INACTIVE_RIGHT_V);
+ } else {
+ tab_inactive_l = rb.GetBitmapNamed(IDR_TAB_INACTIVE_LEFT);
+ tab_inactive_c = rb.GetBitmapNamed(IDR_TAB_INACTIVE_CENTER);
+ tab_inactive_r = rb.GetBitmapNamed(IDR_TAB_INACTIVE_RIGHT);
+
+ tab_inactive_otr_l = rb.GetBitmapNamed(IDR_TAB_INACTIVE_LEFT_OTR);
+ tab_inactive_otr_c = rb.GetBitmapNamed(IDR_TAB_INACTIVE_CENTER_OTR);
+ tab_inactive_otr_r = rb.GetBitmapNamed(IDR_TAB_INACTIVE_RIGHT_OTR);
+ }
+}
+
void InitResources() {
static bool initialized = false;
if (!initialized) {
@@ -97,25 +123,7 @@ void InitResources() {
tab_active_l_width = tab_active_l->width();
tab_active_r_width = tab_active_r->width();
- if (win_util::ShouldUseVistaFrame()) {
- tab_inactive_l = rb.GetBitmapNamed(IDR_TAB_INACTIVE_LEFT_V);
- tab_inactive_c = rb.GetBitmapNamed(IDR_TAB_INACTIVE_CENTER_V);
- tab_inactive_r = rb.GetBitmapNamed(IDR_TAB_INACTIVE_RIGHT_V);
-
- // Our Vista frame doesn't change background color to show OTR,
- // so we continue to use the existing background tabs.
- tab_inactive_otr_l = rb.GetBitmapNamed(IDR_TAB_INACTIVE_LEFT_V);
- tab_inactive_otr_c = rb.GetBitmapNamed(IDR_TAB_INACTIVE_CENTER_V);
- tab_inactive_otr_r = rb.GetBitmapNamed(IDR_TAB_INACTIVE_RIGHT_V);
- } else {
- tab_inactive_l = rb.GetBitmapNamed(IDR_TAB_INACTIVE_LEFT);
- tab_inactive_c = rb.GetBitmapNamed(IDR_TAB_INACTIVE_CENTER);
- tab_inactive_r = rb.GetBitmapNamed(IDR_TAB_INACTIVE_RIGHT);
-
- tab_inactive_otr_l = rb.GetBitmapNamed(IDR_TAB_INACTIVE_LEFT_OTR);
- tab_inactive_otr_c = rb.GetBitmapNamed(IDR_TAB_INACTIVE_CENTER_OTR);
- tab_inactive_otr_r = rb.GetBitmapNamed(IDR_TAB_INACTIVE_RIGHT_OTR);
- }
+ LoadTabImages(win_util::ShouldUseVistaFrame());
tab_hover_l = rb.GetBitmapNamed(IDR_TAB_HOVER_LEFT);
tab_hover_c = rb.GetBitmapNamed(IDR_TAB_HOVER_CENTER);
@@ -535,6 +543,12 @@ void TabRenderer::OnMouseExited(const views::MouseEvent& e) {
hover_animation_->Hide();
}
+void TabRenderer::ThemeChanged() {
+ if (GetWidget() && GetWidget()->AsWindow())
+ LoadTabImages(GetWidget()->AsWindow()->UseNativeFrame());
+ View::ThemeChanged();
+}
+
///////////////////////////////////////////////////////////////////////////////
// TabRenderer, AnimationDelegate implementation:
@@ -566,7 +580,7 @@ void TabRenderer::PaintTabBackground(ChromeCanvas* canvas) {
animation = pulse_animation_.get();
if (animation->GetCurrentValue() > 0) {
PaintHoverTabBackground(canvas, animation->GetCurrentValue() *
- (win_util::ShouldUseVistaFrame() ?
+ (GetWidget()->AsWindow()->UseNativeFrame() ?
kHoverOpacityVista : kHoverOpacity));
} else {
PaintInactiveTabBackground(canvas);
diff --git a/chrome/browser/views/tabs/tab_renderer.h b/chrome/browser/views/tabs/tab_renderer.h
index 9cad816..68df3e3 100644
--- a/chrome/browser/views/tabs/tab_renderer.h
+++ b/chrome/browser/views/tabs/tab_renderer.h
@@ -76,6 +76,7 @@ class TabRenderer : public views::View,
virtual void Layout();
virtual void OnMouseEntered(const views::MouseEvent& event);
virtual void OnMouseExited(const views::MouseEvent& event);
+ virtual void ThemeChanged();
// Overridden from AnimationDelegate:
virtual void AnimationProgressed(const Animation* animation);
@@ -166,6 +167,9 @@ class TabRenderer : public views::View,
bool should_display_crashed_favicon_;
+ static void InitClass();
+ static bool initialized_;
+
DISALLOW_EVIL_CONSTRUCTORS(TabRenderer);
};
diff --git a/chrome/browser/views/tabs/tab_strip.cc b/chrome/browser/views/tabs/tab_strip.cc
index fceb5af..e3ec025 100644
--- a/chrome/browser/views/tabs/tab_strip.cc
+++ b/chrome/browser/views/tabs/tab_strip.cc
@@ -25,6 +25,7 @@
#include "chrome/common/win_util.h"
#include "chrome/views/image_view.h"
#include "chrome/views/painter.h"
+#include "chrome/views/window.h"
#include "grit/generated_resources.h"
#include "grit/theme_resources.h"
@@ -618,7 +619,7 @@ void TabStrip::PaintChildren(ChromeCanvas* canvas) {
}
}
- if (win_util::ShouldUseVistaFrame()) {
+ if (GetWidget()->AsWindow()->UseNativeFrame()) {
// Make sure unselected tabs are somewhat transparent.
SkPaint paint;
paint.setColor(SkColorSetARGB(200, 255, 255, 255));
diff --git a/chrome/browser/views/toolbar_view.cc b/chrome/browser/views/toolbar_view.cc
index dd88eff..25c7161 100644
--- a/chrome/browser/views/toolbar_view.cc
+++ b/chrome/browser/views/toolbar_view.cc
@@ -47,7 +47,7 @@
#include "chrome/views/label.h"
#include "chrome/views/non_client_view.h"
#include "chrome/views/tooltip_manager.h"
-#include "chrome/views/widget.h"
+#include "chrome/views/window.h"
#include "grit/chromium_strings.h"
#include "grit/generated_resources.h"
#include "grit/theme_resources.h"
@@ -354,7 +354,7 @@ void BrowserToolbarView::Paint(ChromeCanvas* canvas) {
// For glass, we need to draw a black line below the location bar to separate
// it from the content area. For non-glass, the NonClientView draws the
// toolbar background below the location bar for us.
- if (win_util::ShouldUseVistaFrame())
+ if (GetWidget()->AsWindow()->UseNativeFrame())
canvas->FillRectInt(SK_ColorBLACK, 0, height() - 1, width(), 1);
}
@@ -497,8 +497,9 @@ gfx::Size BrowserToolbarView::GetPreferredSize() {
return gfx::Size(0, normal_background.height());
}
- int vertical_spacing = PopupTopSpacing() + (win_util::ShouldUseVistaFrame() ?
- kPopupBottomSpacingGlass : kPopupBottomSpacingNonGlass);
+ int vertical_spacing = PopupTopSpacing() +
+ (GetWidget()->AsWindow()->UseNativeFrame() ? kPopupBottomSpacingGlass
+ : kPopupBottomSpacingNonGlass);
return gfx::Size(0, location_bar_->GetPreferredSize().height() +
vertical_spacing);
}
@@ -806,7 +807,8 @@ void BrowserToolbarView::ButtonPressed(views::BaseButton* sender) {
// static
int BrowserToolbarView::PopupTopSpacing() {
- return win_util::ShouldUseVistaFrame() ? 0 : kPopupTopSpacingNonGlass;
+ return GetWidget()->AsWindow()->UseNativeFrame() ? 0
+ : kPopupTopSpacingNonGlass;
}
void BrowserToolbarView::Observe(NotificationType type,
diff --git a/chrome/browser/views/toolbar_view.h b/chrome/browser/views/toolbar_view.h
index 1712ef4..970b378 100644
--- a/chrome/browser/views/toolbar_view.h
+++ b/chrome/browser/views/toolbar_view.h
@@ -131,7 +131,7 @@ class BrowserToolbarView : public views::View,
};
// Returns the number of pixels above the location bar in non-normal display.
- static int PopupTopSpacing();
+ int PopupTopSpacing();
// NotificationObserver
virtual void Observe(NotificationType type,
diff --git a/chrome/views/default_non_client_view.cc b/chrome/views/custom_frame_view.cc
index e3998a5..54303f6 100644
--- a/chrome/views/default_non_client_view.cc
+++ b/chrome/views/custom_frame_view.cc
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "chrome/views/default_non_client_view.h"
+#include "chrome/views/custom_frame_view.h"
#include "base/win_util.h"
#include "chrome/common/gfx/path.h"
@@ -11,6 +11,7 @@
#include "chrome/common/resource_bundle.h"
#include "chrome/common/win_util.h"
#include "chrome/views/client_view.h"
+#include "chrome/views/window_delegate.h"
#include "grit/theme_resources.h"
namespace views {
@@ -165,9 +166,9 @@ SkBitmap* ActiveWindowResources::standard_frame_bitmaps_[];
SkBitmap* InactiveWindowResources::standard_frame_bitmaps_[];
// static
-WindowResources* DefaultNonClientView::active_resources_ = NULL;
-WindowResources* DefaultNonClientView::inactive_resources_ = NULL;
-ChromeFont DefaultNonClientView::title_font_;
+WindowResources* CustomFrameView::active_resources_ = NULL;
+WindowResources* CustomFrameView::inactive_resources_ = NULL;
+ChromeFont CustomFrameView::title_font_;
namespace {
// The frame border is only visible in restored mode and is hardcoded to 4 px on
@@ -214,19 +215,17 @@ const int kCaptionTopSpacing = 1;
}
///////////////////////////////////////////////////////////////////////////////
-// DefaultNonClientView, public:
+// CustomFrameView, public:
-DefaultNonClientView::DefaultNonClientView(
- CustomFrameWindow* container)
- : NonClientView(),
- client_view_(NULL),
+CustomFrameView::CustomFrameView(Window* frame)
+ : NonClientFrameView(),
close_button_(new Button),
restore_button_(new Button),
maximize_button_(new Button),
minimize_button_(new Button),
system_menu_button_(new Button),
should_show_minmax_buttons_(false),
- container_(container) {
+ frame_(frame) {
InitClass();
WindowResources* resources = active_resources_;
@@ -261,49 +260,39 @@ DefaultNonClientView::DefaultNonClientView(
minimize_button_->SetListener(this, -1);
AddChildView(minimize_button_);
- should_show_minmax_buttons_ = container->window_delegate()->CanMaximize();
+ should_show_minmax_buttons_ = frame_->window_delegate()->CanMaximize();
AddChildView(system_menu_button_);
}
-DefaultNonClientView::~DefaultNonClientView() {
+CustomFrameView::~CustomFrameView() {
}
///////////////////////////////////////////////////////////////////////////////
-// DefaultNonClientView, CustomFrameWindow::NonClientView implementation:
+// CustomFrameView, NonClientFrameView implementation:
-gfx::Rect DefaultNonClientView::CalculateClientAreaBounds(int width,
- int height) const {
- int top_height = NonClientTopBorderHeight();
- int border_thickness = NonClientBorderThickness();
- return gfx::Rect(border_thickness, top_height,
- std::max(0, width - (2 * border_thickness)),
- std::max(0, height - top_height - border_thickness));
+gfx::Rect CustomFrameView::GetBoundsForClientView() const {
+ return client_view_bounds_;
}
-gfx::Size DefaultNonClientView::CalculateWindowSizeForClientSize(
- int width,
- int height) const {
+gfx::Rect CustomFrameView::GetWindowBoundsForClientBounds(
+ const gfx::Rect& client_bounds) const {
+ int top_height = NonClientTopBorderHeight();
int border_thickness = NonClientBorderThickness();
- return gfx::Size(width + (2 * border_thickness),
- height + NonClientTopBorderHeight() + border_thickness);
+ return gfx::Rect(std::max(0, client_bounds.x() - border_thickness),
+ std::max(0, client_bounds.y() - top_height),
+ client_bounds.width() + (2 * border_thickness),
+ client_bounds.height() + top_height + border_thickness);
}
-gfx::Point DefaultNonClientView::GetSystemMenuPoint() const {
+gfx::Point CustomFrameView::GetSystemMenuPoint() const {
gfx::Point system_menu_point(FrameBorderThickness(),
NonClientTopBorderHeight() - BottomEdgeThicknessWithinNonClientHeight());
ConvertPointToScreen(this, &system_menu_point);
return system_menu_point;
}
-int DefaultNonClientView::NonClientHitTest(const gfx::Point& point) {
- if (!bounds().Contains(point))
- return HTNOWHERE;
-
- int frame_component = container_->client_view()->NonClientHitTest(point);
- if (frame_component != HTNOWHERE)
- return frame_component;
-
+int CustomFrameView::NonClientHitTest(const gfx::Point& point) {
// Then see if the point is within any of the window controls.
if (close_button_->GetBounds(APPLY_MIRRORING_TRANSFORMATION).Contains(point))
return HTCLOSE;
@@ -322,13 +311,13 @@ int DefaultNonClientView::NonClientHitTest(const gfx::Point& point) {
int window_component = GetHTComponentForFrame(point, FrameBorderThickness(),
NonClientBorderThickness(), kResizeAreaCornerSize, kResizeAreaCornerSize,
- container_->window_delegate()->CanResize());
+ frame_->window_delegate()->CanResize());
// Fall back to the caption if no other component matches.
return (window_component == HTNOWHERE) ? HTCAPTION : window_component;
}
-void DefaultNonClientView::GetWindowMask(const gfx::Size& size,
- gfx::Path* window_mask) {
+void CustomFrameView::GetWindowMask(const gfx::Size& size,
+ gfx::Path* window_mask) {
DCHECK(window_mask);
// Redefine the window visible region for the new size.
@@ -350,11 +339,11 @@ void DefaultNonClientView::GetWindowMask(const gfx::Size& size,
window_mask->close();
}
-void DefaultNonClientView::EnableClose(bool enable) {
+void CustomFrameView::EnableClose(bool enable) {
close_button_->SetEnabled(enable);
}
-void DefaultNonClientView::ResetWindowControls() {
+void CustomFrameView::ResetWindowControls() {
restore_button_->SetState(Button::BS_NORMAL);
minimize_button_->SetState(Button::BS_NORMAL);
maximize_button_->SetState(Button::BS_NORMAL);
@@ -362,79 +351,71 @@ void DefaultNonClientView::ResetWindowControls() {
}
///////////////////////////////////////////////////////////////////////////////
-// DefaultNonClientView, View overrides:
+// CustomFrameView, View overrides:
-void DefaultNonClientView::Paint(ChromeCanvas* canvas) {
- if (container_->IsMaximized())
+void CustomFrameView::Paint(ChromeCanvas* canvas) {
+ if (frame_->IsMaximized())
PaintMaximizedFrameBorder(canvas);
else
PaintRestoredFrameBorder(canvas);
PaintTitleBar(canvas);
- if (!container_->IsMaximized())
+ if (!frame_->IsMaximized())
PaintRestoredClientEdge(canvas);
}
-void DefaultNonClientView::Layout() {
+void CustomFrameView::Layout() {
LayoutWindowControls();
LayoutTitleBar();
LayoutClientView();
}
-gfx::Size DefaultNonClientView::GetPreferredSize() {
- gfx::Size pref = client_view_->GetPreferredSize();
+gfx::Size CustomFrameView::GetPreferredSize() {
+ gfx::Size pref = frame_->client_view()->GetPreferredSize();
DCHECK(pref.width() > 0 && pref.height() > 0);
- return CalculateWindowSizeForClientSize(pref.width(), pref.height());
-}
-
-void DefaultNonClientView::ViewHierarchyChanged(bool is_add,
- View* parent,
- View* child) {
- // Add our Client View as we are added to the Widget so that if we are
- // subsequently resized all the parent-child relationships are established.
- if (is_add && GetWidget() && child == this)
- AddChildView(container_->client_view());
+ gfx::Rect bounds(0, 0, pref.width(), pref.height());
+ return frame_->GetWindowBoundsForClientBounds(bounds).size();
}
///////////////////////////////////////////////////////////////////////////////
-// DefaultNonClientView, BaseButton::ButtonListener implementation:
+// CustomFrameView, BaseButton::ButtonListener implementation:
-void DefaultNonClientView::ButtonPressed(BaseButton* sender) {
+void CustomFrameView::ButtonPressed(BaseButton* sender) {
if (sender == close_button_)
- container_->ExecuteSystemMenuCommand(SC_CLOSE);
+ frame_->ExecuteSystemMenuCommand(SC_CLOSE);
else if (sender == minimize_button_)
- container_->ExecuteSystemMenuCommand(SC_MINIMIZE);
+ frame_->ExecuteSystemMenuCommand(SC_MINIMIZE);
else if (sender == maximize_button_)
- container_->ExecuteSystemMenuCommand(SC_MAXIMIZE);
+ frame_->ExecuteSystemMenuCommand(SC_MAXIMIZE);
else if (sender == restore_button_)
- container_->ExecuteSystemMenuCommand(SC_RESTORE);
+ frame_->ExecuteSystemMenuCommand(SC_RESTORE);
}
///////////////////////////////////////////////////////////////////////////////
-// DefaultNonClientView, private:
+// CustomFrameView, private:
-int DefaultNonClientView::FrameBorderThickness() const {
- return container_->IsMaximized() ?
+int CustomFrameView::FrameBorderThickness() const {
+ return frame_->IsMaximized() ?
GetSystemMetrics(SM_CXSIZEFRAME) : kFrameBorderThickness;
}
-int DefaultNonClientView::NonClientBorderThickness() const {
+int CustomFrameView::NonClientBorderThickness() const {
// In maximized mode, we don't show a client edge.
return FrameBorderThickness() +
- (container_->IsMaximized() ? 0 : kClientEdgeThickness);
+ (frame_->IsMaximized() ? 0 : kClientEdgeThickness);
}
-int DefaultNonClientView::NonClientTopBorderHeight() const {
+int CustomFrameView::NonClientTopBorderHeight() const {
int title_top_spacing, title_thickness;
return TitleCoordinates(&title_top_spacing, &title_thickness);
}
-int DefaultNonClientView::BottomEdgeThicknessWithinNonClientHeight() const {
+int CustomFrameView::BottomEdgeThicknessWithinNonClientHeight() const {
return kFrameShadowThickness +
- (container_->IsMaximized() ? 0 : kClientEdgeThickness);
+ (frame_->IsMaximized() ? 0 : kClientEdgeThickness);
}
-int DefaultNonClientView::TitleCoordinates(int* title_top_spacing,
- int* title_thickness) const {
+int CustomFrameView::TitleCoordinates(int* title_top_spacing,
+ int* title_thickness) const {
int frame_thickness = FrameBorderThickness();
int min_titlebar_height = kTitlebarMinimumHeight + frame_thickness;
*title_top_spacing = frame_thickness + kTitleTopSpacing;
@@ -445,7 +426,7 @@ int DefaultNonClientView::TitleCoordinates(int* title_top_spacing,
// since while it's part of the bottom spacing it will be added in at the end.
int title_bottom_spacing =
kFrameBorderThickness + kTitleTopSpacing - kFrameShadowThickness;
- if (container_->IsMaximized()) {
+ if (frame_->IsMaximized()) {
// When we maximize, the top border appears to be chopped off; shift the
// title down to stay centered within the remaining space.
int title_adjust = (kFrameBorderThickness / 2);
@@ -458,7 +439,7 @@ int DefaultNonClientView::TitleCoordinates(int* title_top_spacing,
BottomEdgeThicknessWithinNonClientHeight();
}
-void DefaultNonClientView::PaintRestoredFrameBorder(ChromeCanvas* canvas) {
+void CustomFrameView::PaintRestoredFrameBorder(ChromeCanvas* canvas) {
SkBitmap* top_left_corner = resources()->GetPartBitmap(FRAME_TOP_LEFT_CORNER);
SkBitmap* top_right_corner =
resources()->GetPartBitmap(FRAME_TOP_RIGHT_CORNER);
@@ -502,7 +483,7 @@ void DefaultNonClientView::PaintRestoredFrameBorder(ChromeCanvas* canvas) {
height() - top_left_corner->height() - bottom_left_corner->height());
}
-void DefaultNonClientView::PaintMaximizedFrameBorder(
+void CustomFrameView::PaintMaximizedFrameBorder(
ChromeCanvas* canvas) {
SkBitmap* top_edge = resources()->GetPartBitmap(FRAME_TOP_EDGE);
canvas->TileImageInt(*top_edge, 0, FrameBorderThickness(), width(),
@@ -513,11 +494,11 @@ void DefaultNonClientView::PaintMaximizedFrameBorder(
SkBitmap* titlebar_bottom = resources()->GetPartBitmap(FRAME_CLIENT_EDGE_TOP);
int edge_height = titlebar_bottom->height() - kClientEdgeThickness;
canvas->TileImageInt(*titlebar_bottom, 0,
- container_->client_view()->y() - edge_height, width(), edge_height);
+ frame_->client_view()->y() - edge_height, width(), edge_height);
}
-void DefaultNonClientView::PaintTitleBar(ChromeCanvas* canvas) {
- WindowDelegate* d = container_->window_delegate();
+void CustomFrameView::PaintTitleBar(ChromeCanvas* canvas) {
+ WindowDelegate* d = frame_->window_delegate();
// It seems like in some conditions we can be asked to paint after the window
// that contains us is WM_DESTROYed. At this point, our delegate is NULL. The
@@ -530,8 +511,8 @@ void DefaultNonClientView::PaintTitleBar(ChromeCanvas* canvas) {
title_bounds_.width(), title_bounds_.height());
}
-void DefaultNonClientView::PaintRestoredClientEdge(ChromeCanvas* canvas) {
- gfx::Rect client_area_bounds = container_->client_view()->bounds();
+void CustomFrameView::PaintRestoredClientEdge(ChromeCanvas* canvas) {
+ gfx::Rect client_area_bounds = frame_->client_view()->bounds();
int client_area_top = client_area_bounds.y();
SkBitmap* top_left = resources()->GetPartBitmap(FRAME_CLIENT_EDGE_TOP_LEFT);
@@ -577,11 +558,11 @@ void DefaultNonClientView::PaintRestoredClientEdge(ChromeCanvas* canvas) {
client_area_top, left->width(), client_area_height);
}
-void DefaultNonClientView::LayoutWindowControls() {
+void CustomFrameView::LayoutWindowControls() {
close_button_->SetImageAlignment(Button::ALIGN_LEFT, Button::ALIGN_BOTTOM);
// Maximized buttons start at window top so that even if their images aren't
// drawn flush with the screen edge, they still obey Fitts' Law.
- bool is_maximized = container_->IsMaximized();
+ bool is_maximized = frame_->IsMaximized();
int frame_thickness = FrameBorderThickness();
int caption_y = is_maximized ? frame_thickness : kCaptionTopSpacing;
int top_extra_height = is_maximized ? kCaptionTopSpacing : 0;
@@ -600,7 +581,7 @@ void DefaultNonClientView::LayoutWindowControls() {
// When the window is restored, we show a maximized button; otherwise, we show
// a restore button.
- bool is_restored = !is_maximized && !container_->IsMinimized();
+ bool is_restored = !is_maximized && !frame_->IsMinimized();
views::Button* invisible_button = is_restored ?
restore_button_ : maximize_button_;
invisible_button->SetVisible(false);
@@ -645,7 +626,7 @@ void DefaultNonClientView::LayoutWindowControls() {
active_resources_->GetPartBitmap(pushed_part));
}
-void DefaultNonClientView::LayoutTitleBar() {
+void CustomFrameView::LayoutTitleBar() {
// Always lay out the icon, even when it's not present, so we can lay out the
// window title based on its position.
int frame_thickness = FrameBorderThickness();
@@ -671,10 +652,10 @@ void DefaultNonClientView::LayoutTitleBar() {
// the remaining space. Because the apparent shape of our border is simpler,
// using the same positioning makes things look slightly uncentered with
// restored windows, so we come up to compensate.
- if (!container_->IsMaximized())
+ if (!frame_->IsMaximized())
icon_y -= kIconRestoredAdjust;
- views::WindowDelegate* d = container_->window_delegate();
+ views::WindowDelegate* d = frame_->window_delegate();
if (!d->ShouldShowWindowIcon())
icon_size = 0;
system_menu_button_->SetBounds(icon_x, icon_y, icon_size, icon_size);
@@ -690,13 +671,18 @@ void DefaultNonClientView::LayoutTitleBar() {
std::max(0, title_right - title_x), title_font_.height());
}
-void DefaultNonClientView::LayoutClientView() {
- container_->client_view()->SetBounds(CalculateClientAreaBounds(width(),
- height()));
+void CustomFrameView::LayoutClientView() {
+ int top_height = NonClientTopBorderHeight();
+ int border_thickness = NonClientBorderThickness();
+ client_view_bounds_.SetRect(
+ border_thickness,
+ top_height,
+ std::max(0, width() - (2 * border_thickness)),
+ std::max(0, height() - top_height - border_thickness));
}
// static
-void DefaultNonClientView::InitClass() {
+void CustomFrameView::InitClass() {
static bool initialized = false;
if (!initialized) {
active_resources_ = new ActiveWindowResources;
@@ -709,3 +695,4 @@ void DefaultNonClientView::InitClass() {
}
} // namespace views
+
diff --git a/chrome/views/default_non_client_view.h b/chrome/views/custom_frame_view.h
index 2c46fca..0a34f2d 100644
--- a/chrome/views/default_non_client_view.h
+++ b/chrome/views/custom_frame_view.h
@@ -2,13 +2,12 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef CHROME_VIEWS_DEFAULT_NON_CLIENT_VIEW_H_
-#define CHROME_VIEWS_DEFAULT_NON_CLIENT_VIEW_H_
+#ifndef CHROME_VIEWS_CUSTOM_FRAME_VIEW_H_
+#define CHROME_VIEWS_CUSTOM_FRAME_VIEW_H_
-#include "base/basictypes.h"
#include "chrome/views/button.h"
-#include "chrome/views/custom_frame_window.h"
#include "chrome/views/non_client_view.h"
+#include "chrome/views/window.h"
#include "chrome/views/window_resources.h"
namespace gfx{
@@ -21,26 +20,24 @@ class ChromeFont;
namespace views {
-class ClientView;
-
///////////////////////////////////////////////////////////////////////////////
//
-// DefaultNonClientView
+// CustomFrameView
//
-// A ChromeView that provides the "frame" for CustomFrameWindows. This means
+// A ChromeView that provides the non client frame for Windows. This means
// rendering the non-standard window caption, border, and controls.
//
////////////////////////////////////////////////////////////////////////////////
-class DefaultNonClientView : public NonClientView,
- public BaseButton::ButtonListener {
+class CustomFrameView : public NonClientFrameView,
+ public BaseButton::ButtonListener {
public:
- explicit DefaultNonClientView(CustomFrameWindow* container);
- virtual ~DefaultNonClientView();
+ explicit CustomFrameView(Window* frame);
+ virtual ~CustomFrameView();
- // Overridden from views::NonClientView:
- virtual gfx::Rect CalculateClientAreaBounds(int width, int height) const;
- virtual gfx::Size CalculateWindowSizeForClientSize(int width,
- int height) const;
+ // Overridden from views::NonClientFrameView:
+ virtual gfx::Rect GetBoundsForClientView() const;
+ virtual gfx::Rect GetWindowBoundsForClientBounds(
+ const gfx::Rect& client_bounds) const;
virtual gfx::Point GetSystemMenuPoint() const;
virtual int NonClientHitTest(const gfx::Point& point);
virtual void GetWindowMask(const gfx::Size& size, gfx::Path* window_mask);
@@ -51,7 +48,6 @@ class DefaultNonClientView : public NonClientView,
virtual void Paint(ChromeCanvas* canvas);
virtual void Layout();
virtual gfx::Size GetPreferredSize();
- virtual void ViewHierarchyChanged(bool is_add, View* parent, View* child);
// BaseButton::ButtonListener implementation:
virtual void ButtonPressed(BaseButton* sender);
@@ -91,14 +87,12 @@ class DefaultNonClientView : public NonClientView,
// Returns the resource collection to be used when rendering the window.
WindowResources* resources() const {
- return container_->is_active() || paint_as_active() ? active_resources_
- : inactive_resources_;
+ return frame_->is_active() || paint_as_active() ? active_resources_
+ : inactive_resources_;
}
- // The View that provides the background for the window, and optionally
- // dialog buttons. Note: the non-client view does _not_ own this view, the
- // container does.
- ClientView* client_view_;
+ // The bounds of the client view, in this view's coordinates.
+ gfx::Rect client_view_bounds_;
// The layout rect of the title, if visible.
gfx::Rect title_bounds_;
@@ -112,7 +106,7 @@ class DefaultNonClientView : public NonClientView,
bool should_show_minmax_buttons_;
// The window that owns this view.
- CustomFrameWindow* container_;
+ Window* frame_;
// Initialize various static resources.
static void InitClass();
@@ -120,9 +114,10 @@ class DefaultNonClientView : public NonClientView,
static WindowResources* inactive_resources_;
static ChromeFont title_font_;
- DISALLOW_COPY_AND_ASSIGN(DefaultNonClientView);
+ DISALLOW_EVIL_CONSTRUCTORS(CustomFrameView);
};
} // namespace views
-#endif // CHROME_VIEWS_DEFAULT_NON_CLIENT_VIEW_H_
+#endif // #ifndef CHROME_VIEWS_CUSTOM_FRAME_VIEW_H_
+
diff --git a/chrome/views/custom_frame_window.cc b/chrome/views/custom_frame_window.cc
deleted file mode 100644
index 0ae6158..0000000
--- a/chrome/views/custom_frame_window.cc
+++ /dev/null
@@ -1,506 +0,0 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/views/custom_frame_window.h"
-
-#include "base/gfx/point.h"
-#include "base/gfx/size.h"
-#include "chrome/common/gfx/chrome_canvas.h"
-#include "chrome/common/gfx/path.h"
-#include "chrome/common/l10n_util.h"
-#include "chrome/common/win_util.h"
-#include "chrome/views/client_view.h"
-#include "chrome/views/default_non_client_view.h"
-#include "chrome/views/root_view.h"
-#include "chrome/views/window_delegate.h"
-#include "grit/generated_resources.h"
-
-namespace views {
-
-// A scoping class that prevents a window from being able to redraw in response
-// to invalidations that may occur within it for the lifetime of the object.
-//
-// Why would we want such a thing? Well, it turns out Windows has some
-// "unorthodox" behavior when it comes to painting its non-client areas.
-// Occasionally, Windows will paint portions of the default non-client area
-// right over the top of the custom frame. This is not simply fixed by handling
-// WM_NCPAINT/WM_PAINT, with some investigation it turns out that this
-// rendering is being done *inside* the default implementation of some message
-// handlers and functions:
-// . WM_SETTEXT
-// . WM_SETICON
-// . WM_NCLBUTTONDOWN
-// . EnableMenuItem, called from our WM_INITMENU handler
-// The solution is to handle these messages and call DefWindowProc ourselves,
-// but prevent the window from being able to update itself for the duration of
-// the call. We do this with this class, which automatically calls its
-// associated CustomFrameWindow's lock and unlock functions as it is created
-// and destroyed. See documentation in those methods for the technique used.
-//
-// IMPORTANT: Do not use this scoping object for large scopes or periods of
-// time! IT WILL PREVENT THE WINDOW FROM BEING REDRAWN! (duh).
-//
-// I would love to hear Raymond Chen's explanation for all this. And maybe a
-// list of other messages that this applies to ;-)
-class CustomFrameWindow::ScopedRedrawLock {
- public:
- explicit ScopedRedrawLock(CustomFrameWindow* window) : window_(window) {
- window_->LockUpdates();
- }
-
- ~ScopedRedrawLock() {
- window_->UnlockUpdates();
- }
-
- private:
- // The window having its style changed.
- CustomFrameWindow* window_;
-};
-
-HCURSOR CustomFrameWindow::resize_cursors_[6];
-
-///////////////////////////////////////////////////////////////////////////////
-// CustomFrameWindow, public:
-
-CustomFrameWindow::CustomFrameWindow(WindowDelegate* window_delegate)
- : Window(window_delegate),
- is_active_(false),
- lock_updates_(false),
- saved_window_style_(0) {
- InitClass();
- non_client_view_ = new DefaultNonClientView(this);
-}
-
-CustomFrameWindow::CustomFrameWindow(WindowDelegate* window_delegate,
- NonClientView* non_client_view)
- : Window(window_delegate) {
- InitClass();
- non_client_view_ = non_client_view;
-}
-
-CustomFrameWindow::~CustomFrameWindow() {
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// CustomFrameWindow, Window overrides:
-
-void CustomFrameWindow::Init(HWND parent, const gfx::Rect& bounds) {
- // TODO(beng): (Cleanup) Right now, the only way to specify a different
- // non-client view is to subclass this object and provide one
- // by setting this member before calling Init.
- if (!non_client_view_)
- non_client_view_ = new DefaultNonClientView(this);
- Window::Init(parent, bounds);
-
- ResetWindowRegion();
-}
-
-void CustomFrameWindow::UpdateWindowTitle() {
- // Layout winds up causing the title to be re-validated during
- // string measurement.
- non_client_view_->Layout();
- // Must call the base class too so that places like the Task Bar get updated.
- Window::UpdateWindowTitle();
-}
-
-void CustomFrameWindow::UpdateWindowIcon() {
- // The icon will be re-validated during painting.
- non_client_view_->SchedulePaint();
- // Call the base class so that places like the Task Bar get updated.
- Window::UpdateWindowIcon();
-}
-
-void CustomFrameWindow::EnableClose(bool enable) {
- non_client_view_->EnableClose(enable);
- // Make sure the SysMenu changes to reflect this change as well.
- Window::EnableClose(enable);
-}
-
-void CustomFrameWindow::DisableInactiveRendering(bool disable) {
- Window::DisableInactiveRendering(disable);
- non_client_view_->set_paint_as_active(disable);
- if (!disable)
- non_client_view_->SchedulePaint();
-}
-
-void CustomFrameWindow::SizeWindowToDefault() {
- gfx::Size pref = client_view()->GetPreferredSize();
- DCHECK(pref.width() > 0 && pref.height() > 0);
- gfx::Size window_size =
- non_client_view_->CalculateWindowSizeForClientSize(pref.width(),
- pref.height());
- win_util::CenterAndSizeWindow(owning_window(), GetHWND(),
- window_size.ToSIZE(), false);
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// CustomFrameWindow, WidgetWin overrides:
-
-static void EnableMenuItem(HMENU menu, UINT command, bool enabled) {
- UINT flags = MF_BYCOMMAND | (enabled ? MF_ENABLED : MF_DISABLED | MF_GRAYED);
- EnableMenuItem(menu, command, flags);
-}
-
-void CustomFrameWindow::OnInitMenu(HMENU menu) {
- bool is_minimized = IsMinimized();
- bool is_maximized = IsMaximized();
- bool is_restored = !is_minimized && !is_maximized;
-
- ScopedRedrawLock lock(this);
- EnableMenuItem(menu, SC_RESTORE, !is_restored);
- EnableMenuItem(menu, SC_MOVE, is_restored);
- EnableMenuItem(menu, SC_SIZE, window_delegate()->CanResize() && is_restored);
- EnableMenuItem(menu, SC_MAXIMIZE,
- window_delegate()->CanMaximize() && !is_maximized);
- EnableMenuItem(menu, SC_MINIMIZE,
- window_delegate()->CanMaximize() && !is_minimized);
-}
-
-void CustomFrameWindow::OnMouseLeave() {
- bool process_mouse_exited = true;
- POINT pt;
- if (GetCursorPos(&pt)) {
- LRESULT ht_component =
- ::SendMessage(GetHWND(), WM_NCHITTEST, 0, MAKELPARAM(pt.x, pt.y));
- if (ht_component != HTNOWHERE) {
- // If the mouse moved into a part of the window's non-client area, then
- // don't send a mouse exited event since the mouse is still within the
- // bounds of the ChromeView that's rendering the frame. Note that we do
- // _NOT_ do this for windows with native frames, since in that case the
- // mouse really will have left the bounds of the RootView.
- process_mouse_exited = false;
- }
- }
-
- if (process_mouse_exited)
- ProcessMouseExited();
-}
-
-LRESULT CustomFrameWindow::OnNCActivate(BOOL active) {
- is_active_ = !!active;
-
- // We can get WM_NCACTIVATE before we're actually visible. If we're not
- // visible, no need to paint.
- if (IsWindowVisible(GetHWND())) {
- non_client_view_->SchedulePaint();
- // We need to force a paint now, as a user dragging a window will block
- // painting operations while the move is in progress.
- PaintNow(root_view_->GetScheduledPaintRect());
- }
-
- // Defering to our parent as it is important that the NCActivate message gets
- // DefProc'ed or the task bar won't show our process as active.
- // See bug http://crbug.com/4513.
- return Window::OnNCActivate(active);
-}
-
-LRESULT CustomFrameWindow::OnNCCalcSize(BOOL mode, LPARAM l_param) {
- // We need to repaint all when the window bounds change.
- return WVR_REDRAW;
-}
-
-LRESULT CustomFrameWindow::OnNCHitTest(const CPoint& point) {
- // NC points are in screen coordinates.
- CPoint temp = point;
- MapWindowPoints(HWND_DESKTOP, GetHWND(), &temp, 1);
- return non_client_view_->NonClientHitTest(gfx::Point(temp.x, temp.y));
-}
-
-struct ClipState {
- // The window being painted.
- HWND parent;
-
- // DC painting to.
- HDC dc;
-
- // Origin of the window in terms of the screen.
- int x;
- int y;
-};
-
-// See comments in OnNCPaint for details of this function.
-static BOOL CALLBACK ClipDCToChild(HWND window, LPARAM param) {
- ClipState* clip_state = reinterpret_cast<ClipState*>(param);
- if (GetParent(window) == clip_state->parent && IsWindowVisible(window)) {
- RECT bounds;
- GetWindowRect(window, &bounds);
- ExcludeClipRect(clip_state->dc,
- bounds.left - clip_state->x,
- bounds.top - clip_state->y,
- bounds.right - clip_state->x,
- bounds.bottom - clip_state->y);
- }
- return TRUE;
-}
-
-void CustomFrameWindow::OnNCPaint(HRGN rgn) {
- // We have an NC region and need to paint it. We expand the NC region to
- // include the dirty region of the root view. This is done to minimize
- // paints.
- CRect window_rect;
- GetWindowRect(&window_rect);
-
- if (window_rect.Width() != root_view_->width() ||
- window_rect.Height() != root_view_->height()) {
- // If the size of the window differs from the size of the root view it
- // means we're being asked to paint before we've gotten a WM_SIZE. This can
- // happen when the user is interactively resizing the window. To avoid
- // mass flickering we don't do anything here. Once we get the WM_SIZE we'll
- // reset the region of the window which triggers another WM_NCPAINT and
- // all is well.
- return;
- }
-
- CRect dirty_region;
- // A value of 1 indicates paint all.
- if (!rgn || rgn == reinterpret_cast<HRGN>(1)) {
- dirty_region = CRect(0, 0, window_rect.Width(), window_rect.Height());
- } else {
- RECT rgn_bounding_box;
- GetRgnBox(rgn, &rgn_bounding_box);
- if (!IntersectRect(&dirty_region, &rgn_bounding_box, &window_rect))
- return; // Dirty region doesn't intersect window bounds, bale.
-
- // rgn_bounding_box is in screen coordinates. Map it to window coordinates.
- OffsetRect(&dirty_region, -window_rect.left, -window_rect.top);
- }
-
- // In theory GetDCEx should do what we want, but I couldn't get it to work.
- // In particular the docs mentiond DCX_CLIPCHILDREN, but as far as I can tell
- // it doesn't work at all. So, instead we get the DC for the window then
- // manually clip out the children.
- HDC dc = GetWindowDC(GetHWND());
- ClipState clip_state;
- clip_state.x = window_rect.left;
- clip_state.y = window_rect.top;
- clip_state.parent = GetHWND();
- clip_state.dc = dc;
- EnumChildWindows(GetHWND(), &ClipDCToChild,
- reinterpret_cast<LPARAM>(&clip_state));
-
- RootView* root_view = GetRootView();
- CRect old_paint_region = root_view->GetScheduledPaintRectConstrainedToSize();
-
- if (!old_paint_region.IsRectEmpty()) {
- // The root view has a region that needs to be painted. Include it in the
- // region we're going to paint.
-
- CRect tmp = dirty_region;
- UnionRect(&dirty_region, &tmp, &old_paint_region);
- }
-
- root_view->SchedulePaint(gfx::Rect(dirty_region), false);
-
- // ChromeCanvasPaints destructor does the actual painting. As such, wrap the
- // following in a block to force paint to occur so that we can release the dc.
- {
- ChromeCanvasPaint canvas(dc, opaque(), dirty_region.left, dirty_region.top,
- dirty_region.Width(), dirty_region.Height());
-
- root_view->ProcessPaint(&canvas);
- }
-
- ReleaseDC(GetHWND(), dc);
-}
-
-void CustomFrameWindow::OnNCLButtonDown(UINT ht_component,
- const CPoint& point) {
- switch (ht_component) {
- case HTCLOSE:
- case HTMINBUTTON:
- case HTMAXBUTTON: {
- // When the mouse is pressed down in these specific non-client areas, we
- // need to tell the RootView to send the mouse pressed event (which sets
- // capture, allowing subsequent WM_LBUTTONUP (note, _not_ WM_NCLBUTTONUP)
- // to fire so that the appropriate WM_SYSCOMMAND can be sent by the
- // applicable button's ButtonListener. We _have_ to do this this way
- // rather than letting Windows just send the syscommand itself (as would
- // happen if we never did this dance) because for some insane reason
- // DefWindowProc for WM_NCLBUTTONDOWN also renders the pressed window
- // control button appearance, in the Windows classic style, over our
- // view! Ick! By handling this message we prevent Windows from doing this
- // undesirable thing, but that means we need to roll the sys-command
- // handling ourselves.
- ProcessNCMousePress(point, MK_LBUTTON);
- return;
- }
- default:
- Window::OnNCLButtonDown(ht_component, point);
- /*
- if (!IsMsgHandled()) {
- // Window::OnNCLButtonDown set the message as unhandled. This normally
- // means WidgetWin::ProcessWindowMessage will pass it to
- // DefWindowProc. Sadly, DefWindowProc for WM_NCLBUTTONDOWN does weird
- // non-client painting, so we need to call it directly here inside a
- // scoped update lock.
- ScopedRedrawLock lock(this);
- DefWindowProc(GetHWND(), WM_NCLBUTTONDOWN, ht_component,
- MAKELPARAM(point.x, point.y));
- SetMsgHandled(TRUE);
- }
- */
- break;
- }
-}
-
-LRESULT CustomFrameWindow::OnNCUAHDrawCaption(UINT msg, WPARAM w_param,
- LPARAM l_param) {
- // See comment in widget_win.h at the definition of WM_NCUAHDRAWCAPTION for
- // an explanation about why we need to handle this message.
- SetMsgHandled(TRUE);
- return 0;
-}
-
-LRESULT CustomFrameWindow::OnNCUAHDrawFrame(UINT msg, WPARAM w_param,
- LPARAM l_param) {
- // See comment in widget_win.h at the definition of WM_NCUAHDRAWCAPTION for
- // an explanation about why we need to handle this message.
- SetMsgHandled(TRUE);
- return 0;
-}
-
-LRESULT CustomFrameWindow::OnSetCursor(HWND window, UINT hittest_code,
- UINT message) {
- int index = RC_NORMAL;
- switch (hittest_code) {
- case HTTOP:
- case HTBOTTOM:
- index = RC_VERTICAL;
- break;
- case HTTOPLEFT:
- case HTBOTTOMRIGHT:
- index = RC_NWSE;
- break;
- case HTTOPRIGHT:
- case HTBOTTOMLEFT:
- index = RC_NESW;
- break;
- case HTLEFT:
- case HTRIGHT:
- index = RC_HORIZONTAL;
- break;
- case HTCAPTION:
- case HTCLIENT:
- index = RC_NORMAL;
- break;
- }
- SetCursor(resize_cursors_[index]);
- return 0;
-}
-
-LRESULT CustomFrameWindow::OnSetIcon(UINT size_type, HICON new_icon) {
- ScopedRedrawLock lock(this);
- return DefWindowProc(GetHWND(), WM_SETICON, size_type,
- reinterpret_cast<LPARAM>(new_icon));
-}
-
-LRESULT CustomFrameWindow::OnSetText(const wchar_t* text) {
- ScopedRedrawLock lock(this);
- return DefWindowProc(GetHWND(), WM_SETTEXT, NULL,
- reinterpret_cast<LPARAM>(text));
-}
-
-void CustomFrameWindow::OnSize(UINT param, const CSize& size) {
- Window::OnSize(param, size);
-
- // ResetWindowRegion is going to trigger WM_NCPAINT. By doing it after we've
- // invoked OnSize we ensure the RootView has been layed out.
- ResetWindowRegion();
-}
-
-void CustomFrameWindow::OnSysCommand(UINT notification_code, CPoint click) {
- // Windows uses the 4 lower order bits of |notification_code| for type-
- // specific information so we must exclude this when comparing.
- static const int sc_mask = 0xFFF0;
- if ((notification_code & sc_mask) == SC_MINIMIZE ||
- (notification_code & sc_mask) == SC_MAXIMIZE ||
- (notification_code & sc_mask) == SC_RESTORE) {
- non_client_view_->ResetWindowControls();
- } else if ((notification_code & sc_mask) == SC_MOVE ||
- (notification_code & sc_mask) == SC_SIZE) {
- if (lock_updates_) {
- // We were locked, before entering a resize or move modal loop. Now that
- // we've begun to move the window, we need to unlock updates so that the
- // sizing/moving feedback can be continuous.
- UnlockUpdates();
- }
- }
- Window::OnSysCommand(notification_code, click);
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// CustomFrameWindow, private:
-
-// static
-void CustomFrameWindow::InitClass() {
- static bool initialized = false;
- if (!initialized) {
- resize_cursors_[RC_NORMAL] = LoadCursor(NULL, IDC_ARROW);
- resize_cursors_[RC_VERTICAL] = LoadCursor(NULL, IDC_SIZENS);
- resize_cursors_[RC_HORIZONTAL] = LoadCursor(NULL, IDC_SIZEWE);
- resize_cursors_[RC_NESW] = LoadCursor(NULL, IDC_SIZENESW);
- resize_cursors_[RC_NWSE] = LoadCursor(NULL, IDC_SIZENWSE);
- initialized = true;
- }
-}
-
-void CustomFrameWindow::LockUpdates() {
- lock_updates_ = true;
- saved_window_style_ = GetWindowLong(GetHWND(), GWL_STYLE);
- SetWindowLong(GetHWND(), GWL_STYLE, saved_window_style_ & ~WS_VISIBLE);
-}
-
-void CustomFrameWindow::UnlockUpdates() {
- SetWindowLong(GetHWND(), GWL_STYLE, saved_window_style_);
- lock_updates_ = false;
-}
-
-void CustomFrameWindow::ResetWindowRegion() {
- // Changing the window region is going to force a paint. Only change the
- // window region if the region really differs.
- HRGN current_rgn = CreateRectRgn(0, 0, 0, 0);
- int current_rgn_result = GetWindowRgn(GetHWND(), current_rgn);
-
- CRect window_rect;
- GetWindowRect(&window_rect);
- HRGN new_region;
- if (IsMaximized()) {
- HMONITOR monitor = MonitorFromWindow(GetHWND(), MONITOR_DEFAULTTONEAREST);
- MONITORINFO mi;
- mi.cbSize = sizeof mi;
- GetMonitorInfo(monitor, &mi);
- CRect work_rect = mi.rcWork;
- work_rect.OffsetRect(-window_rect.left, -window_rect.top);
- new_region = CreateRectRgnIndirect(&work_rect);
- } else {
- gfx::Path window_mask;
- non_client_view_->GetWindowMask(gfx::Size(window_rect.Width(),
- window_rect.Height()),
- &window_mask);
- new_region = window_mask.CreateHRGN();
- }
-
- if (current_rgn_result == ERROR || !EqualRgn(current_rgn, new_region)) {
- // SetWindowRgn takes ownership of the HRGN created by CreateHRGN.
- SetWindowRgn(new_region, TRUE);
- } else {
- DeleteObject(new_region);
- }
-
- DeleteObject(current_rgn);
-}
-
-void CustomFrameWindow::ProcessNCMousePress(const CPoint& point, int flags) {
- CPoint temp = point;
- MapWindowPoints(HWND_DESKTOP, GetHWND(), &temp, 1);
- UINT message_flags = 0;
- if ((GetKeyState(VK_CONTROL) & 0x80) == 0x80)
- message_flags |= MK_CONTROL;
- if ((GetKeyState(VK_SHIFT) & 0x80) == 0x80)
- message_flags |= MK_SHIFT;
- message_flags |= flags;
- ProcessMousePressed(temp, message_flags, false, false);
-}
-
-} // namespace views
diff --git a/chrome/views/custom_frame_window.h b/chrome/views/custom_frame_window.h
deleted file mode 100644
index f5b6334..0000000
--- a/chrome/views/custom_frame_window.h
+++ /dev/null
@@ -1,103 +0,0 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROME_VIEWS_CUSTOM_FRAME_WINDOW_H__
-#define CHROME_VIEWS_CUSTOM_FRAME_WINDOW_H__
-
-#include "chrome/common/gfx/chrome_canvas.h"
-#include "chrome/views/window.h"
-#include "chrome/views/window_delegate.h"
-
-namespace views {
-
-class NonClientView;
-
-////////////////////////////////////////////////////////////////////////////////
-//
-// CustomFrameWindow
-//
-// A CustomFrameWindow is a Window subclass that implements the Chrome-style
-// window frame used on Windows XP and Vista without DWM Composition.
-// See documentation in window.h for more information about the capabilities
-// of this window type.
-//
-////////////////////////////////////////////////////////////////////////////////
-class CustomFrameWindow : public Window {
- public:
- explicit CustomFrameWindow(WindowDelegate* window_delegate);
- CustomFrameWindow(WindowDelegate* window_delegate,
- NonClientView* non_client_view);
- virtual ~CustomFrameWindow();
-
- // Returns whether or not the frame is active.
- bool is_active() const { return is_active_; }
-
- // Overridden from Window:
- virtual void Init(HWND parent, const gfx::Rect& bounds);
- virtual void UpdateWindowTitle();
- virtual void UpdateWindowIcon();
-
- protected:
- // Overridden from Window:
- virtual void SizeWindowToDefault();
- virtual void EnableClose(bool enable);
- virtual void DisableInactiveRendering(bool disable);
-
- // Overridden from WidgetWin:
- virtual void OnInitMenu(HMENU menu);
- virtual void OnMouseLeave();
- virtual LRESULT OnNCActivate(BOOL active);
- virtual LRESULT OnNCCalcSize(BOOL mode, LPARAM l_param);
- virtual LRESULT OnNCHitTest(const CPoint& point);
- virtual void OnNCPaint(HRGN rgn);
- virtual void OnNCLButtonDown(UINT ht_component, const CPoint& point);
- virtual LRESULT OnNCUAHDrawCaption(UINT msg, WPARAM w_param, LPARAM l_param);
- virtual LRESULT OnNCUAHDrawFrame(UINT msg, WPARAM w_param, LPARAM l_param);
- virtual LRESULT OnSetCursor(HWND window, UINT hittest_code, UINT message);
- virtual LRESULT OnSetIcon(UINT size_type, HICON new_icon);
- virtual LRESULT OnSetText(const wchar_t* text);
- virtual void OnSize(UINT param, const CSize& size);
- virtual void OnSysCommand(UINT notification_code, CPoint click);
-
- private:
- class ScopedRedrawLock;
-
- // Lock or unlock the window from being able to redraw itself in response to
- // updates to its invalid region.
- void LockUpdates();
- void UnlockUpdates();
-
- // Resets the window region.
- void ResetWindowRegion();
-
- // Converts a non-client mouse down message to a regular ChromeViews event
- // and handle it. |point| is the mouse position of the message in screen
- // coords. |flags| are flags that would be passed with a WM_L/M/RBUTTON*
- // message and relate to things like which button was pressed. These are
- // combined with flags relating to the current key state.
- void ProcessNCMousePress(const CPoint& point, int flags);
-
- // True if this window is the active top level window.
- bool is_active_;
-
- // True if updates to this window are currently locked.
- bool lock_updates_;
-
- // The window styles of the window before updates were locked.
- DWORD saved_window_style_;
-
- // Static resource initialization.
- static void InitClass();
- enum ResizeCursor {
- RC_NORMAL = 0, RC_VERTICAL, RC_HORIZONTAL, RC_NESW, RC_NWSE
- };
- static HCURSOR resize_cursors_[6];
-
- DISALLOW_EVIL_CONSTRUCTORS(CustomFrameWindow);
-};
-
-} // namespace views
-
-#endif // CHROME_VIEWS_CUSTOM_FRAME_WINDOW_H__
-
diff --git a/chrome/views/native_frame_view.cc b/chrome/views/native_frame_view.cc
new file mode 100644
index 0000000..04f3448
--- /dev/null
+++ b/chrome/views/native_frame_view.cc
@@ -0,0 +1,61 @@
+// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/views/native_frame_view.h"
+
+#include "chrome/views/window.h"
+
+namespace views {
+
+////////////////////////////////////////////////////////////////////////////////
+// NativeFrameView, public:
+
+NativeFrameView::NativeFrameView(Window* frame)
+ : NonClientFrameView(),
+ frame_(frame) {
+}
+
+NativeFrameView::~NativeFrameView() {
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// NativeFrameView, NonClientFrameView overrides:
+
+gfx::Rect NativeFrameView::GetBoundsForClientView() const {
+ return gfx::Rect(0, 0, width(), height());
+}
+
+gfx::Rect NativeFrameView::GetWindowBoundsForClientBounds(
+ const gfx::Rect& client_bounds) const {
+ RECT rect = client_bounds.ToRECT();
+ AdjustWindowRectEx(&rect, frame_->window_style(), FALSE,
+ frame_->window_ex_style());
+ return gfx::Rect(rect);
+}
+
+gfx::Point NativeFrameView::GetSystemMenuPoint() const {
+ POINT temp = {0, -kFrameShadowThickness };
+ MapWindowPoints(frame_->GetHWND(), HWND_DESKTOP, &temp, 1);
+ return gfx::Point(temp);
+}
+
+int NativeFrameView::NonClientHitTest(const gfx::Point& point) {
+ return HTNOWHERE;
+}
+
+void NativeFrameView::GetWindowMask(const gfx::Size& size,
+ gfx::Path* window_mask) {
+ // Nothing to do, we use the default window mask.
+}
+
+void NativeFrameView::EnableClose(bool enable) {
+ // Nothing to do, handled automatically by Window.
+}
+
+void NativeFrameView::ResetWindowControls() {
+ // Nothing to do.
+}
+
+} // namespace views
+
diff --git a/chrome/views/native_frame_view.h b/chrome/views/native_frame_view.h
new file mode 100644
index 0000000..aa599ff
--- /dev/null
+++ b/chrome/views/native_frame_view.h
@@ -0,0 +1,38 @@
+// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_VIEWS_NATIVE_FRAME_VIEW_H_
+#define CHROME_VIEWS_NATIVE_FRAME_VIEW_H_
+
+#include "chrome/views/non_client_view.h"
+
+namespace views {
+
+class NativeFrameView : public NonClientFrameView {
+ public:
+ explicit NativeFrameView(Window* frame);
+ virtual ~NativeFrameView();
+
+ // NonClientFrameView overrides:
+ virtual gfx::Rect GetBoundsForClientView() const;
+ virtual gfx::Rect GetWindowBoundsForClientBounds(
+ const gfx::Rect& client_bounds) const;
+ virtual gfx::Point GetSystemMenuPoint() const;
+ virtual int NonClientHitTest(const gfx::Point& point);
+ virtual void GetWindowMask(const gfx::Size& size,
+ gfx::Path* window_mask);
+ virtual void EnableClose(bool enable);
+ virtual void ResetWindowControls();
+
+ private:
+ // Our containing frame.
+ Window* frame_;
+
+ DISALLOW_COPY_AND_ASSIGN(NativeFrameView);
+};
+
+} // namespace views
+
+#endif // #ifndef CHROME_VIEWS_NATIVE_FRAME_VIEW_H_
+
diff --git a/chrome/views/non_client_view.cc b/chrome/views/non_client_view.cc
index bb89cb5..166042d 100644
--- a/chrome/views/non_client_view.cc
+++ b/chrome/views/non_client_view.cc
@@ -3,20 +3,46 @@
// found in the LICENSE file.
#include "chrome/views/non_client_view.h"
-#include "chrome/views/widget.h"
+
+#include "chrome/common/win_util.h"
+#include "chrome/views/root_view.h"
+#include "chrome/views/window.h"
namespace views {
-const int NonClientView::kFrameShadowThickness = 1;
-const int NonClientView::kClientEdgeThickness = 1;
+const int NonClientFrameView::kFrameShadowThickness = 1;
+const int NonClientFrameView::kClientEdgeThickness = 1;
+
+// The frame view and the client view are always at these specific indices,
+// because the RootView message dispatch sends messages to items higher in the
+// z-order first and we always want the client view to have first crack at
+// handling mouse messages.
+static const int kFrameViewIndex = 0;
+static const int kClientViewIndex = 1;
////////////////////////////////////////////////////////////////////////////////
// NonClientView, public:
-NonClientView::NonClientView() : paint_as_active_(false) {
+NonClientView::NonClientView(Window* frame)
+ : frame_(frame),
+ client_view_(NULL),
+ use_native_frame_(win_util::ShouldUseVistaFrame()) {
}
NonClientView::~NonClientView() {
+ // This value may have been reset before the window hierarchy shuts down,
+ // so we need to manually remove it.
+ RemoveChildView(frame_view_.get());
+}
+
+void NonClientView::SetFrameView(NonClientFrameView* frame_view) {
+ // See comment in header about ownership.
+ frame_view->SetParentOwned(false);
+ if (frame_view_.get())
+ RemoveChildView(frame_view_.get());
+ frame_view_.reset(frame_view);
+ if (GetParent())
+ AddChildView(kFrameViewIndex, frame_view_.get());
}
bool NonClientView::CanClose() const {
@@ -27,41 +53,84 @@ void NonClientView::WindowClosing() {
client_view_->WindowClosing();
}
+void NonClientView::SystemThemeChanged() {
+ // 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(frame_->GetHWND(), &saved_window_placement);
+ frame_->Hide();
+
+ 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(frame_->GetHWND(), &saved_window_placement);
+}
+
+void NonClientView::SetUseNativeFrame(bool use_native_frame) {
+ use_native_frame_ = use_native_frame;
+ SetFrameView(frame_->CreateFrameViewForWindow());
+ GetRootView()->ThemeChanged();
+ Layout();
+ SchedulePaint();
+ frame_->UpdateFrameAfterFrameChange();
+}
+
bool NonClientView::UseNativeFrame() const {
- return true;
+ // 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_;
}
-gfx::Rect NonClientView::CalculateClientAreaBounds(int width,
- int height) const {
- return gfx::Rect();
+void NonClientView::DisableInactiveRendering(bool disable) {
+ frame_view_->DisableInactiveRendering(disable);
}
-gfx::Size NonClientView::CalculateWindowSizeForClientSize(int width,
- int height) const {
- return gfx::Size();
+gfx::Rect NonClientView::GetWindowBoundsForClientBounds(
+ const gfx::Rect client_bounds) const {
+ return frame_view_->GetWindowBoundsForClientBounds(client_bounds);
}
gfx::Point NonClientView::GetSystemMenuPoint() const {
- CPoint temp(0, -kFrameShadowThickness);
- MapWindowPoints(GetWidget()->GetHWND(), HWND_DESKTOP, &temp, 1);
- return gfx::Point(temp);
+ return frame_view_->GetSystemMenuPoint();
}
int NonClientView::NonClientHitTest(const gfx::Point& point) {
- return client_view_->NonClientHitTest(point);
+ // Sanity check.
+ if (!bounds().Contains(point))
+ return HTNOWHERE;
+
+ // The ClientView gets first crack, since it overlays the NonClientFrameView
+ // in the display stack.
+ int frame_component = client_view_->NonClientHitTest(point);
+ if (frame_component != HTNOWHERE)
+ return frame_component;
+
+ // Finally ask the NonClientFrameView. It's at the back of the display stack
+ // so it gets asked last.
+ return frame_view_->NonClientHitTest(point);
}
void NonClientView::GetWindowMask(const gfx::Size& size,
gfx::Path* window_mask) {
+ frame_view_->GetWindowMask(size, window_mask);
}
void NonClientView::EnableClose(bool enable) {
+ frame_view_->EnableClose(enable);
}
void NonClientView::ResetWindowControls() {
+ frame_view_->ResetWindowControls();
}
-
////////////////////////////////////////////////////////////////////////////////
// NonClientView, View overrides:
@@ -70,26 +139,34 @@ gfx::Size NonClientView::GetPreferredSize() {
}
void NonClientView::Layout() {
- client_view_->SetBounds(0, 0, width(), height());
+ // First layout the NonClientFrameView, which determines the size of the
+ // ClientView...
+ frame_view_->SetBounds(0, 0, width(), height());
+
+ // Then layout the ClientView, using those bounds.
+ client_view_->SetBounds(frame_view_->GetBoundsForClientView());
}
void NonClientView::ViewHierarchyChanged(bool is_add, View* parent,
View* child) {
- // Add our Client View as we are added to the Widget so that if we are
- // subsequently resized all the parent-child relationships are established.
- if (is_add && GetWidget() && child == this)
- AddChildView(client_view_);
+ // Add our two child views here as we are added to the Widget so that if we
+ // are subsequently resized all the parent-child relationships are
+ // established.
+ if (is_add && GetWidget() && child == this) {
+ AddChildView(kFrameViewIndex, frame_view_.get());
+ AddChildView(kClientViewIndex, client_view_);
+ }
}
////////////////////////////////////////////////////////////////////////////////
-// NonClientView, protected:
-
-int NonClientView::GetHTComponentForFrame(const gfx::Point& point,
- int top_resize_border_height,
- int resize_border_thickness,
- int top_resize_corner_height,
- int resize_corner_width,
- bool can_resize) {
+// NonClientFrameView, protected:
+
+int NonClientFrameView::GetHTComponentForFrame(const gfx::Point& point,
+ int top_resize_border_height,
+ int resize_border_thickness,
+ int top_resize_corner_height,
+ int resize_corner_width,
+ bool can_resize) {
// Tricky: In XP, native behavior is to return HTTOPLEFT and HTTOPRIGHT for
// a |resize_corner_size|-length strip of both the side and top borders, but
// only to return HTBOTTOMLEFT/HTBOTTOMRIGHT along the bottom border + corner
diff --git a/chrome/views/non_client_view.h b/chrome/views/non_client_view.h
index 1887c2e..f801d6f 100644
--- a/chrome/views/non_client_view.h
+++ b/chrome/views/non_client_view.h
@@ -5,6 +5,7 @@
#ifndef CHROME_VIEWS_NON_CLIENT_VIEW_H_
#define CHROME_VIEWS_NON_CLIENT_VIEW_H_
+#include "base/task.h"
#include "chrome/views/view.h"
#include "chrome/views/client_view.h"
@@ -14,21 +15,15 @@ class Path;
namespace views {
-///////////////////////////////////////////////////////////////////////////////
-// NonClientView
-//
-// An object implementing the NonClientView interface is a View that provides
-// the "non-client" areas of a window. This is the area that typically
-// encompasses the window frame - title bar, sizing borders and window
-// controls. This interface provides methods that allow a specific
-// presentation to define non-client areas for windows hit testing, the shape
-// of the window, and other window-related information.
+////////////////////////////////////////////////////////////////////////////////
+// NonClientFrameView
//
-class NonClientView : public View {
+// An object that subclasses NonClientFrameView is a View that renders and
+// responds to events within the frame portions of the non-client area of a
+// window. This view does _not_ contain the ClientView, but rather is a sibling
+// of it.
+class NonClientFrameView : public views::View {
public:
- NonClientView();
- virtual ~NonClientView();
-
// Various edges of the frame border have a 1 px shadow along their edges; in
// a few cases we shift elements based on this amount for visual appeal.
static const int kFrameShadowThickness;
@@ -36,6 +31,99 @@ class NonClientView : public View {
// frame border.
static const int kClientEdgeThickness;
+ void DisableInactiveRendering(bool disable) {
+ paint_as_active_ = disable;
+ if (!paint_as_active_)
+ SchedulePaint();
+ }
+
+ // Returns the bounds (in this View's parent's coordinates) that the client
+ // view should be laid out within.
+ virtual gfx::Rect GetBoundsForClientView() const = 0;
+
+ // Returns true if this FrameView should always use the custom frame,
+ // regardless of the system settings. An example is the Constrained Window,
+ // which is a child window and must always provide its own frame.
+ virtual bool AlwaysUseCustomFrame() const { return false; }
+
+ virtual gfx::Rect GetWindowBoundsForClientBounds(
+ const gfx::Rect& client_bounds) const = 0;
+ virtual gfx::Point GetSystemMenuPoint() const = 0;
+ virtual int NonClientHitTest(const gfx::Point& point) = 0;
+ virtual void GetWindowMask(const gfx::Size& size,
+ gfx::Path* window_mask) = 0;
+ virtual void EnableClose(bool enable) = 0;
+ virtual void ResetWindowControls() = 0;
+
+ protected:
+ NonClientFrameView() : paint_as_active_(false) {}
+
+
+ // Helper for non-client view implementations to determine which area of the
+ // window border the specified |point| falls within. The other parameters are
+ // the size of the sizing edges, and whether or not the window can be
+ // resized.
+ int GetHTComponentForFrame(const gfx::Point& point,
+ int top_resize_border_height,
+ int resize_border_thickness,
+ int top_resize_corner_height,
+ int resize_corner_width,
+ bool can_resize);
+
+ // Accessor for paint_as_active_.
+ bool paint_as_active() const { return paint_as_active_; }
+
+ private:
+ // True when the non-client view should always be rendered as if the window
+ // were active, regardless of whether or not the top level window actually
+ // is active.
+ bool paint_as_active_;
+};
+
+////////////////////////////////////////////////////////////////////////////////
+// NonClientView
+//
+// The NonClientView is the logical root of all Views contained within a
+// Window, except for the RootView which is its parent and of which it is the
+// sole child. The NonClientView has two children, the NonClientFrameView which
+// is responsible for painting and responding to events from the non-client
+// portions of the window, and the ClientView, which is responsible for the
+// same for the client area of the window:
+//
+// +- views::Window ------------------------------------+
+// | +- views::RootView ------------------------------+ |
+// | | +- views::NonClientView ---------------------+ | |
+// | | | +- views::NonClientFrameView subclass ---+ | | |
+// | | | | | | | |
+// | | | | << all painting and event receiving >> | | | |
+// | | | | << of the non-client areas of a >> | | | |
+// | | | | << views::Window. >> | | | |
+// | | | | | | | |
+// | | | +----------------------------------------+ | | |
+// | | | +- views::ClientView or subclass --------+ | | |
+// | | | | | | | |
+// | | | | << all painting and event receiving >> | | | |
+// | | | | << of the client areas of a >> | | | |
+// | | | | << views::Window. >> | | | |
+// | | | | | | | |
+// | | | +----------------------------------------+ | | |
+// | | +--------------------------------------------+ | |
+// | +------------------------------------------------+ |
+// +----------------------------------------------------+
+//
+// The NonClientFrameView and ClientView are siblings because due to theme
+// changes the NonClientFrameView may be replaced with different
+// implementations (e.g. during the switch from DWM/Aero-Glass to Vista Basic/
+// Classic rendering).
+//
+class NonClientView : public View {
+ public:
+ explicit NonClientView(Window* frame);
+ virtual ~NonClientView();
+
+ // Replaces the current NonClientFrameView (if any) with the specified one.
+ void SetFrameView(NonClientFrameView* frame_view);
+
// Returns true if the ClientView determines that the containing window can be
// closed, false otherwise.
bool CanClose() const;
@@ -43,48 +131,52 @@ class NonClientView : public View {
// Called by the containing Window when it is closed.
void WindowClosing();
+ // Called by the window when it receives a theme changed notification. Changes
+ // the content of the NonClientView to match what is required for the current
+ // system theme.
+ void SystemThemeChanged();
+
+ // Changes the frame from native to custom depending on the value of
+ // |use_native_frame|.
+ void SetUseNativeFrame(bool use_native_frame);
+
// Returns true if the native window frame should be used, false if the
// NonClientView provides its own frame implementation.
bool UseNativeFrame() const;
- // Calculates the bounds of the client area of the window assuming the
- // window is sized to |width| and |height|.
- virtual gfx::Rect CalculateClientAreaBounds(int width, int height) const;
+ // Prevents the window from being rendered as deactivated when |disable| is
+ // true, until called with |disable| false. Used when a sub-window is to be
+ // shown that shouldn't visually de-activate the window.
+ // Subclasses can override this to perform additional actions when this value
+ // changes.
+ void DisableInactiveRendering(bool disable);
- // Calculates the size of window required to display a client area of the
- // specified width and height.
- virtual gfx::Size CalculateWindowSizeForClientSize(int width,
- int height) const;
+ // Returns the bounds of the window required to display the content area at
+ // the specified bounds.
+ gfx::Rect GetWindowBoundsForClientBounds(const gfx::Rect client_bounds) const;
// Returns the point, in screen coordinates, where the system menu should
// be shown so it shows up anchored to the system menu icon.
- virtual gfx::Point GetSystemMenuPoint() const;
+ gfx::Point GetSystemMenuPoint() const;
// Determines the windows HT* code when the mouse cursor is at the
// specified point, in window coordinates.
- virtual int NonClientHitTest(const gfx::Point& point);
+ int NonClientHitTest(const gfx::Point& point);
// Returns a mask to be used to clip the top level window for the given
// size. This is used to create the non-rectangular window shape.
- virtual void GetWindowMask(const gfx::Size& size,
- gfx::Path* window_mask);
+ void GetWindowMask(const gfx::Size& size, gfx::Path* window_mask);
// Toggles the enable state for the Close button (and the Close menu item in
// the system menu).
- virtual void EnableClose(bool enable);
+ void EnableClose(bool enable);
// Tells the window controls as rendered by the NonClientView to reset
// themselves to a normal state. This happens in situations where the
// containing window does not receive a normal sequences of messages that
// would lead to the controls returning to this normal state naturally, e.g.
// when the window is maximized, minimized or restored.
- virtual void ResetWindowControls();
-
- // Prevents the non-client view from rendering as inactive when called with
- // |disable| true, until called with false.
- void set_paint_as_active(bool paint_as_active) {
- paint_as_active_ = paint_as_active;
- }
+ void ResetWindowControls();
// Get/Set client_view property.
ClientView* client_view() const { return client_view_; }
@@ -100,30 +192,24 @@ class NonClientView : public View {
// NonClientView, View overrides:
virtual void ViewHierarchyChanged(bool is_add, View* parent, View* child);
- // Helper for non-client view implementations to determine which area of the
- // window border the specified |point| falls within. The other parameters are
- // the size of the sizing edges, and whether or not the window can be
- // resized.
- int GetHTComponentForFrame(const gfx::Point& point,
- int top_resize_border_height,
- int resize_border_thickness,
- int top_resize_corner_height,
- int resize_corner_width,
- bool can_resize);
-
- // Accessor for paint_as_active_.
- bool paint_as_active() const { return paint_as_active_; }
-
private:
+ // The frame that hosts this NonClientView.
+ Window* frame_;
+
// A ClientView object or subclass, responsible for sizing the contents view
// of the window, hit testing and perhaps other tasks depending on the
// implementation.
ClientView* client_view_;
- // True when the non-client view should always be rendered as if the window
- // were active, regardless of whether or not the top level window actually
- // is active.
- bool paint_as_active_;
+ // The NonClientFrameView that renders the non-client portions of the window.
+ // This object is not owned by the view hierarchy because it can be replaced
+ // 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);
};
} // namespace views
diff --git a/chrome/views/root_view.cc b/chrome/views/root_view.cc
index dfff6e4..8955732 100644
--- a/chrome/views/root_view.cc
+++ b/chrome/views/root_view.cc
@@ -220,6 +220,10 @@ Widget* RootView::GetWidget() const {
return widget_;
}
+void RootView::ThemeChanged() {
+ View::ThemeChanged();
+}
+
/////////////////////////////////////////////////////////////////////////////
//
// RootView - event dispatch and propagation
diff --git a/chrome/views/root_view.h b/chrome/views/root_view.h
index 6538625..103b06d 100644
--- a/chrome/views/root_view.h
+++ b/chrome/views/root_view.h
@@ -83,6 +83,10 @@ class RootView : public View,
// Get the Widget that hosts this View.
virtual Widget* GetWidget() const;
+ // Public API for broadcasting theme change notifications to this View
+ // hierarchy.
+ virtual void ThemeChanged();
+
// The following event methods are overridden to propagate event to the
// control tree
virtual bool OnMousePressed(const MouseEvent& e);
diff --git a/chrome/views/view.cc b/chrome/views/view.cc
index d435ddb..395eabc 100644
--- a/chrome/views/view.cc
+++ b/chrome/views/view.cc
@@ -626,6 +626,12 @@ void View::PropagateAddNotifications(View* parent, View* child) {
ViewHierarchyChangedImpl(true, true, parent, child);
}
+void View::ThemeChanged() {
+ int c = GetChildViewCount();
+ for (int i = c - 1; i >= 0; --i)
+ GetChildViewAt(i)->ThemeChanged();
+}
+
#ifndef NDEBUG
bool View::IsProcessingPaint() const {
return GetParent() && GetParent()->IsProcessingPaint();
diff --git a/chrome/views/view.h b/chrome/views/view.h
index aee08a3..824eb3f 100644
--- a/chrome/views/view.h
+++ b/chrome/views/view.h
@@ -995,6 +995,14 @@ class View : public AcceleratorTarget {
// to find other radio buttons.
int group_;
+ // Called when the UI theme has changed, overriding allows individual Views to
+ // do special cleanup and processing (such as dropping resource caches).
+ // Subclasses that override this method must call the base class
+ // implementation to ensure child views are processed.
+ // Can only be called by subclasses. To dispatch a theme changed notification,
+ // call this method on the RootView.
+ virtual void ThemeChanged();
+
#ifndef NDEBUG
// Returns true if the View is currently processing a paint.
virtual bool IsProcessingPaint() const;
diff --git a/chrome/views/views.vcproj b/chrome/views/views.vcproj
index e937b47..cbc6cd8 100644
--- a/chrome/views/views.vcproj
+++ b/chrome/views/views.vcproj
@@ -254,11 +254,11 @@
>
</File>
<File
- RelativePath=".\custom_frame_window.cc"
+ RelativePath=".\custom_frame_view.cc"
>
</File>
<File
- RelativePath=".\custom_frame_window.h"
+ RelativePath=".\custom_frame_view.h"
>
</File>
<File
@@ -270,14 +270,6 @@
>
</File>
<File
- RelativePath=".\default_non_client_view.cc"
- >
- </File>
- <File
- RelativePath=".\default_non_client_view.h"
- >
- </File>
- <File
RelativePath=".\dialog_client_view.cc"
>
</File>
@@ -418,6 +410,14 @@
>
</File>
<File
+ RelativePath=".\native_frame_view.cc"
+ >
+ </File>
+ <File
+ RelativePath=".\native_frame_view.h"
+ >
+ </File>
+ <File
RelativePath=".\native_scroll_bar.cc"
>
</File>
diff --git a/chrome/views/widget.h b/chrome/views/widget.h
index d135860..0dab65f 100644
--- a/chrome/views/widget.h
+++ b/chrome/views/widget.h
@@ -16,9 +16,10 @@ class Rect;
namespace views {
+class Accelerator;
class RootView;
class TooltipManager;
-class Accelerator;
+class Window;
////////////////////////////////////////////////////////////////////////////////
//
@@ -77,6 +78,11 @@ class Widget {
// no accelerator associated with a given id, which is a common condition.
virtual bool GetAccelerator(int cmd_id,
Accelerator* accelerator) = 0;
+
+ // Returns the Widget as a Window, if such a conversion is possible, or NULL
+ // if it is not.
+ virtual Window* AsWindow() { return NULL; }
+ virtual const Window* AsWindow() const { return NULL; }
};
} // namespace views
diff --git a/chrome/views/widget_win.cc b/chrome/views/widget_win.cc
index 9568a64..0d7edf4 100644
--- a/chrome/views/widget_win.cc
+++ b/chrome/views/widget_win.cc
@@ -566,7 +566,7 @@ void WidgetWin::OnMouseMove(UINT flags, const CPoint& point) {
ProcessMouseMoved(point, flags, false);
}
-LRESULT WidgetWin::OnMouseLeave(UINT uMsg, WPARAM w_param, LPARAM l_param) {
+LRESULT WidgetWin::OnMouseLeave(UINT message, WPARAM w_param, LPARAM l_param) {
tooltip_manager_->OnMouseLeave();
ProcessMouseExited();
return 0;
diff --git a/chrome/views/widget_win.h b/chrome/views/widget_win.h
index 97f9fe4..546e9f7 100644
--- a/chrome/views/widget_win.h
+++ b/chrome/views/widget_win.h
@@ -176,6 +176,9 @@ class WidgetWin : public Widget,
MESSAGE_HANDLER_EX(WM_NCUAHDRAWCAPTION, OnNCUAHDrawCaption)
MESSAGE_HANDLER_EX(WM_NCUAHDRAWFRAME, OnNCUAHDrawFrame)
+ // Vista and newer
+ MESSAGE_HANDLER_EX(WM_DWMCOMPOSITIONCHANGED, OnDwmCompositionChanged)
+
// Non-atlcrack.h handlers
MESSAGE_HANDLER_EX(WM_GETOBJECT, OnGetObject)
MESSAGE_HANDLER_EX(WM_NCMOUSELEAVE, OnNCMouseLeave)
@@ -183,6 +186,7 @@ class WidgetWin : public Widget,
// This list is in _ALPHABETICAL_ order! OR I WILL HURT YOU.
MSG_WM_ACTIVATE(OnActivate)
+ MSG_WM_ACTIVATEAPP(OnActivateApp)
MSG_WM_APPCOMMAND(OnAppCommand)
MSG_WM_CANCELMODE(OnCancelMode)
MSG_WM_CAPTURECHANGED(OnCaptureChanged)
@@ -347,7 +351,12 @@ class WidgetWin : public Widget,
// handling to the appropriate Process* function. This is so that
// subclasses can easily override these methods to do different things
// and have a convenient function to call to get the default behavior.
- virtual void OnActivate(UINT action, BOOL minimized, HWND window) { }
+ virtual void OnActivate(UINT action, BOOL minimized, HWND window) {
+ SetMsgHandled(FALSE);
+ }
+ virtual void OnActivateApp(BOOL active, DWORD thread_id) {
+ SetMsgHandled(FALSE);
+ }
virtual LRESULT OnAppCommand(HWND window, short app_command, WORD device,
int keystate) {
SetMsgHandled(FALSE);
@@ -362,6 +371,12 @@ class WidgetWin : public Widget,
// WARNING: If you override this be sure and invoke super, otherwise we'll
// leak a few things.
virtual void OnDestroy();
+ virtual LRESULT OnDwmCompositionChanged(UINT msg,
+ WPARAM w_param,
+ LPARAM l_param) {
+ SetMsgHandled(FALSE);
+ return 0;
+ }
virtual void OnEndSession(BOOL ending, UINT logoff) { SetMsgHandled(FALSE); }
virtual void OnEnterSizeMove() { SetMsgHandled(FALSE); }
virtual void OnExitMenuLoop(BOOL is_track_popup_menu) { SetMsgHandled(FALSE); }
@@ -384,7 +399,7 @@ class WidgetWin : public Widget,
virtual void OnMButtonUp(UINT flags, const CPoint& point);
virtual LRESULT OnMouseActivate(HWND window, UINT hittest_code, UINT message);
virtual void OnMouseMove(UINT flags, const CPoint& point);
- virtual LRESULT OnMouseLeave(UINT uMsg, WPARAM w_param, LPARAM l_param);
+ virtual LRESULT OnMouseLeave(UINT message, WPARAM w_param, LPARAM l_param);
virtual void OnMove(const CPoint& point) { SetMsgHandled(FALSE); }
virtual void OnMoving(UINT param, const LPRECT new_bounds) { }
virtual LRESULT OnMouseWheel(UINT flags, short distance, const CPoint& point);
diff --git a/chrome/views/window.cc b/chrome/views/window.cc
index d4cb905..a879a99 100644
--- a/chrome/views/window.cc
+++ b/chrome/views/window.cc
@@ -16,8 +16,8 @@
#include "chrome/common/resource_bundle.h"
#include "chrome/common/win_util.h"
#include "chrome/views/client_view.h"
-#include "chrome/views/custom_frame_window.h"
-#include "chrome/views/default_non_client_view.h"
+#include "chrome/views/custom_frame_view.h"
+#include "chrome/views/native_frame_view.h"
#include "chrome/views/non_client_view.h"
#include "chrome/views/root_view.h"
#include "chrome/views/window_delegate.h"
@@ -82,12 +82,8 @@ Window::~Window() {
Window* Window::CreateChromeWindow(HWND parent,
const gfx::Rect& bounds,
WindowDelegate* window_delegate) {
- Window* window = NULL;
- if (win_util::ShouldUseVistaFrame()) {
- window = new Window(window_delegate);
- } else {
- window = new CustomFrameWindow(window_delegate);
- }
+ Window* window = new Window(window_delegate);
+ window->non_client_view_->SetFrameView(window->CreateFrameViewForWindow());
window->Init(parent, bounds);
return window;
}
@@ -205,18 +201,9 @@ void Window::EnableClose(bool enable) {
SWP_NOSENDCHANGING | SWP_NOSIZE | SWP_NOZORDER);
}
-void Window::DisableInactiveRendering(bool disable) {
- disable_inactive_rendering_ = disable;
- if (!disable_inactive_rendering_)
- DefWindowProc(GetHWND(), WM_NCACTIVATE, FALSE, 0);
-
- if (!non_client_view_->UseNativeFrame()) {
- // If the non-client view is rendering its own frame, we need to forcibly
- // schedule a paint so it updates when we unset this mode.
- non_client_view_->set_paint_as_active(disable);
- if (!disable)
- non_client_view_->SchedulePaint();
- }
+void Window::DisableInactiveRendering() {
+ disable_inactive_rendering_ = true;
+ non_client_view_->DisableInactiveRendering(disable_inactive_rendering_);
}
void Window::UpdateWindowTitle() {
@@ -262,6 +249,11 @@ void Window::ExecuteSystemMenuCommand(int command) {
SendMessage(GetHWND(), WM_SYSCOMMAND, command, 0);
}
+gfx::Rect Window::GetWindowBoundsForClientBounds(
+ const gfx::Rect& client_bounds) {
+ return non_client_view_->GetWindowBoundsForClientBounds(client_bounds);
+}
+
// static
int Window::GetLocalizedContentsWidth(int col_resource_id) {
double chars = _wtof(l10n_util::GetString(col_resource_id).c_str());
@@ -309,7 +301,7 @@ Window::Window(WindowDelegate* window_delegate)
: WidgetWin(),
focus_on_creation_(true),
window_delegate_(window_delegate),
- non_client_view_(new NonClientView),
+ non_client_view_(new NonClientView(this)),
owning_hwnd_(NULL),
minimum_size_(100, 100),
is_modal_(false),
@@ -349,13 +341,13 @@ void Window::Init(HWND parent, const gfx::Rect& bounds) {
WidgetWin::Init(parent, bounds, true);
win_util::SetWindowUserData(GetHWND(), this);
- std::wstring window_title = window_delegate_->GetWindowTitle();
- std::wstring localized_text;
- if (l10n_util::AdjustStringForLocaleDirection(window_title, &localized_text))
- window_title.assign(localized_text);
- SetWindowText(GetHWND(), window_title.c_str());
+ // Create the ClientView, add it to the NonClientView and add the
+ // NonClientView to the RootView. This will cause everything to be parented.
+ non_client_view_->set_client_view(window_delegate_->CreateClientView(this));
+ WidgetWin::SetContentsView(non_client_view_);
+
+ UpdateWindowTitle();
- SetClientView(window_delegate_->CreateClientView(this));
SetInitialBounds(bounds);
InitAlwaysOnTopState();
@@ -366,7 +358,18 @@ void Window::Init(HWND parent, const gfx::Rect& bounds) {
NotificationService::AllSources());
}
- ResetWindowRegion();
+ ResetWindowRegion(false);
+}
+
+NonClientFrameView* Window::CreateFrameViewForWindow() {
+ if (non_client_view_->UseNativeFrame())
+ return new NativeFrameView(this);
+ return new CustomFrameView(this);
+}
+
+void Window::UpdateFrameAfterFrameChange() {
+ // We've either gained or lost a custom window region, so reset it now.
+ ResetWindowRegion(true);
}
void Window::SizeWindowToDefault() {
@@ -398,6 +401,15 @@ void Window::OnActivate(UINT action, BOOL minimized, HWND window) {
SaveWindowPosition();
}
+void Window::OnActivateApp(BOOL active, DWORD thread_id) {
+ if (!active && thread_id != GetCurrentThreadId()) {
+ // Another application was activated, we should reset any state that
+ // disables inactive rendering now.
+ disable_inactive_rendering_ = false;
+ non_client_view_->DisableInactiveRendering(false);
+ }
+}
+
LRESULT Window::OnAppCommand(HWND window, short app_command, WORD device,
int keystate) {
// We treat APPCOMMAND ids as an extension of our command namespace, and just
@@ -426,6 +438,27 @@ void Window::OnDestroy() {
}
namespace {
+static BOOL CALLBACK SendDwmCompositionChanged(HWND window, LPARAM param) {
+ SendMessage(window, WM_DWMCOMPOSITIONCHANGED, 0, 0);
+ return TRUE;
+}
+} // namespace
+
+LRESULT Window::OnDwmCompositionChanged(UINT msg, WPARAM w_param,
+ LPARAM l_param) {
+ // 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_->SystemThemeChanged();
+
+ // 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(GetHWND(), &SendDwmCompositionChanged, NULL);
+ return 0;
+}
+
+namespace {
static void EnableMenuItem(HMENU menu, UINT command, bool enabled) {
UINT flags = MF_BYCOMMAND | (enabled ? MF_ENABLED : MF_DISABLED | MF_GRAYED);
EnableMenuItem(menu, command, flags);
@@ -435,10 +468,8 @@ static void EnableMenuItem(HMENU menu, UINT command, bool enabled) {
void Window::OnInitMenu(HMENU menu) {
// We only need to manually enable the system menu if we're not using a native
// frame.
- if (non_client_view_->UseNativeFrame()) {
- SetMsgHandled(FALSE);
- return;
- }
+ if (non_client_view_->UseNativeFrame())
+ WidgetWin::OnInitMenu(menu);
bool is_minimized = IsMinimized();
bool is_maximized = IsMaximized();
@@ -482,12 +513,12 @@ void Window::OnMouseLeave() {
}
LRESULT Window::OnNCActivate(BOOL active) {
+ is_active_ = !!active;
+
// If we're not using the native frame, we need to force a synchronous repaint
// otherwise we'll be left in the wrong activation state until something else
// causes a repaint later.
if (!non_client_view_->UseNativeFrame()) {
- is_active_ = !!active;
-
// We can get WM_NCACTIVATE before we're actually visible. If we're not
// visible, no need to paint.
if (IsWindowVisible(GetHWND())) {
@@ -498,21 +529,26 @@ LRESULT Window::OnNCActivate(BOOL active) {
}
}
+ // If we're active again, we should be allowed to render as inactive, so
+ // tell the non-client view. This must be done independently of the check for
+ // disable_inactive_rendering_ since that check is valid even if the frame
+ // is not active, but this can only be done if we've become active.
+ if (is_active_)
+ non_client_view_->DisableInactiveRendering(false);
+
+ // Reset the disable inactive rendering state since activation has changed.
if (disable_inactive_rendering_) {
disable_inactive_rendering_ = false;
- return DefWindowProc(GetHWND(), WM_NCACTIVATE, TRUE, 0);
+ return CallDefaultNCActivateHandler(TRUE);
}
- // Otherwise just do the default thing.
- return WidgetWin::OnNCActivate(active);
+ return CallDefaultNCActivateHandler(active);
}
LRESULT Window::OnNCCalcSize(BOOL mode, LPARAM l_param) {
// We only need to adjust the client size/paint handling when we're not using
// the native frame.
- if (non_client_view_->UseNativeFrame()) {
- SetMsgHandled(FALSE);
- return 0;
- }
+ if (non_client_view_->UseNativeFrame())
+ return WidgetWin::OnNCCalcSize(mode, l_param);
// We need to repaint all when the window bounds change.
return WVR_REDRAW;
@@ -529,8 +565,7 @@ LRESULT Window::OnNCHitTest(const CPoint& point) {
// Otherwise, we let Windows do all the native frame non-client handling for
// us.
- SetMsgHandled(FALSE);
- return 0;
+ return WidgetWin::OnNCHitTest(point);
}
namespace {
@@ -564,10 +599,8 @@ static BOOL CALLBACK ClipDCToChild(HWND window, LPARAM param) {
void Window::OnNCPaint(HRGN rgn) {
// We only do non-client painting if we're not using the native frame.
- if (non_client_view_->UseNativeFrame()) {
- SetMsgHandled(FALSE);
- return;
- }
+ if (non_client_view_->UseNativeFrame())
+ return WidgetWin::OnNCPaint(rgn);
// We have an NC region and need to paint it. We expand the NC region to
// include the dirty region of the root view. This is done to minimize
@@ -765,7 +798,7 @@ void Window::OnSize(UINT size_param, const CSize& new_size) {
// ResetWindowRegion is going to trigger WM_NCPAINT. By doing it after we've
// invoked OnSize we ensure the RootView has been laid out.
- ResetWindowRegion();
+ ResetWindowRegion(false);
}
void Window::OnSysCommand(UINT notification_code, CPoint click) {
@@ -796,17 +829,17 @@ void Window::OnSysCommand(UINT notification_code, CPoint click) {
is_always_on_top_ = !is_always_on_top_;
// Change the menu check state.
- HMENU system_menu = ::GetSystemMenu(GetHWND(), FALSE);
+ HMENU system_menu = GetSystemMenu(GetHWND(), FALSE);
MENUITEMINFO menu_info;
memset(&menu_info, 0, sizeof(MENUITEMINFO));
menu_info.cbSize = sizeof(MENUITEMINFO);
- BOOL r = ::GetMenuItemInfo(system_menu, IDC_ALWAYS_ON_TOP,
- FALSE, &menu_info);
+ BOOL r = GetMenuItemInfo(system_menu, IDC_ALWAYS_ON_TOP,
+ FALSE, &menu_info);
DCHECK(r);
menu_info.fMask = MIIM_STATE;
if (is_always_on_top_)
menu_info.fState = MFS_CHECKED;
- r = ::SetMenuItemInfo(system_menu, IDC_ALWAYS_ON_TOP, FALSE, &menu_info);
+ r = SetMenuItemInfo(system_menu, IDC_ALWAYS_ON_TOP, FALSE, &menu_info);
// Now change the actual window's behavior.
AlwaysOnTopChanged();
@@ -823,13 +856,6 @@ void Window::OnSysCommand(UINT notification_code, CPoint click) {
////////////////////////////////////////////////////////////////////////////////
// Window, private:
-void Window::SetClientView(ClientView* client_view) {
- DCHECK(client_view && GetHWND());
- non_client_view_->set_client_view(client_view);
- // This will trigger the ClientView to be added by the non-client view.
- WidgetWin::SetContentsView(non_client_view_);
-}
-
void Window::BecomeModal() {
// We implement modality by crawling up the hierarchy of windows starting
// at the owner, disabling all of them so that they don't receive input
@@ -1023,11 +1049,14 @@ void Window::UnlockUpdates() {
lock_updates_ = false;
}
-void Window::ResetWindowRegion() {
+void Window::ResetWindowRegion(bool force) {
// A native frame uses the native window region, and we don't want to mess
// with it.
- if (non_client_view_->UseNativeFrame())
+ if (non_client_view_->UseNativeFrame()) {
+ if (force)
+ SetWindowRgn(NULL, TRUE);
return;
+ }
// Changing the window region is going to force a paint. Only change the
// window region if the region really differs.
@@ -1075,6 +1104,14 @@ void Window::ProcessNCMousePress(const CPoint& point, int flags) {
ProcessMousePressed(temp, message_flags, false, false);
}
+LRESULT Window::CallDefaultNCActivateHandler(BOOL active) {
+ // The DefWindowProc handling for WM_NCACTIVATE renders the classic-look
+ // window title bar directly, so we need to use a redraw lock here to prevent
+ // it from doing so.
+ ScopedRedrawLock lock(this);
+ return DefWindowProc(GetHWND(), WM_NCACTIVATE, active, 0);
+}
+
void Window::InitClass() {
static bool initialized = false;
if (!initialized) {
diff --git a/chrome/views/window.h b/chrome/views/window.h
index b87f0e3..564cfab 100644
--- a/chrome/views/window.h
+++ b/chrome/views/window.h
@@ -68,7 +68,7 @@ class Window : public WidgetWin,
void SetBounds(const gfx::Rect& bounds, HWND other_hwnd);
// Closes the window, ultimately destroying it.
- virtual void Close();
+ void Close();
// Whether or not the window is maximized or minimized.
bool IsMaximized() const;
@@ -76,35 +76,46 @@ class Window : public WidgetWin,
// Toggles the enable state for the Close button (and the Close menu item in
// the system menu).
- virtual void EnableClose(bool enable);
+ void EnableClose(bool enable);
- // Prevents the window from being rendered as deactivated when |disable| is
- // true, until called with |disable| false. Used when a sub-window is to be
- // shown that shouldn't visually de-activate the window.
- // Subclasses can override this to perform additional actions when this value
- // changes.
- virtual void DisableInactiveRendering(bool disable);
-
- WindowDelegate* window_delegate() const { return window_delegate_; }
-
- void set_focus_on_creation(bool focus_on_creation) {
- focus_on_creation_ = focus_on_creation;
- }
+ // Prevents the window from being rendered as deactivated the next time it is.
+ // This state is reset automatically as soon as the window becomes actiated
+ // again. There is no ability to control the state through this API as this
+ // leads to sync problems.
+ void DisableInactiveRendering();
// Tell the window to update its title from the delegate.
- virtual void UpdateWindowTitle();
+ void UpdateWindowTitle();
// Tell the window to update its icon from the delegate.
- virtual void UpdateWindowIcon();
+ void UpdateWindowIcon();
// Executes the specified SC_command.
void ExecuteSystemMenuCommand(int command);
- // The parent of this window.
- HWND owning_window() const { return owning_hwnd_; }
+ // Shortcut to access the determination of whether or not we're using a
+ // native frame. This triggers different rendering modes in certain views and
+ // should be used in preference to calling win_util::ShouldUseVistaFrame.
+ bool UseNativeFrame() const { return non_client_view_->UseNativeFrame(); }
+
+ // Returns the bounds of the window required to display the content area
+ // at the specified bounds.
+ gfx::Rect GetWindowBoundsForClientBounds(const gfx::Rect& client_bounds);
+
+ // Creates an appropriate NonClientFrameView for this window.
+ virtual NonClientFrameView* CreateFrameViewForWindow();
- // Shortcut to access the ClientView associated with this window.
+ // Updates the frame after an event caused it to be changed.
+ virtual void UpdateFrameAfterFrameChange();
+
+ // Accessors and setters for various properties.
+ WindowDelegate* window_delegate() const { return window_delegate_; }
+ HWND owning_window() const { return owning_hwnd_; }
ClientView* client_view() const { return non_client_view_->client_view(); }
+ bool is_active() const { return is_active_; }
+ void set_focus_on_creation(bool focus_on_creation) {
+ focus_on_creation_ = focus_on_creation;
+ }
// Returns the preferred size of the contents view of this window based on
// its localized size data. The width in cols is held in a localized string
@@ -144,25 +155,30 @@ class Window : public WidgetWin,
// Overridden from WidgetWin:
virtual void OnActivate(UINT action, BOOL minimized, HWND window);
+ virtual void OnActivateApp(BOOL active, DWORD thread_id);
virtual LRESULT OnAppCommand(HWND window, short app_command, WORD device,
int keystate);
virtual void OnCommand(UINT notification_code, int command_id, HWND window);
virtual void OnDestroy();
+ virtual LRESULT OnDwmCompositionChanged(UINT msg, WPARAM w_param,
+ LPARAM l_param);
virtual void OnInitMenu(HMENU menu);
virtual void OnMouseLeave();
virtual LRESULT OnNCActivate(BOOL active);
virtual LRESULT OnNCCalcSize(BOOL mode, LPARAM l_param);
virtual LRESULT OnNCHitTest(const CPoint& point);
- virtual LRESULT OnNCUAHDrawCaption(UINT msg, WPARAM w_param, LPARAM l_param);
- virtual LRESULT OnNCUAHDrawFrame(UINT msg, WPARAM w_param, LPARAM l_param);
virtual void OnNCPaint(HRGN rgn);
virtual void OnNCLButtonDown(UINT ht_component, const CPoint& point);
virtual void OnNCRButtonDown(UINT ht_component, const CPoint& point);
+ virtual LRESULT OnNCUAHDrawCaption(UINT msg, WPARAM w_param, LPARAM l_param);
+ virtual LRESULT OnNCUAHDrawFrame(UINT msg, WPARAM w_param, LPARAM l_param);
virtual LRESULT OnSetCursor(HWND window, UINT hittest_code, UINT message);
virtual LRESULT OnSetIcon(UINT size_type, HICON new_icon);
virtual LRESULT OnSetText(const wchar_t* text);
virtual void OnSize(UINT size_param, const CSize& new_size);
virtual void OnSysCommand(UINT notification_code, CPoint click);
+ virtual Window* AsWindow() { return this; }
+ virtual const Window* AsWindow() const { return this; }
// The View that provides the non-client area of the window (title bar,
// window controls, sizing borders etc). To use an implementation other than
@@ -176,15 +192,6 @@ class Window : public WidgetWin,
}
private:
- // Sets the specified view as the ClientView of this Window. The ClientView
- // is responsible for laying out the Window's contents view, as well as
- // performing basic hit-testing, and perhaps other responsibilities depending
- // on the implementation. The Window's view hierarchy takes ownership of the
- // ClientView unless the ClientView specifies otherwise. This must be called
- // only once, and after the native window has been created.
- // This is called by Init. |client_view| cannot be NULL.
- void SetClientView(ClientView* client_view);
-
// Set the window as modal (by disabling all the other windows).
void BecomeModal();
@@ -224,7 +231,9 @@ class Window : public WidgetWin,
void UnlockUpdates();
// Resets the window region for the current window bounds if necessary.
- void ResetWindowRegion();
+ // If |force| is true, the window region is reset to NULL even for native
+ // frame windows.
+ void ResetWindowRegion(bool force);
// Converts a non-client mouse down message to a regular ChromeViews event
// and handle it. |point| is the mouse position of the message in screen
@@ -233,6 +242,11 @@ class Window : public WidgetWin,
// combined with flags relating to the current key state.
void ProcessNCMousePress(const CPoint& point, int flags);
+ // Calls the default WM_NCACTIVATE handler with the specified activation
+ // value, safely wrapping the call in a ScopedRedrawLock to prevent frame
+ // flicker.
+ LRESULT CallDefaultNCActivateHandler(BOOL active);
+
// Static resource initialization.
static void InitClass();
enum ResizeCursor {