diff options
author | ben@chromium.org <ben@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-06-02 23:01:12 +0000 |
---|---|---|
committer | ben@chromium.org <ben@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-06-02 23:01:12 +0000 |
commit | 677c2ee722f21b54cf3dec42a0a4b9d35b00fe87 (patch) | |
tree | 3f3d3f9ab92ed9d3c14546e29f6ea013ea98c8f8 | |
parent | 1ab7d168f2037ce57108af43129fcf2481072244 (diff) | |
download | chromium_src-677c2ee722f21b54cf3dec42a0a4b9d35b00fe87.zip chromium_src-677c2ee722f21b54cf3dec42a0a4b9d35b00fe87.tar.gz chromium_src-677c2ee722f21b54cf3dec42a0a4b9d35b00fe87.tar.bz2 |
Revert 87702 - Move NonClientView and FrameType logic from Window to Widget.
Also fixes leak of default WidgetDelegate by replacing it with a DefaultWidgetDelegate subclass that overrides DeleteDelegate and deletes itself. This required moving the destruction logic from Window down onto Widget.
BUG=72040
TEST=none
Review URL: http://codereview.chromium.org/7033049
TBR=ben@chromium.org
Review URL: http://codereview.chromium.org/7109028
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@87719 0039d316-1c4b-4281-b951-d872f2087c98
35 files changed, 372 insertions, 402 deletions
diff --git a/chrome/browser/chromeos/frame/bubble_window.cc b/chrome/browser/chromeos/frame/bubble_window.cc index 7ab60d5..a0ddb6e 100644 --- a/chrome/browser/chromeos/frame/bubble_window.cc +++ b/chrome/browser/chromeos/frame/bubble_window.cc @@ -30,9 +30,9 @@ namespace chromeos { // static const SkColor BubbleWindow::kBackgroundColor = SK_ColorWHITE; -BubbleWindow::BubbleWindow(views::Window* window, Style style) - : views::NativeWindowGtk(window), - style_(style) { +BubbleWindow::BubbleWindow(views::Window* window) + : views::NativeWindowGtk(window) { + MakeTransparent(); } void BubbleWindow::InitNativeWidget(const views::Widget::InitParams& params) { @@ -56,11 +56,6 @@ void BubbleWindow::InitNativeWidget(const views::Widget::InitParams& params) { gdk_window_set_back_pixmap(window_contents()->window, NULL, FALSE); } -views::NonClientFrameView* BubbleWindow::CreateNonClientFrameView() { - views::Window* window = GetWindow(); - return new BubbleFrameView(window, window->window_delegate(), style_); -} - void BubbleWindow::TrimMargins(int margin_left, int margin_right, int margin_top, int margin_bottom, int border_radius) { @@ -120,7 +115,9 @@ views::Window* BubbleWindow::Create( Style style, views::WindowDelegate* window_delegate) { views::Window* window = new views::Window; - BubbleWindow* bubble_window = new BubbleWindow(window, style); + BubbleWindow* bubble_window = new BubbleWindow(window); + window->non_client_view()->SetFrameView( + new BubbleFrameView(window, window_delegate, style)); views::Window::InitParams params(window_delegate); params.parent_window = parent; params.native_window = bubble_window; @@ -128,7 +125,6 @@ views::Window* BubbleWindow::Create( params.widget_init_params.bounds = bounds; params.widget_init_params.parent = GTK_WIDGET(parent); params.widget_init_params.native_widget = bubble_window; - params.widget_init_params.transparent = true; window->InitWindow(params); if (style == STYLE_XSHAPE) { diff --git a/chrome/browser/chromeos/frame/bubble_window.h b/chrome/browser/chromeos/frame/bubble_window.h index 07fa6a4..621e41f 100644 --- a/chrome/browser/chromeos/frame/bubble_window.h +++ b/chrome/browser/chromeos/frame/bubble_window.h @@ -38,21 +38,15 @@ class BubbleWindow : public views::NativeWindowGtk { static const SkColor kBackgroundColor; protected: - BubbleWindow(views::Window* window, Style style); + explicit BubbleWindow(views::Window* window); // Overidden from views::NativeWindowGtk: virtual void InitNativeWidget( const views::Widget::InitParams& params) OVERRIDE; - virtual views::NonClientFrameView* CreateNonClientFrameView() OVERRIDE; // Trims the window margins and rounds off the corners. void TrimMargins(int margin_left, int margin_right, int margin_top, int margin_bottom, int border_radius); - - private: - Style style_; - - DISALLOW_COPY_AND_ASSIGN(BubbleWindow); }; } // namespace chromeos diff --git a/chrome/browser/chromeos/login/user_controller.cc b/chrome/browser/chromeos/login/user_controller.cc index d177faf..0f135b9 100644 --- a/chrome/browser/chromeos/login/user_controller.cc +++ b/chrome/browser/chromeos/login/user_controller.cc @@ -51,8 +51,9 @@ const int kControlsHeight = 28; const int kVerticalIntervalSize = 10; void CloseWindow(views::Widget* window) { - if (window) - window->CloseNow(); + if (!window) + return; + window->Close(); } } // namespace diff --git a/chrome/browser/ui/views/constrained_window_views.cc b/chrome/browser/ui/views/constrained_window_views.cc index e6fb0bd..fa6fd7f 100644 --- a/chrome/browser/ui/views/constrained_window_views.cc +++ b/chrome/browser/ui/views/constrained_window_views.cc @@ -571,6 +571,7 @@ ConstrainedWindowViews::ConstrainedWindowViews( : owner_(owner), ALLOW_THIS_IN_INITIALIZER_LIST(native_constrained_window_( NativeConstrainedWindow::CreateNativeConstrainedWindow(this))) { + non_client_view()->SetFrameView(CreateFrameViewForWindow()); views::Window::InitParams params(window_delegate); params.native_window = native_constrained_window_->AsNativeWindow(); params.widget_init_params.child = true; @@ -618,7 +619,7 @@ void ConstrainedWindowViews::FocusConstrainedWindow() { //////////////////////////////////////////////////////////////////////////////// // ConstrainedWindowViews, views::Window overrides: -views::NonClientFrameView* ConstrainedWindowViews::CreateNonClientFrameView() { +views::NonClientFrameView* ConstrainedWindowViews::CreateFrameViewForWindow() { return new ConstrainedWindowFrameView(this); } diff --git a/chrome/browser/ui/views/constrained_window_views.h b/chrome/browser/ui/views/constrained_window_views.h index 14a93c2..802f015 100644 --- a/chrome/browser/ui/views/constrained_window_views.h +++ b/chrome/browser/ui/views/constrained_window_views.h @@ -36,6 +36,10 @@ class NativeConstrainedWindowDelegate { // Called when the NativeConstrainedWindow is clicked on when inactive. virtual void OnNativeConstrainedWindowMouseActivate() = 0; + // Creates the frame view for the constrained window. + // TODO(beng): remove once ConstrainedWindowViews is-a views::Window. + virtual views::NonClientFrameView* CreateFrameViewForWindow() = 0; + virtual views::internal::NativeWindowDelegate* AsNativeWindowDelegate() = 0; }; @@ -74,7 +78,7 @@ class ConstrainedWindowViews : public views::Window, private: // Overridden from views::Window: - virtual views::NonClientFrameView* CreateNonClientFrameView() OVERRIDE; + virtual views::NonClientFrameView* CreateFrameViewForWindow() OVERRIDE; // Overridden from NativeConstrainedWindowDelegate: virtual void OnNativeConstrainedWindowDestroyed() OVERRIDE; diff --git a/chrome/browser/ui/views/frame/browser_frame.cc b/chrome/browser/ui/views/frame/browser_frame.cc index f50b539..a682c89 100644 --- a/chrome/browser/ui/views/frame/browser_frame.cc +++ b/chrome/browser/ui/views/frame/browser_frame.cc @@ -100,7 +100,7 @@ views::internal::RootView* BrowserFrame::CreateRootView() { return root_view_; } -views::NonClientFrameView* BrowserFrame::CreateNonClientFrameView() { +views::NonClientFrameView* BrowserFrame::CreateFrameViewForWindow() { #if defined(OS_WIN) if (ShouldUseNativeFrame()) { browser_frame_view_ = new GlassBrowserFrameView(this, browser_view_); diff --git a/chrome/browser/ui/views/frame/browser_frame.h b/chrome/browser/ui/views/frame/browser_frame.h index 5f661f4..d8af0cd 100644 --- a/chrome/browser/ui/views/frame/browser_frame.h +++ b/chrome/browser/ui/views/frame/browser_frame.h @@ -71,7 +71,7 @@ class BrowserFrame : public views::Window { // Overridden from views::Window: virtual bool IsMaximized() const OVERRIDE; virtual views::internal::RootView* CreateRootView() OVERRIDE; - virtual views::NonClientFrameView* CreateNonClientFrameView() OVERRIDE; + virtual views::NonClientFrameView* CreateFrameViewForWindow() OVERRIDE; virtual bool GetAccelerator(int command_id, ui::Accelerator* accelerator) OVERRIDE; virtual ui::ThemeProvider* GetThemeProvider() const OVERRIDE; diff --git a/views/widget/native_widget.h b/views/widget/native_widget.h index 6cb4147..f3faba0 100644 --- a/views/widget/native_widget.h +++ b/views/widget/native_widget.h @@ -66,14 +66,6 @@ class NativeWidget { // Initializes the NativeWidget. virtual void InitNativeWidget(const Widget::InitParams& params) = 0; - // Returns a NonClientFrameView for the widget's NonClientView, or NULL if - // the NativeWidget wants no special NonClientFrameView. - virtual NonClientFrameView* CreateNonClientFrameView() = 0; - - virtual void UpdateFrameAfterFrameChange() = 0; - virtual bool ShouldUseNativeFrame() const = 0; - virtual void FrameTypeChanged() = 0; - // Returns the Widget associated with this NativeWidget. This function is // guaranteed to return non-NULL for the lifetime of the NativeWidget. virtual Widget* GetWidget() = 0; diff --git a/views/widget/native_widget_delegate.h b/views/widget/native_widget_delegate.h index d39bd58..05af457 100644 --- a/views/widget/native_widget_delegate.h +++ b/views/widget/native_widget_delegate.h @@ -31,9 +31,6 @@ class NativeWidgetDelegate { // Called when the native widget is created. virtual void OnNativeWidgetCreated() = 0; - // Called just after the native widget is destroyed. - virtual void OnNativeWidgetDestroyed() = 0; - // Called when the NativeWidget changed size to |new_size|. virtual void OnSizeChanged(const gfx::Size& new_size) = 0; diff --git a/views/widget/native_widget_gtk.cc b/views/widget/native_widget_gtk.cc index 392abe8..c5f926c 100644 --- a/views/widget/native_widget_gtk.cc +++ b/views/widget/native_widget_gtk.cc @@ -736,27 +736,6 @@ void NativeWidgetGtk::InitNativeWidget(const Widget::InitParams& params) { } } -NonClientFrameView* NativeWidgetGtk::CreateNonClientFrameView() { - return NULL; -} - -void NativeWidgetGtk::UpdateFrameAfterFrameChange() { - // We currently don't support different frame types on Gtk, so we don't - // need to implement this. - NOTIMPLEMENTED(); -} - -bool NativeWidgetGtk::ShouldUseNativeFrame() const { - return false; -} - -void NativeWidgetGtk::FrameTypeChanged() { - // This is called when the Theme has changed, so forward the event to the root - // widget. - GetWidget()->ThemeChanged(); - GetWidget()->GetRootView()->SchedulePaint(); -} - Widget* NativeWidgetGtk::GetWidget() { return delegate_->AsWidget(); } @@ -1456,7 +1435,6 @@ void NativeWidgetGtk::OnDestroy(GtkWidget* object) { } void NativeWidgetGtk::OnDestroyed(GObject *where_the_object_was) { - delegate_->OnNativeWidgetDestroyed(); if (ownership_ == Widget::InitParams::NATIVE_WIDGET_OWNS_WIDGET) delete this; } diff --git a/views/widget/native_widget_gtk.h b/views/widget/native_widget_gtk.h index 2603298..e6a9951 100644 --- a/views/widget/native_widget_gtk.h +++ b/views/widget/native_widget_gtk.h @@ -148,10 +148,6 @@ class NativeWidgetGtk : public NativeWidget, // Overridden from NativeWidget: virtual void InitNativeWidget(const Widget::InitParams& params) OVERRIDE; - virtual NonClientFrameView* CreateNonClientFrameView() OVERRIDE; - virtual void UpdateFrameAfterFrameChange() OVERRIDE; - virtual bool ShouldUseNativeFrame() const OVERRIDE; - virtual void FrameTypeChanged() OVERRIDE; virtual Widget* GetWidget() OVERRIDE; virtual const Widget* GetWidget() const OVERRIDE; virtual gfx::NativeView GetNativeView() const OVERRIDE; diff --git a/views/widget/native_widget_views.cc b/views/widget/native_widget_views.cc index d0eebe4..9f26791 100644 --- a/views/widget/native_widget_views.cc +++ b/views/widget/native_widget_views.cc @@ -48,21 +48,6 @@ void NativeWidgetViews::InitNativeWidget(const Widget::InitParams& params) { // TODO(beng): SetInitParams(). } -NonClientFrameView* NativeWidgetViews::CreateNonClientFrameView() { - return NULL; -} - -void NativeWidgetViews::UpdateFrameAfterFrameChange() { -} - -bool NativeWidgetViews::ShouldUseNativeFrame() const { - NOTIMPLEMENTED(); - return false; -} - -void NativeWidgetViews::FrameTypeChanged() { -} - Widget* NativeWidgetViews::GetWidget() { return delegate_->AsWidget(); } diff --git a/views/widget/native_widget_views.h b/views/widget/native_widget_views.h index f6d445d..96bdc9a 100644 --- a/views/widget/native_widget_views.h +++ b/views/widget/native_widget_views.h @@ -35,10 +35,6 @@ class NativeWidgetViews : public NativeWidget { protected: // Overridden from NativeWidget: virtual void InitNativeWidget(const Widget::InitParams& params) OVERRIDE; - virtual NonClientFrameView* CreateNonClientFrameView() OVERRIDE; - virtual void UpdateFrameAfterFrameChange() OVERRIDE; - virtual bool ShouldUseNativeFrame() const OVERRIDE; - virtual void FrameTypeChanged() OVERRIDE; virtual Widget* GetWidget() OVERRIDE; virtual const Widget* GetWidget() const OVERRIDE; virtual gfx::NativeView GetNativeView() const OVERRIDE; diff --git a/views/widget/native_widget_win.cc b/views/widget/native_widget_win.cc index db9f73a..1afb3e5 100644 --- a/views/widget/native_widget_win.cc +++ b/views/widget/native_widget_win.cc @@ -37,7 +37,6 @@ #include "views/widget/native_widget_delegate.h" #include "views/widget/root_view.h" #include "views/widget/widget_delegate.h" -#include "views/window/native_frame_view.h" #include "views/window/native_window_win.h" #pragma comment(lib, "dwmapi.lib") @@ -168,21 +167,6 @@ void SetChildBounds(HWND child_window, actual_bounds.height(), flags); } -// Callback used to notify child windows that the top level window received a -// DWMCompositionChanged message. -BOOL CALLBACK SendDwmCompositionChanged(HWND window, LPARAM param) { - SendMessage(window, WM_DWMCOMPOSITIONCHANGED, 0, 0); - return TRUE; -} - -// Tells the window its frame (non-client area) has changed. -void SendFrameChanged(HWND window) { - SetWindowPos(window, NULL, 0, 0, 0, 0, - SWP_FRAMECHANGED | SWP_NOACTIVATE | SWP_NOCOPYBITS | - SWP_NOMOVE | SWP_NOOWNERZORDER | SWP_NOREPOSITION | - SWP_NOSENDCHANGING | SWP_NOSIZE | SWP_NOZORDER); -} - // Links the HWND to its NativeWidget. const char* const kNativeWidgetKey = "__VIEWS_NATIVE_WIDGET__"; @@ -291,49 +275,6 @@ void NativeWidgetWin::InitNativeWidget(const Widget::InitParams& params) { WindowImpl::Init(parent, params.bounds); } -NonClientFrameView* NativeWidgetWin::CreateNonClientFrameView() { - return GetWidget()->ShouldUseNativeFrame() ? - new NativeFrameView(GetWidget()) : NULL; -} - -void NativeWidgetWin::UpdateFrameAfterFrameChange() { - // We've either gained or lost a custom window region, so reset it now. - ResetWindowRegion(true); -} - -bool NativeWidgetWin::ShouldUseNativeFrame() const { - return IsAeroGlassEnabled(); -} - -void NativeWidgetWin::FrameTypeChanged() { - // Called when the frame type could possibly be changing (theme change or - // DWM composition change). - if (base::win::GetVersion() >= base::win::VERSION_VISTA) { - // We need to toggle the rendering policy of the DWM/glass frame as we - // change from opaque to glass. "Non client rendering enabled" means that - // the DWM's glass non-client rendering is enabled, which is why - // DWMNCRP_ENABLED is used for the native frame case. _DISABLED means the - // DWM doesn't render glass, and so is used in the custom frame case. - DWMNCRENDERINGPOLICY policy = GetWidget()->ShouldUseNativeFrame() ? - DWMNCRP_ENABLED : DWMNCRP_DISABLED; - DwmSetWindowAttribute(GetNativeView(), DWMWA_NCRENDERING_POLICY, - &policy, sizeof(DWMNCRENDERINGPOLICY)); - } - - // Send a frame change notification, since the non-client metrics have - // changed. - SendFrameChanged(GetNativeView()); - - // Update the non-client view with the correct frame view for the active frame - // type. - GetWidget()->non_client_view()->UpdateFrame(); - - // WM_DWMCOMPOSITIONCHANGED is only sent to top level windows, however we want - // to notify our children too, since we can have MDI child windows who need to - // update their appearance. - EnumChildWindows(GetNativeView(), &SendDwmCompositionChanged, NULL); -} - Widget* NativeWidgetWin::GetWidget() { return delegate_->AsWidget(); } @@ -1300,9 +1241,7 @@ void NativeWidgetWin::OnSettingChange(UINT flags, const wchar_t* section) { } void NativeWidgetWin::OnSize(UINT param, const CSize& 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(false); + SetMsgHandled(FALSE); } void NativeWidgetWin::OnSysCommand(UINT notification_code, CPoint click) { @@ -1336,7 +1275,6 @@ void NativeWidgetWin::OnWindowPosChanged(WINDOWPOS* window_pos) { } void NativeWidgetWin::OnFinalMessage(HWND window) { - delegate_->OnNativeWidgetDestroyed(); if (ownership_ == Widget::InitParams::NATIVE_WIDGET_OWNS_WIDGET) delete this; } @@ -1540,49 +1478,6 @@ void NativeWidgetWin::ClientAreaSizeChanged() { } } -void NativeWidgetWin::ResetWindowRegion(bool force) { - // A native frame uses the native window region, and we don't want to mess - // with it. - if (GetWidget()->ShouldUseNativeFrame()) { - 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. - HRGN current_rgn = CreateRectRgn(0, 0, 0, 0); - int current_rgn_result = GetWindowRgn(GetNativeView(), current_rgn); - - CRect window_rect; - GetWindowRect(&window_rect); - HRGN new_region; - if (IsMaximized()) { - HMONITOR monitor = - MonitorFromWindow(GetNativeView(), 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; - GetWidget()->non_client_view()->GetWindowMask( - gfx::Size(window_rect.Width(), window_rect.Height()), &window_mask); - new_region = window_mask.CreateNativeRegion(); - } - - if (current_rgn_result == ERROR || !EqualRgn(current_rgn, new_region)) { - // SetWindowRgn takes ownership of the HRGN created by CreateNativeRegion. - SetWindowRgn(new_region, TRUE); - } else { - DeleteObject(new_region); - } - - DeleteObject(current_rgn); -} - gfx::AcceleratedWidget NativeWidgetWin::GetAcceleratedWidget() { #if defined(VIEWS_COMPOSITOR) return hwnd(); diff --git a/views/widget/native_widget_win.h b/views/widget/native_widget_win.h index 7dd4995..40f4c84 100644 --- a/views/widget/native_widget_win.h +++ b/views/widget/native_widget_win.h @@ -176,10 +176,6 @@ class NativeWidgetWin : public ui::WindowImpl, // Overridden from NativeWidget: virtual void InitNativeWidget(const Widget::InitParams& params) OVERRIDE; - virtual NonClientFrameView* CreateNonClientFrameView() OVERRIDE; - virtual void UpdateFrameAfterFrameChange() OVERRIDE; - virtual bool ShouldUseNativeFrame() const OVERRIDE; - virtual void FrameTypeChanged() OVERRIDE; virtual Widget* GetWidget() OVERRIDE; virtual const Widget* GetWidget() const OVERRIDE; virtual gfx::NativeView GetNativeView() const OVERRIDE; @@ -479,11 +475,6 @@ class NativeWidgetWin : public ui::WindowImpl, // or subsequently. void ClientAreaSizeChanged(); - // Resets the window region for the current widget bounds if necessary. - // If |force| is true, the window region is reset to NULL even for native - // frame windows. - void ResetWindowRegion(bool force); - // Overridden from NativeWidget. virtual gfx::AcceleratedWidget GetAcceleratedWidget() OVERRIDE; diff --git a/views/widget/widget.cc b/views/widget/widget.cc index e2b2202..bc84fb0 100644 --- a/views/widget/widget.cc +++ b/views/widget/widget.cc @@ -14,7 +14,6 @@ #include "views/widget/root_view.h" #include "views/widget/native_widget.h" #include "views/widget/widget_delegate.h" -#include "views/window/custom_frame_view.h" namespace views { @@ -23,22 +22,6 @@ namespace { bool use_pure_views = false; } -// A default implementation of WidgetDelegate, used by Widget when no -// WidgetDelegate is supplied. -class DefaultWidgetDelegate : public WidgetDelegate { - public: - DefaultWidgetDelegate() {} - virtual ~DefaultWidgetDelegate() {} - - // Overridden from WidgetDelegate: - virtual void DeleteDelegate() OVERRIDE { - delete this; - } - - private: - DISALLOW_COPY_AND_ASSIGN(DefaultWidgetDelegate); -}; - //////////////////////////////////////////////////////////////////////////////// // Widget, InitParams: @@ -90,13 +73,10 @@ Widget::Widget() : is_mouse_button_pressed_(false), last_mouse_event_was_move_(false), native_widget_(NULL), - type_(InitParams::TYPE_WINDOW), widget_delegate_(NULL), - non_client_view_(NULL), dragged_view_(NULL), ownership_(InitParams::NATIVE_WIDGET_OWNS_WIDGET), - is_secondary_widget_(true), - frame_type_(FRAME_TYPE_DEFAULT) { + is_secondary_widget_(true) { } Widget::~Widget() { @@ -124,9 +104,7 @@ Widget* Widget::GetWidgetForNativeView(gfx::NativeView native_view) { } void Widget::Init(const InitParams& params) { - type_ = params.type; - widget_delegate_ = - params.delegate ? params.delegate : new DefaultWidgetDelegate; + widget_delegate_ = params.delegate ? params.delegate : new WidgetDelegate; ownership_ = params.ownership; native_widget_ = params.native_widget ? params.native_widget @@ -136,10 +114,6 @@ void Widget::Init(const InitParams& params) { if (params.type == InitParams::TYPE_MENU) is_mouse_button_pressed_ = native_widget_->IsMouseButtonDown(); native_widget_->InitNativeWidget(params); - if (type_ == InitParams::TYPE_WINDOW) { - non_client_view_ = new NonClientView; - non_client_view_->SetFrameView(CreateNonClientFrameView()); - } } // Unconverted methods (see header) -------------------------------------------- @@ -407,38 +381,6 @@ void Widget::SetFocusTraversableParentView(View* parent_view) { root_view_->SetFocusTraversableParentView(parent_view); } -void Widget::UpdateFrameAfterFrameChange() { - native_widget_->UpdateFrameAfterFrameChange(); -} - -NonClientFrameView* Widget::CreateNonClientFrameView() { - NonClientFrameView* frame_view = widget_delegate_->CreateNonClientFrameView(); - if (!frame_view) - frame_view = native_widget_->CreateNonClientFrameView(); - return frame_view ? frame_view : new CustomFrameView(this); -} - -bool Widget::ShouldUseNativeFrame() const { - if (frame_type_ != FRAME_TYPE_DEFAULT) - return frame_type_ == FRAME_TYPE_FORCE_NATIVE; - return native_widget_->ShouldUseNativeFrame(); -} - -void Widget::DebugToggleFrameType() { - if (frame_type_ == FRAME_TYPE_DEFAULT) { - frame_type_ = ShouldUseNativeFrame() ? FRAME_TYPE_FORCE_CUSTOM : - FRAME_TYPE_FORCE_NATIVE; - } else { - frame_type_ = frame_type_ == FRAME_TYPE_FORCE_CUSTOM ? - FRAME_TYPE_FORCE_NATIVE : FRAME_TYPE_FORCE_CUSTOM; - } - FrameTypeChanged(); -} - -void Widget::FrameTypeChanged() { - native_widget_->FrameTypeChanged(); -} - void Widget::NotifyAccessibilityEvent( View* view, ui::AccessibilityTypes::Event event_type, @@ -475,11 +417,6 @@ void Widget::OnNativeWidgetCreated() { EnsureCompositor(); } -void Widget::OnNativeWidgetDestroyed() { - widget_delegate_->DeleteDelegate(); - widget_delegate_ = NULL; -} - void Widget::OnSizeChanged(const gfx::Size& new_size) { root_view_->SetSize(new_size); } diff --git a/views/widget/widget.h b/views/widget/widget.h index 19952eb..912cc76 100644 --- a/views/widget/widget.h +++ b/views/widget/widget.h @@ -15,8 +15,6 @@ #include "ui/gfx/rect.h" #include "views/focus/focus_manager.h" #include "views/widget/native_widget_delegate.h" -#include "views/window/client_view.h" -#include "views/window/non_client_view.h" #if defined(OS_WIN) // Windows headers define macros for these function names which screw with us. @@ -48,7 +46,6 @@ namespace views { class DefaultThemeProvider; class InputMethod; class NativeWidget; -class NonClientFrameView; class TooltipManager; class View; class WidgetDelegate; @@ -85,12 +82,6 @@ class RootView; class Widget : public internal::NativeWidgetDelegate, public FocusTraversable { public: - enum FrameType { - FRAME_TYPE_DEFAULT, // Use whatever the default would be. - FRAME_TYPE_FORCE_CUSTOM, // Force the custom frame. - FRAME_TYPE_FORCE_NATIVE // Force the native frame. - }; - struct InitParams { enum Type { TYPE_WINDOW, // A Window, like a frame window. @@ -363,44 +354,6 @@ class Widget : public internal::NativeWidgetDelegate, void SetFocusTraversableParent(FocusTraversable* parent); void SetFocusTraversableParentView(View* parent_view); - // Updates the frame after an event caused it to be changed. - virtual void UpdateFrameAfterFrameChange(); - - void set_frame_type(FrameType frame_type) { frame_type_ = frame_type; } - FrameType frame_type() const { return frame_type_; } - - // Creates an appropriate NonClientFrameView for this widget. The - // WidgetDelegate is given the first opportunity to create one, followed by - // the NativeWidget implementation. If both return NULL, a default one is - // created. - virtual NonClientFrameView* CreateNonClientFrameView(); - - // Whether we should be using a native frame. - bool ShouldUseNativeFrame() const; - - // Forces the frame into the alternate frame type (custom or native) depending - // on its current state. - void DebugToggleFrameType(); - - // Tell the window that something caused the frame type to change. - void FrameTypeChanged(); - - NonClientView* non_client_view() { - return const_cast<NonClientView*>( - const_cast<const Widget*>(this)->non_client_view()); - } - const NonClientView* non_client_view() const { - return non_client_view_; - } - - ClientView* client_view() { - return const_cast<ClientView*>( - const_cast<const Widget*>(this)->client_view()); - } - const ClientView* client_view() const { - return non_client_view()->client_view(); - } - const ui::Compositor* compositor() const { return compositor_.get(); } ui::Compositor* compositor() { return compositor_.get(); } @@ -422,7 +375,6 @@ class Widget : public internal::NativeWidgetDelegate, virtual void OnNativeFocus(gfx::NativeView focused_view) OVERRIDE; virtual void OnNativeBlur(gfx::NativeView focused_view) OVERRIDE; virtual void OnNativeWidgetCreated() OVERRIDE; - virtual void OnNativeWidgetDestroyed() OVERRIDE; virtual void OnSizeChanged(const gfx::Size& new_size) OVERRIDE; virtual bool HasFocusManager() const OVERRIDE; virtual bool OnNativeWidgetPaintAccelerated( @@ -478,8 +430,6 @@ class Widget : public internal::NativeWidgetDelegate, NativeWidget* native_widget_; - InitParams::Type type_; - // Non-owned pointer to the Widget's delegate. May be NULL if no delegate is // being used. WidgetDelegate* widget_delegate_; @@ -489,12 +439,6 @@ class Widget : public internal::NativeWidgetDelegate, // this and tooltip_manager_. scoped_ptr<internal::RootView> root_view_; - // The View that provides the non-client area of the window (title bar, - // window controls, sizing borders etc). To use an implementation other than - // the default, this class must be sub-classed and this value set to the - // desired implementation before calling |InitWindow()|. - NonClientView* non_client_view_; - // The focus manager keeping track of focus for this Widget and any of its // children. NULL for non top-level widgets. // WARNING: RootView's destructor calls into the FocusManager. As such, this @@ -517,10 +461,6 @@ class Widget : public internal::NativeWidgetDelegate, // See set_is_secondary_widget(). bool is_secondary_widget_; - // The current frame type in use by this window. Defaults to - // FRAME_TYPE_DEFAULT. - FrameType frame_type_; - DISALLOW_COPY_AND_ASSIGN(Widget); }; diff --git a/views/widget/widget_delegate.cc b/views/widget/widget_delegate.cc index fa91e7b..5e86035 100644 --- a/views/widget/widget_delegate.cc +++ b/views/widget/widget_delegate.cc @@ -140,9 +140,5 @@ ClientView* WidgetDelegate::CreateClientView(Window* window) { return new ClientView(window, GetContentsView()); } -NonClientFrameView* WidgetDelegate::CreateNonClientFrameView() { - return NULL; -} - } // namespace views diff --git a/views/widget/widget_delegate.h b/views/widget/widget_delegate.h index dac0253..a6aab4e 100644 --- a/views/widget/widget_delegate.h +++ b/views/widget/widget_delegate.h @@ -20,7 +20,6 @@ class Rect; namespace views { class ClientView; class DialogDelegate; -class NonClientFrameView; class View; class Window; @@ -140,10 +139,6 @@ class WidgetDelegate { // of the window. virtual ClientView* CreateClientView(Window* window); - // Called by the Widget to create the NonClient Frame View for this widget. - // Return NULL to use the default one. - virtual NonClientFrameView* CreateNonClientFrameView(); - Window* window() const { return window_; } protected: diff --git a/views/window/custom_frame_view.cc b/views/window/custom_frame_view.cc index 6f9bb8f..85d6ac9 100644 --- a/views/window/custom_frame_view.cc +++ b/views/window/custom_frame_view.cc @@ -63,7 +63,7 @@ const int kTitleCaptionSpacing = 5; /////////////////////////////////////////////////////////////////////////////// // CustomFrameView, public: -CustomFrameView::CustomFrameView(Widget* frame) +CustomFrameView::CustomFrameView(Window* frame) : ALLOW_THIS_IN_INITIALIZER_LIST(close_button_(new ImageButton(this))), ALLOW_THIS_IN_INITIALIZER_LIST(restore_button_(new ImageButton(this))), ALLOW_THIS_IN_INITIALIZER_LIST(maximize_button_(new ImageButton(this))), @@ -112,10 +112,10 @@ CustomFrameView::CustomFrameView(Widget* frame) rb.GetBitmapNamed(IDR_MINIMIZE_P)); AddChildView(minimize_button_); - should_show_minmax_buttons_ = frame_->widget_delegate()->CanMaximize(); - should_show_client_edge_ = frame_->widget_delegate()->ShouldShowClientEdge(); + should_show_minmax_buttons_ = frame_->window_delegate()->CanMaximize(); + should_show_client_edge_ = frame_->window_delegate()->ShouldShowClientEdge(); - if (frame_->widget_delegate()->ShouldShowWindowIcon()) { + if (frame_->window_delegate()->ShouldShowWindowIcon()) { window_icon_ = new ImageButton(this); AddChildView(window_icon_); } @@ -176,7 +176,7 @@ int CustomFrameView::NonClientHitTest(const gfx::Point& point) { int window_component = GetHTComponentForFrame(point, FrameBorderThickness(), NonClientBorderThickness(), kResizeAreaCornerSize, kResizeAreaCornerSize, - frame_->widget_delegate()->CanResize()); + frame_->window_delegate()->CanResize()); // Fall back to the caption if no other component matches. return (window_component == HTNOWHERE) ? HTCAPTION : window_component; } @@ -403,7 +403,7 @@ void CustomFrameView::PaintMaximizedFrameBorder(gfx::Canvas* canvas) { } void CustomFrameView::PaintTitleBar(gfx::Canvas* canvas) { - WidgetDelegate* d = frame_->widget_delegate(); + 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 @@ -536,11 +536,11 @@ void CustomFrameView::LayoutTitleBar() { // The window title is based on the calculated icon position, even when there // is no icon. gfx::Rect icon_bounds(IconBounds()); - if (frame_->widget_delegate()->ShouldShowWindowIcon()) + if (frame_->window_delegate()->ShouldShowWindowIcon()) window_icon_->SetBoundsRect(icon_bounds); // Size the title. - int title_x = frame_->widget_delegate()->ShouldShowWindowIcon() ? + int title_x = frame_->window_delegate()->ShouldShowWindowIcon() ? icon_bounds.right() + kIconTitleSpacing : icon_bounds.x(); int title_height = title_font_->GetHeight(); // We bias the title position so that when the difference between the icon and diff --git a/views/window/custom_frame_view.h b/views/window/custom_frame_view.h index aa3367d..16f8ace 100644 --- a/views/window/custom_frame_view.h +++ b/views/window/custom_frame_view.h @@ -7,8 +7,8 @@ #pragma once #include "views/controls/button/image_button.h" -#include "views/widget/widget.h" #include "views/window/non_client_view.h" +#include "views/window/window.h" #include "views/window/window_resources.h" namespace gfx { @@ -32,7 +32,7 @@ namespace views { class CustomFrameView : public NonClientFrameView, public ButtonListener { public: - explicit CustomFrameView(Widget* frame); + explicit CustomFrameView(Window* frame); virtual ~CustomFrameView(); // Overridden from NonClientFrameView: @@ -114,7 +114,7 @@ class CustomFrameView : public NonClientFrameView, bool should_show_client_edge_; // The window that owns this view. - Widget* frame_; + Window* frame_; // Initialize various static resources. static void InitClass(); diff --git a/views/window/native_frame_view.cc b/views/window/native_frame_view.cc index 752bdec1f..55906ba 100644 --- a/views/window/native_frame_view.cc +++ b/views/window/native_frame_view.cc @@ -4,16 +4,16 @@ #include "views/window/native_frame_view.h" -#include "views/widget/native_widget.h" #include "views/widget/native_widget_win.h" -#include "views/widget/widget.h" +#include "views/window/native_window.h" +#include "views/window/window.h" namespace views { //////////////////////////////////////////////////////////////////////////////// // NativeFrameView, public: -NativeFrameView::NativeFrameView(Widget* frame) +NativeFrameView::NativeFrameView(Window* frame) : NonClientFrameView(), frame_(frame) { } @@ -32,7 +32,7 @@ gfx::Rect NativeFrameView::GetWindowBoundsForClientBounds( const gfx::Rect& client_bounds) const { RECT rect = client_bounds.ToRECT(); NativeWidgetWin* widget_win = - static_cast<NativeWidgetWin*>(frame_->native_widget()); + static_cast<NativeWidgetWin*>(frame_->native_window()->AsNativeWidget()); AdjustWindowRectEx(&rect, widget_win->window_style(), FALSE, widget_win->window_ex_style()); return gfx::Rect(rect); diff --git a/views/window/native_frame_view.h b/views/window/native_frame_view.h index 6c50648..9bc943f 100644 --- a/views/window/native_frame_view.h +++ b/views/window/native_frame_view.h @@ -10,11 +10,11 @@ namespace views { -class Widget; +class Window; class NativeFrameView : public NonClientFrameView { public: - explicit NativeFrameView(Widget* frame); + explicit NativeFrameView(Window* frame); virtual ~NativeFrameView(); // NonClientFrameView overrides: @@ -33,7 +33,7 @@ class NativeFrameView : public NonClientFrameView { private: // Our containing frame. - Widget* frame_; + Window* frame_; DISALLOW_COPY_AND_ASSIGN(NativeFrameView); }; diff --git a/views/window/native_window.h b/views/window/native_window.h index ca5c6fc..dc3a579 100644 --- a/views/window/native_window.h +++ b/views/window/native_window.h @@ -63,6 +63,14 @@ class NativeWindow { // Enables or disables the close button for the window. virtual void EnableClose(bool enable) = 0; + + // Window pass-thrus --------------------------------------------------------- + // See documentation in window.h + + virtual NonClientFrameView* CreateFrameViewForWindow() = 0; + virtual void UpdateFrameAfterFrameChange() = 0; + virtual bool ShouldUseNativeFrame() const = 0; + virtual void FrameTypeChanged() = 0; }; } // namespace views diff --git a/views/window/native_window_delegate.h b/views/window/native_window_delegate.h index e596120..12cf3cf 100644 --- a/views/window/native_window_delegate.h +++ b/views/window/native_window_delegate.h @@ -36,11 +36,11 @@ class NativeWindowDelegate { virtual bool IsDialogBox() const = 0; // Returns the smallest size the window can be resized to by the user. - virtual gfx::Size GetMinimumSize() = 0; + virtual gfx::Size GetMinimumSize() const = 0; // Returns the non-client component (see views/window/hit_test.h) containing // |point|, in client coordinates. - virtual int GetNonClientComponent(const gfx::Point& point) = 0; + virtual int GetNonClientComponent(const gfx::Point& point) const = 0; // Runs the specified native command. Returns true if the command is handled. virtual bool ExecuteCommand(int command_id) = 0; @@ -59,6 +59,9 @@ class NativeWindowDelegate { // last chance to do anything with the native window handle. virtual void OnNativeWindowDestroying() = 0; + // Called just after the native window is destroyed. + virtual void OnNativeWindowDestroyed() = 0; + // Called when the native window's position or size has changed. virtual void OnNativeWindowBoundsChanged() = 0; diff --git a/views/window/native_window_gtk.cc b/views/window/native_window_gtk.cc index dd944ad..7d238d4 100644 --- a/views/window/native_window_gtk.cc +++ b/views/window/native_window_gtk.cc @@ -238,6 +238,27 @@ const Window* NativeWindowGtk::GetWindow() const { return delegate_->AsWindow(); } +NonClientFrameView* NativeWindowGtk::CreateFrameViewForWindow() { + return NULL; +} + +void NativeWindowGtk::UpdateFrameAfterFrameChange() { + // We currently don't support different frame types on Gtk, so we don't + // need to implement this. + NOTIMPLEMENTED(); +} + +bool NativeWindowGtk::ShouldUseNativeFrame() const { + return false; +} + +void NativeWindowGtk::FrameTypeChanged() { + // This is called when the Theme has changed, so forward the event to the root + // widget. + GetWidget()->ThemeChanged(); + GetWidget()->GetRootView()->SchedulePaint(); +} + //////////////////////////////////////////////////////////////////////////////// // NativeWindowGtk, NativeWidgetGtk overrides: @@ -281,6 +302,11 @@ void NativeWindowGtk::OnDestroy(GtkWidget* widget) { NativeWidgetGtk::OnDestroy(widget); } +void NativeWindowGtk::OnDestroyed(GObject *where_the_object_was) { + delegate_->OnNativeWindowDestroyed(); + NativeWidgetGtk::OnDestroyed(where_the_object_was); +} + //////////////////////////////////////////////////////////////////////////////// // NativeWindow, public: diff --git a/views/window/native_window_gtk.h b/views/window/native_window_gtk.h index 3ea4c25..f939f97 100644 --- a/views/window/native_window_gtk.h +++ b/views/window/native_window_gtk.h @@ -52,6 +52,10 @@ class NativeWindowGtk : public NativeWidgetGtk, public NativeWindow { virtual void ShowNativeWindow(ShowState state) OVERRIDE; virtual void BecomeModal() OVERRIDE; virtual void EnableClose(bool enable) OVERRIDE; + virtual NonClientFrameView* CreateFrameViewForWindow() OVERRIDE; + virtual void UpdateFrameAfterFrameChange() OVERRIDE; + virtual bool ShouldUseNativeFrame() const OVERRIDE; + virtual void FrameTypeChanged() OVERRIDE; // Overridden from NativeWidgetGtk: virtual void Restore() OVERRIDE; @@ -62,6 +66,7 @@ class NativeWindowGtk : public NativeWidgetGtk, public NativeWindow { friend class Window; virtual void OnDestroy(GtkWidget* widget); + virtual void OnDestroyed(GObject *where_the_object_was); private: static gboolean CallConfigureEvent(GtkWidget* widget, diff --git a/views/window/native_window_views.cc b/views/window/native_window_views.cc index 26bc697..c9f2a84 100644 --- a/views/window/native_window_views.cc +++ b/views/window/native_window_views.cc @@ -57,4 +57,19 @@ void NativeWindowViews::BecomeModal() { void NativeWindowViews::EnableClose(bool enable) { } +NonClientFrameView* NativeWindowViews::CreateFrameViewForWindow() { + return NULL; +} + +void NativeWindowViews::UpdateFrameAfterFrameChange() { +} + +bool NativeWindowViews::ShouldUseNativeFrame() const { + NOTIMPLEMENTED(); + return false; +} + +void NativeWindowViews::FrameTypeChanged() { +} + } // namespace views diff --git a/views/window/native_window_views.h b/views/window/native_window_views.h index 1489d08..20eb3d0 100644 --- a/views/window/native_window_views.h +++ b/views/window/native_window_views.h @@ -33,6 +33,10 @@ class NativeWindowViews : public NativeWidgetViews, virtual void ShowNativeWindow(ShowState state) OVERRIDE; virtual void BecomeModal() OVERRIDE; virtual void EnableClose(bool enable) OVERRIDE; + virtual NonClientFrameView* CreateFrameViewForWindow() OVERRIDE; + virtual void UpdateFrameAfterFrameChange() OVERRIDE; + virtual bool ShouldUseNativeFrame() const OVERRIDE; + virtual void FrameTypeChanged() OVERRIDE; internal::NativeWindowDelegate* delegate_; diff --git a/views/window/native_window_win.cc b/views/window/native_window_win.cc index df35437..db688df 100644 --- a/views/window/native_window_win.cc +++ b/views/window/native_window_win.cc @@ -22,6 +22,7 @@ #include "views/accessibility/native_view_accessibility_win.h" #include "views/window/client_view.h" #include "views/window/native_window_delegate.h" +#include "views/window/native_frame_view.h" #include "views/window/non_client_view.h" #include "views/window/window_delegate.h" @@ -74,6 +75,13 @@ void SendFrameChanged(HWND window) { SWP_NOSENDCHANGING | SWP_NOSIZE | SWP_NOZORDER); } +// Callback used to notify child windows that the top level window received a +// DWMCompositionChanged message. +BOOL CALLBACK SendDwmCompositionChanged(HWND window, LPARAM param) { + SendMessage(window, WM_DWMCOMPOSITIONCHANGED, 0, 0); + return TRUE; +} + // Enables or disables the menu item for the specified command and menu. void EnableMenuItem(HMENU menu, UINT command, bool enabled) { UINT flags = MF_BYCOMMAND | (enabled ? MF_ENABLED : MF_DISABLED | MF_GRAYED); @@ -308,6 +316,11 @@ void NativeWindowWin::OnExitSizeMove() { delegate_->OnNativeWindowEndUserBoundsChange(); } +void NativeWindowWin::OnFinalMessage(HWND window) { + delegate_->OnNativeWindowDestroyed(); + NativeWidgetWin::OnFinalMessage(window); +} + void NativeWindowWin::OnGetMinMaxInfo(MINMAXINFO* minmax_info) { gfx::Size min_window_size(delegate_->GetMinimumSize()); minmax_info->ptMinTrackSize.x = min_window_size.width(); @@ -724,7 +737,10 @@ LRESULT NativeWindowWin::OnSetText(const wchar_t* text) { void NativeWindowWin::OnSize(UINT size_param, const CSize& new_size) { delegate_->OnNativeWindowBoundsChanged(); RedrawWindow(GetNativeView(), NULL, NULL, RDW_INVALIDATE | RDW_ALLCHILDREN); - NativeWidgetWin::OnSize(size_param, 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(false); } void NativeWindowWin::OnSysCommand(UINT notification_code, CPoint click) { @@ -903,6 +919,49 @@ void NativeWindowWin::EnableClose(bool enable) { SendFrameChanged(GetNativeView()); } +NonClientFrameView* NativeWindowWin::CreateFrameViewForWindow() { + return GetWindow()->ShouldUseNativeFrame() ? + new NativeFrameView(GetWindow()) : NULL; +} + +void NativeWindowWin::UpdateFrameAfterFrameChange() { + // We've either gained or lost a custom window region, so reset it now. + ResetWindowRegion(true); +} + +bool NativeWindowWin::ShouldUseNativeFrame() const { + return NativeWidgetWin::IsAeroGlassEnabled(); +} + +void NativeWindowWin::FrameTypeChanged() { + // Called when the frame type could possibly be changing (theme change or + // DWM composition change). + if (base::win::GetVersion() >= base::win::VERSION_VISTA) { + // We need to toggle the rendering policy of the DWM/glass frame as we + // change from opaque to glass. "Non client rendering enabled" means that + // the DWM's glass non-client rendering is enabled, which is why + // DWMNCRP_ENABLED is used for the native frame case. _DISABLED means the + // DWM doesn't render glass, and so is used in the custom frame case. + DWMNCRENDERINGPOLICY policy = GetWindow()->ShouldUseNativeFrame() ? + DWMNCRP_ENABLED : DWMNCRP_DISABLED; + DwmSetWindowAttribute(GetNativeView(), DWMWA_NCRENDERING_POLICY, + &policy, sizeof(DWMNCRENDERINGPOLICY)); + } + + // Send a frame change notification, since the non-client metrics have + // changed. + SendFrameChanged(GetNativeView()); + + // Update the non-client view with the correct frame view for the active frame + // type. + GetWindow()->non_client_view()->UpdateFrame(); + + // WM_DWMCOMPOSITIONCHANGED is only sent to top level windows, however we want + // to notify our children too, since we can have MDI child windows who need to + // update their appearance. + EnumChildWindows(GetNativeView(), &SendDwmCompositionChanged, NULL); +} + //////////////////////////////////////////////////////////////////////////////// // NativeWindowWin, NativeWidgetWin overrides: @@ -964,6 +1023,49 @@ void NativeWindowWin::UnlockUpdates() { lock_updates_ = false; } +void NativeWindowWin::ResetWindowRegion(bool force) { + // A native frame uses the native window region, and we don't want to mess + // with it. + if (GetWindow()->ShouldUseNativeFrame()) { + 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. + HRGN current_rgn = CreateRectRgn(0, 0, 0, 0); + int current_rgn_result = GetWindowRgn(GetNativeView(), current_rgn); + + CRect window_rect; + GetWindowRect(&window_rect); + HRGN new_region; + if (IsMaximized()) { + HMONITOR monitor = + MonitorFromWindow(GetNativeView(), 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; + GetWindow()->non_client_view()->GetWindowMask( + gfx::Size(window_rect.Width(), window_rect.Height()), &window_mask); + new_region = window_mask.CreateNativeRegion(); + } + + if (current_rgn_result == ERROR || !EqualRgn(current_rgn, new_region)) { + // SetWindowRgn takes ownership of the HRGN created by CreateNativeRegion. + SetWindowRgn(new_region, TRUE); + } else { + DeleteObject(new_region); + } + + DeleteObject(current_rgn); +} + LRESULT NativeWindowWin::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 diff --git a/views/window/native_window_win.h b/views/window/native_window_win.h index 8652c42..d251579 100644 --- a/views/window/native_window_win.h +++ b/views/window/native_window_win.h @@ -81,6 +81,7 @@ class NativeWindowWin : public NativeWidgetWin, LPARAM l_param) OVERRIDE; virtual void OnEnterSizeMove() OVERRIDE; virtual void OnExitSizeMove() OVERRIDE; + virtual void OnFinalMessage(HWND window) OVERRIDE; virtual void OnGetMinMaxInfo(MINMAXINFO* minmax_info) OVERRIDE; virtual void OnInitMenu(HMENU menu) OVERRIDE; virtual LRESULT OnMouseActivate(UINT message, WPARAM w_param, LPARAM l_param) @@ -114,6 +115,10 @@ class NativeWindowWin : public NativeWidgetWin, virtual void ShowNativeWindow(ShowState state) OVERRIDE; virtual void BecomeModal() OVERRIDE; virtual void EnableClose(bool enable) OVERRIDE; + virtual NonClientFrameView* CreateFrameViewForWindow() OVERRIDE; + virtual void UpdateFrameAfterFrameChange() OVERRIDE; + virtual bool ShouldUseNativeFrame() const OVERRIDE; + virtual void FrameTypeChanged() OVERRIDE; // Overridden from NativeWidgetWin: virtual bool IsActive() const OVERRIDE; @@ -135,6 +140,11 @@ class NativeWindowWin : public NativeWidgetWin, // Stops ignoring SetWindowPos() requests (see below). void StopIgnoringPosChanges() { ignore_window_pos_changes_ = false; } + // Resets the window region for the current window bounds if necessary. + // If |force| is true, the window region is reset to NULL even for native + // frame windows. + void ResetWindowRegion(bool force); + // Update accessibility information via our WindowDelegate. void UpdateAccessibleName(std::wstring& accessible_name); void UpdateAccessibleRole(); diff --git a/views/window/non_client_view.cc b/views/window/non_client_view.cc index febf26c..a930a19 100644 --- a/views/window/non_client_view.cc +++ b/views/window/non_client_view.cc @@ -29,8 +29,9 @@ static const int kClientViewIndex = 1; //////////////////////////////////////////////////////////////////////////////// // NonClientView, public: -NonClientView::NonClientView() - : client_view_(NULL) { +NonClientView::NonClientView(Window* frame) + : frame_(frame), + client_view_(NULL) { } NonClientView::~NonClientView() { @@ -58,12 +59,11 @@ void NonClientView::WindowClosing() { } void NonClientView::UpdateFrame() { - Widget* widget = GetWidget(); - SetFrameView(widget->CreateNonClientFrameView()); - widget->ThemeChanged(); + SetFrameView(frame_->CreateFrameViewForWindow()); + GetWidget()->ThemeChanged(); Layout(); SchedulePaint(); - widget->UpdateFrameAfterFrameChange(); + frame_->UpdateFrameAfterFrameChange(); } void NonClientView::DisableInactiveRendering(bool disable) { diff --git a/views/window/non_client_view.h b/views/window/non_client_view.h index 395ec18..0127d8b 100644 --- a/views/window/non_client_view.h +++ b/views/window/non_client_view.h @@ -130,7 +130,7 @@ class NonClientFrameView : public View { // class NonClientView : public View { public: - NonClientView(); + explicit NonClientView(Window* frame); virtual ~NonClientView(); // Returns the current NonClientFrameView instance, or NULL if @@ -213,6 +213,9 @@ class NonClientView : public View { OVERRIDE; 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. diff --git a/views/window/window.cc b/views/window/window.cc index 4dc8fd8..bae284e 100644 --- a/views/window/window.cc +++ b/views/window/window.cc @@ -14,6 +14,7 @@ #include "ui/gfx/size.h" #include "views/widget/widget.h" #include "views/widget/native_widget.h" +#include "views/window/custom_frame_view.h" #include "views/window/native_window.h" #include "views/window/window_delegate.h" @@ -31,10 +32,14 @@ Window::InitParams::InitParams(WindowDelegate* window_delegate) Window::Window() : native_window_(NULL), + window_delegate_(NULL), + ALLOW_THIS_IN_INITIALIZER_LIST( + non_client_view_(new NonClientView(this))), saved_maximized_state_(false), minimum_size_(100, 100), disable_inactive_rendering_(false), - window_closed_(false) { + window_closed_(false), + frame_type_(FRAME_TYPE_DEFAULT) { } Window::~Window() { @@ -75,13 +80,18 @@ gfx::Size Window::GetLocalizedContentsSize(int col_resource_id, } void Window::InitWindow(const InitParams& params) { + window_delegate_ = params.window_delegate; + DCHECK(window_delegate_); + DCHECK(!window_delegate_->window_); + window_delegate_->window_ = this; native_window_ = params.native_window ? params.native_window : NativeWindow::CreateNativeWindow(this); + // If frame_view was set already, don't replace it with default one. + if (!non_client_view()->frame_view()) + non_client_view()->SetFrameView(CreateFrameViewForWindow()); InitParams modified_params = params; modified_params.widget_init_params.delegate = params.window_delegate; - DCHECK(!modified_params.widget_init_params.delegate->window_); - modified_params.widget_init_params.delegate->window_ = this; modified_params.widget_init_params.native_widget = native_window_->AsNativeWidget(); Init(modified_params.widget_init_params); @@ -102,36 +112,65 @@ void Window::ShowInactive() { void Window::DisableInactiveRendering() { disable_inactive_rendering_ = true; - non_client_view()->DisableInactiveRendering(disable_inactive_rendering_); + non_client_view_->DisableInactiveRendering(disable_inactive_rendering_); } void Window::EnableClose(bool enable) { - non_client_view()->EnableClose(enable); + non_client_view_->EnableClose(enable); native_window_->EnableClose(enable); } void Window::UpdateWindowTitle() { // If the non-client view is rendering its own title, it'll need to relayout // now. - non_client_view()->Layout(); + non_client_view_->Layout(); // Update the native frame's text. We do this regardless of whether or not // the native frame is being used, since this also updates the taskbar, etc. string16 window_title; - if (native_window_->AsNativeWidget()->IsScreenReaderActive()) { - window_title = WideToUTF16(widget_delegate()->GetAccessibleWindowTitle()); - } else { - window_title = WideToUTF16(widget_delegate()->GetWindowTitle()); - } + if (native_window_->AsNativeWidget()->IsScreenReaderActive()) + window_title = WideToUTF16(window_delegate_->GetAccessibleWindowTitle()); + else + window_title = WideToUTF16(window_delegate_->GetWindowTitle()); base::i18n::AdjustStringForLocaleDirection(&window_title); native_window_->AsNativeWidget()->SetWindowTitle(UTF16ToWide(window_title)); } void Window::UpdateWindowIcon() { - non_client_view()->UpdateWindowIcon(); + non_client_view_->UpdateWindowIcon(); native_window_->AsNativeWidget()->SetWindowIcons( - widget_delegate()->GetWindowIcon(), - widget_delegate()->GetWindowAppIcon()); + window_delegate_->GetWindowIcon(), + window_delegate_->GetWindowAppIcon()); +} + +NonClientFrameView* Window::CreateFrameViewForWindow() { + NonClientFrameView* frame_view = native_window_->CreateFrameViewForWindow(); + return frame_view ? frame_view : new CustomFrameView(this); +} + +void Window::UpdateFrameAfterFrameChange() { + native_window_->UpdateFrameAfterFrameChange(); +} + +bool Window::ShouldUseNativeFrame() const { + if (frame_type_ != FRAME_TYPE_DEFAULT) + return frame_type_ == FRAME_TYPE_FORCE_NATIVE; + return native_window_->ShouldUseNativeFrame(); +} + +void Window::DebugToggleFrameType() { + if (frame_type_ == FRAME_TYPE_DEFAULT) { + frame_type_ = ShouldUseNativeFrame() ? FRAME_TYPE_FORCE_CUSTOM : + FRAME_TYPE_FORCE_NATIVE; + } else { + frame_type_ = frame_type_ == FRAME_TYPE_FORCE_CUSTOM ? + FRAME_TYPE_FORCE_NATIVE : FRAME_TYPE_FORCE_CUSTOM; + } + FrameTypeChanged(); +} + +void Window::FrameTypeChanged() { + native_window_->FrameTypeChanged(); } //////////////////////////////////////////////////////////////////////////////// @@ -155,7 +194,7 @@ void Window::Close() { return; } - if (non_client_view()->CanClose()) { + if (non_client_view_->CanClose()) { SaveWindowPosition(); Widget::Close(); window_closed_ = true; @@ -166,7 +205,7 @@ void Window::Close() { // Window, internal::NativeWindowDelegate implementation: bool Window::CanActivate() const { - return widget_delegate()->CanActivate(); + return window_delegate_->CanActivate(); } bool Window::IsInactiveRenderingDisabled() const { @@ -175,44 +214,43 @@ bool Window::IsInactiveRenderingDisabled() const { void Window::EnableInactiveRendering() { disable_inactive_rendering_ = false; - non_client_view()->DisableInactiveRendering(false); + non_client_view_->DisableInactiveRendering(false); } bool Window::IsModal() const { - return widget_delegate()->IsModal(); + return window_delegate_->IsModal(); } bool Window::IsDialogBox() const { - return !!widget_delegate()->AsDialogDelegate(); + return !!window_delegate_->AsDialogDelegate(); } -gfx::Size Window::GetMinimumSize() { - return non_client_view()->GetMinimumSize(); +gfx::Size Window::GetMinimumSize() const { + return non_client_view_->GetMinimumSize(); } -int Window::GetNonClientComponent(const gfx::Point& point) { - return non_client_view()->NonClientHitTest(point); +int Window::GetNonClientComponent(const gfx::Point& point) const { + return non_client_view_->NonClientHitTest(point); } bool Window::ExecuteCommand(int command_id) { - return widget_delegate()->ExecuteWindowsCommand(command_id); + return window_delegate_->ExecuteWindowsCommand(command_id); } void Window::OnNativeWindowCreated(const gfx::Rect& bounds) { - if (widget_delegate()->IsModal()) + if (window_delegate_->IsModal()) native_window_->BecomeModal(); // 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( - widget_delegate()->CreateClientView(this)); - SetContentsView(non_client_view()); + non_client_view_->set_client_view(window_delegate_->CreateClientView(this)); + SetContentsView(non_client_view_); UpdateWindowTitle(); native_window_->AsNativeWidget()->SetAccessibleRole( - widget_delegate()->GetAccessibleWindowRole()); + window_delegate_->GetAccessibleWindowRole()); native_window_->AsNativeWidget()->SetAccessibleState( - widget_delegate()->GetAccessibleWindowState()); + window_delegate_->GetAccessibleWindowState()); SetInitialBounds(bounds); } @@ -220,20 +258,25 @@ void Window::OnNativeWindowCreated(const gfx::Rect& bounds) { void Window::OnNativeWindowActivationChanged(bool active) { if (!active) SaveWindowPosition(); - widget_delegate()->OnWindowActivationChanged(active); + window_delegate_->OnWindowActivationChanged(active); } void Window::OnNativeWindowBeginUserBoundsChange() { - widget_delegate()->OnWindowBeginUserBoundsChange(); + window_delegate_->OnWindowBeginUserBoundsChange(); } void Window::OnNativeWindowEndUserBoundsChange() { - widget_delegate()->OnWindowEndUserBoundsChange(); + window_delegate_->OnWindowEndUserBoundsChange(); } void Window::OnNativeWindowDestroying() { - non_client_view()->WindowClosing(); - widget_delegate()->WindowClosing(); + non_client_view_->WindowClosing(); + window_delegate_->WindowClosing(); +} + +void Window::OnNativeWindowDestroyed() { + window_delegate_->DeleteDelegate(); + window_delegate_ = NULL; } void Window::OnNativeWindowBoundsChanged() { @@ -258,14 +301,13 @@ void Window::SetInitialBounds(const gfx::Rect& bounds) { // state will have been lost. Sadly there's no way to tell on Windows when // a window is restored from maximized state, so we can't more accurately // track maximized state independently of sizing information. - widget_delegate()->GetSavedMaximizedState( - &saved_maximized_state_); + window_delegate_->GetSavedMaximizedState(&saved_maximized_state_); // Restore the window's placement from the controller. gfx::Rect saved_bounds = bounds; - if (widget_delegate()->GetSavedWindowBounds(&saved_bounds)) { - if (!widget_delegate()->ShouldRestoreWindowSize()) { - saved_bounds.set_size(non_client_view()->GetPreferredSize()); + if (window_delegate_->GetSavedWindowBounds(&saved_bounds)) { + if (!window_delegate_->ShouldRestoreWindowSize()) { + saved_bounds.set_size(non_client_view_->GetPreferredSize()); } else { // Make sure the bounds are at least the minimum size. if (saved_bounds.width() < minimum_size_.width()) { @@ -291,7 +333,7 @@ void Window::SetInitialBounds(const gfx::Rect& bounds) { // No initial bounds supplied, so size the window to its content and // center over its parent. native_window_->AsNativeWidget()->CenterWindow( - non_client_view()->GetPreferredSize()); + non_client_view_->GetPreferredSize()); } else { // Use the supplied initial bounds. SetBoundsConstrained(bounds, NULL); @@ -304,7 +346,7 @@ void Window::SaveWindowPosition() { // by go/crash) that in some circumstances we can end up here after // WM_DESTROY, at which point the window delegate is likely gone. So just // bail. - if (!widget_delegate()) + if (!window_delegate_) return; bool maximized; @@ -312,7 +354,7 @@ void Window::SaveWindowPosition() { native_window_->AsNativeWidget()->GetWindowBoundsAndMaximizedState( &bounds, &maximized); - widget_delegate()->SaveWindowPlacement(bounds, maximized); + window_delegate_->SaveWindowPlacement(bounds, maximized); } } // namespace views diff --git a/views/window/window.h b/views/window/window.h index d659686..98fc322 100644 --- a/views/window/window.h +++ b/views/window/window.h @@ -8,7 +8,9 @@ #include "ui/gfx/native_widget_types.h" #include "views/widget/widget.h" +#include "views/window/client_view.h" #include "views/window/native_window_delegate.h" +#include "views/window/non_client_view.h" namespace gfx { class Font; @@ -19,6 +21,7 @@ class Size; namespace views { class NativeWindow; +class NonClientFrameView; class Widget; class WindowDelegate; @@ -40,6 +43,12 @@ class Window : public Widget, Widget::InitParams widget_init_params; }; + enum FrameType { + FRAME_TYPE_DEFAULT, // Use whatever the default would be. + FRAME_TYPE_FORCE_CUSTOM, // Force the custom frame. + FRAME_TYPE_FORCE_NATIVE // Force the native frame. + }; + Window(); virtual ~Window(); @@ -89,6 +98,25 @@ class Window : public Widget, // Tell the window to update its icon from the delegate. void UpdateWindowIcon(); + // Creates an appropriate NonClientFrameView for this window. + virtual NonClientFrameView* CreateFrameViewForWindow(); + + // Updates the frame after an event caused it to be changed. + virtual void UpdateFrameAfterFrameChange(); + + void set_frame_type(FrameType frame_type) { frame_type_ = frame_type; } + FrameType frame_type() const { return frame_type_; } + + // Whether we should be using a native frame. + bool ShouldUseNativeFrame() const; + + // Forces the frame into the alternate frame type (custom or native) depending + // on its current state. + void DebugToggleFrameType(); + + // Tell the window that something caused the frame type to change. + void FrameTypeChanged(); + // Overridden from Widget: virtual void Show() OVERRIDE; virtual void Close() OVERRIDE; @@ -98,7 +126,23 @@ class Window : public Widget, const_cast<const Window*>(this)->window_delegate()); } const WindowDelegate* window_delegate() const { - return reinterpret_cast<WindowDelegate*>(widget_delegate()); + return window_delegate_; + } + + NonClientView* non_client_view() { + return const_cast<NonClientView*>( + const_cast<const Window*>(this)->non_client_view()); + } + const NonClientView* non_client_view() const { + return non_client_view_; + } + + ClientView* client_view() { + return const_cast<ClientView*>( + const_cast<const Window*>(this)->client_view()); + } + const ClientView* client_view() const { + return non_client_view()->client_view(); } NativeWindow* native_window() { return native_window_; } @@ -110,14 +154,15 @@ class Window : public Widget, virtual void EnableInactiveRendering() OVERRIDE; virtual bool IsModal() const OVERRIDE; virtual bool IsDialogBox() const OVERRIDE; - virtual gfx::Size GetMinimumSize() OVERRIDE; - virtual int GetNonClientComponent(const gfx::Point& point) OVERRIDE; + virtual gfx::Size GetMinimumSize() const OVERRIDE; + virtual int GetNonClientComponent(const gfx::Point& point) const OVERRIDE; virtual bool ExecuteCommand(int command_id) OVERRIDE; virtual void OnNativeWindowCreated(const gfx::Rect& bounds) OVERRIDE; virtual void OnNativeWindowActivationChanged(bool active) OVERRIDE; virtual void OnNativeWindowBeginUserBoundsChange() OVERRIDE; virtual void OnNativeWindowEndUserBoundsChange() OVERRIDE; virtual void OnNativeWindowDestroying() OVERRIDE; + virtual void OnNativeWindowDestroyed() OVERRIDE; virtual void OnNativeWindowBoundsChanged() OVERRIDE; virtual Window* AsWindow() OVERRIDE; virtual internal::NativeWidgetDelegate* AsNativeWidgetDelegate() OVERRIDE; @@ -132,6 +177,15 @@ class Window : public Widget, NativeWindow* native_window_; + // Our window delegate (see InitWindow() method for documentation). + WindowDelegate* window_delegate_; + + // The View that provides the non-client area of the window (title bar, + // window controls, sizing borders etc). To use an implementation other than + // the default, this class must be sub-classed and this value set to the + // desired implementation before calling |InitWindow()|. + NonClientView* non_client_view_; + // The saved maximized state for this window. See note in SetInitialBounds // that explains why we save this. bool saved_maximized_state_; @@ -146,6 +200,10 @@ class Window : public Widget, // Set to true if the window is in the process of closing . bool window_closed_; + // The current frame type in use by this window. Defaults to + // FRAME_TYPE_DEFAULT. + FrameType frame_type_; + DISALLOW_COPY_AND_ASSIGN(Window); }; |