diff options
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 { |