summaryrefslogtreecommitdiffstats
path: root/views/widget
diff options
context:
space:
mode:
authorben@chromium.org <ben@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-06-02 22:07:05 +0000
committerben@chromium.org <ben@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-06-02 22:07:05 +0000
commit14bcec307d7ec6b13e90fe5e5ac8ca5aaa397b4b (patch)
tree7c88cf92588f0d99a38757f52cc92b47f7e053ef /views/widget
parent6b8b0f08cfebb37c13f6c835c37d9ed9e982fc37 (diff)
downloadchromium_src-14bcec307d7ec6b13e90fe5e5ac8ca5aaa397b4b.zip
chromium_src-14bcec307d7ec6b13e90fe5e5ac8ca5aaa397b4b.tar.gz
chromium_src-14bcec307d7ec6b13e90fe5e5ac8ca5aaa397b4b.tar.bz2
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 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@87702 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'views/widget')
-rw-r--r--views/widget/native_widget.h8
-rw-r--r--views/widget/native_widget_delegate.h3
-rw-r--r--views/widget/native_widget_gtk.cc22
-rw-r--r--views/widget/native_widget_gtk.h4
-rw-r--r--views/widget/native_widget_views.cc15
-rw-r--r--views/widget/native_widget_views.h4
-rw-r--r--views/widget/native_widget_win.cc107
-rw-r--r--views/widget/native_widget_win.h9
-rw-r--r--views/widget/widget.cc67
-rw-r--r--views/widget/widget.h60
-rw-r--r--views/widget/widget_delegate.cc4
-rw-r--r--views/widget/widget_delegate.h5
12 files changed, 305 insertions, 3 deletions
diff --git a/views/widget/native_widget.h b/views/widget/native_widget.h
index f3faba0..6cb4147 100644
--- a/views/widget/native_widget.h
+++ b/views/widget/native_widget.h
@@ -66,6 +66,14 @@ 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 05af457..d39bd58 100644
--- a/views/widget/native_widget_delegate.h
+++ b/views/widget/native_widget_delegate.h
@@ -31,6 +31,9 @@ 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 c5f926c..392abe8 100644
--- a/views/widget/native_widget_gtk.cc
+++ b/views/widget/native_widget_gtk.cc
@@ -736,6 +736,27 @@ 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();
}
@@ -1435,6 +1456,7 @@ 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 e6a9951..2603298 100644
--- a/views/widget/native_widget_gtk.h
+++ b/views/widget/native_widget_gtk.h
@@ -148,6 +148,10 @@ 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 9f26791..d0eebe4 100644
--- a/views/widget/native_widget_views.cc
+++ b/views/widget/native_widget_views.cc
@@ -48,6 +48,21 @@ 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 96bdc9a..f6d445d 100644
--- a/views/widget/native_widget_views.h
+++ b/views/widget/native_widget_views.h
@@ -35,6 +35,10 @@ 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 1afb3e5..db9f73a 100644
--- a/views/widget/native_widget_win.cc
+++ b/views/widget/native_widget_win.cc
@@ -37,6 +37,7 @@
#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")
@@ -167,6 +168,21 @@ 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__";
@@ -275,6 +291,49 @@ 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();
}
@@ -1241,7 +1300,9 @@ void NativeWidgetWin::OnSettingChange(UINT flags, const wchar_t* section) {
}
void NativeWidgetWin::OnSize(UINT param, const CSize& size) {
- SetMsgHandled(FALSE);
+ // 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 NativeWidgetWin::OnSysCommand(UINT notification_code, CPoint click) {
@@ -1275,6 +1336,7 @@ void NativeWidgetWin::OnWindowPosChanged(WINDOWPOS* window_pos) {
}
void NativeWidgetWin::OnFinalMessage(HWND window) {
+ delegate_->OnNativeWidgetDestroyed();
if (ownership_ == Widget::InitParams::NATIVE_WIDGET_OWNS_WIDGET)
delete this;
}
@@ -1478,6 +1540,49 @@ 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 40f4c84..7dd4995 100644
--- a/views/widget/native_widget_win.h
+++ b/views/widget/native_widget_win.h
@@ -176,6 +176,10 @@ 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;
@@ -475,6 +479,11 @@ 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 bc84fb0..e2b2202 100644
--- a/views/widget/widget.cc
+++ b/views/widget/widget.cc
@@ -14,6 +14,7 @@
#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 {
@@ -22,6 +23,22 @@ 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:
@@ -73,10 +90,13 @@ 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) {
+ is_secondary_widget_(true),
+ frame_type_(FRAME_TYPE_DEFAULT) {
}
Widget::~Widget() {
@@ -104,7 +124,9 @@ Widget* Widget::GetWidgetForNativeView(gfx::NativeView native_view) {
}
void Widget::Init(const InitParams& params) {
- widget_delegate_ = params.delegate ? params.delegate : new WidgetDelegate;
+ type_ = params.type;
+ widget_delegate_ =
+ params.delegate ? params.delegate : new DefaultWidgetDelegate;
ownership_ = params.ownership;
native_widget_ =
params.native_widget ? params.native_widget
@@ -114,6 +136,10 @@ 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) --------------------------------------------
@@ -381,6 +407,38 @@ 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,
@@ -417,6 +475,11 @@ 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 912cc76..19952eb 100644
--- a/views/widget/widget.h
+++ b/views/widget/widget.h
@@ -15,6 +15,8 @@
#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.
@@ -46,6 +48,7 @@ namespace views {
class DefaultThemeProvider;
class InputMethod;
class NativeWidget;
+class NonClientFrameView;
class TooltipManager;
class View;
class WidgetDelegate;
@@ -82,6 +85,12 @@ 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.
@@ -354,6 +363,44 @@ 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(); }
@@ -375,6 +422,7 @@ 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(
@@ -430,6 +478,8 @@ 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_;
@@ -439,6 +489,12 @@ 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
@@ -461,6 +517,10 @@ 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 5e86035..fa91e7b 100644
--- a/views/widget/widget_delegate.cc
+++ b/views/widget/widget_delegate.cc
@@ -140,5 +140,9 @@ 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 a6aab4e..dac0253 100644
--- a/views/widget/widget_delegate.h
+++ b/views/widget/widget_delegate.h
@@ -20,6 +20,7 @@ class Rect;
namespace views {
class ClientView;
class DialogDelegate;
+class NonClientFrameView;
class View;
class Window;
@@ -139,6 +140,10 @@ 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: