diff options
author | ben@chromium.org <ben@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-05-13 17:01:46 +0000 |
---|---|---|
committer | ben@chromium.org <ben@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-05-13 17:01:46 +0000 |
commit | 9756ba445d7c6c7be8b9c885e944ccbf21742b3f (patch) | |
tree | 96bd517c4df7a0f05c38531ac5b96838ab132b30 /views | |
parent | 6c572a070755401823bb0f84d36913dbe1032334 (diff) | |
download | chromium_src-9756ba445d7c6c7be8b9c885e944ccbf21742b3f.zip chromium_src-9756ba445d7c6c7be8b9c885e944ccbf21742b3f.tar.gz chromium_src-9756ba445d7c6c7be8b9c885e944ccbf21742b3f.tar.bz2 |
Revert 85269 - Split the hierarchy.
* Widget ----
Now recognizes a supplied NativeWidget via InitParams. If this is specified then a default one is not created.
Is now created directly rather than using a factory. NativeWidget creation is not performed until Init() is called. This means some functions that rely on a NativeWidget must not be called until _AFTER_ Init() (explains some of the function call reordering in this CL, e.g. moving SetOpacity() until after Init()).
ResetLastMouseMovedFlag() moved to this API so that BaseTabStrip can call it in a cross-platform way.
Made last remaining unimplemented methods on Widget pass-thru to NativeWidget implementations.
* WidgetWin/WidgetGtk ----
The NativeWidget implementations now both require a NativeWidgetDelegate implementation upon construction. This is passed through the constructor by the static factory method NativeWidget::CreateNativeWidget and by subclasses such as WindowWin, BubbleWidgetWin, etc.
Some classes that are constructed directly (e.g. LockWindow, in ChromeOS) never have a Widget created for them, so they create the Widget themselves in their base class initializer.
Code in these classes (and their WindowWin/WindowGtk, BrowserFrameWin, BrowserFrameGtk subclasses) must now call GetWidget() etc to call Widget API methods since they are no longer subclasses.
static_casting to this (and derived) types must now be done on the Widget's native_widget().
GetWindow() is renamed to GetContainingWindow() to avoid naming conflicts.
* Window ----
Window is now a subclass of Widget.
Now recognizes a supplied NativeWindow via InitParams. If this is specified then a default one is not created.
Window::CloseWindow becomes an override of Widget::Close.
CloseAllSecondaryWindows() becomes CloseAllSecondaryWidgets() and moves to widget.h
IsAppWindow() is removed and replaced by set_is_secondary_widget on Widget.
* MenuHost ----
Subclasses Widget now.
* TabContentsViewViews ----
It looks like the Gtk-views code here was still using the old implementation of the Native version of this class - i.e. a class that subclassed TabContentsView AND WidgetGtk. A no-no. I had to write NativeTabContentsViewGtk, which is almost identical to NativeTabContentsViewWin with the Gtk bits of TabContentsViewGtk thrown in.
* BrowserFrame ----
Platform-specific functionality is now restricted to BrowserFrameWin/BrowserFrameGtk behind a NativeBrowserFrame interface. Construction is exposed via a static factory method on NativeBrowserFrame.
BrowserFrame becomes a concrete class that now subclasses Window.
As a result, it no longer needs a GetWindow() accessor method, so people with a BrowserFrame* can just call Window methods directly on it.
It is constructed directly, replacing the BrowserFrame::Create() method.
NativeBrowserFrameDelegate is no longer needed.
BrowserFrameChromeos is simpler as a couple of #ifdefs in BrowserFrame, so I got rid of that too.
* AutocompletePopupWin/Gtk ----
No longer required. AutocompletePopupContentsView now just uses a Widget directly.
* There is some lingering ugliness:
- If you set a native_window field on Window::InitParams you must also manually set widget_init_params.native_widget. I will make InitParams do more of this automatically later.
- It'd be nice for the ContentsView to be specified via InitParams. I'll get to this later.
- NativeBrowserFrame could probably disappear as an interface. It only exists to provide a couple of methods that may be implemented in other ways.
- delete_on_destroy should now be an ownership directionality enum. I will do this later.
- Secondary-widgetness should somehow be inferred from transience. Later.
- set_focus_on_creation for both the NativeWidgets should probably move to Widget if it is really needed.
- WidgetWin/Gtk::SetInitialFocus seems like it could move to Widget.
- I need to clean up function order in some cases.
BUG=72040
TEST=none
Review URL: http://codereview.chromium.org/7012006
TBR=ben@chromium.org
Review URL: http://codereview.chromium.org/7011038
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@85283 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'views')
50 files changed, 715 insertions, 720 deletions
diff --git a/views/accessibility/native_view_accessibility_win.cc b/views/accessibility/native_view_accessibility_win.cc index 2bd8d30..26def37 100644 --- a/views/accessibility/native_view_accessibility_win.cc +++ b/views/accessibility/native_view_accessibility_win.cc @@ -259,7 +259,7 @@ STDMETHODIMP NativeViewAccessibilityWin::get_accChild(VARIANT var_child, } else { // Negative values are used for events fired using the view's WidgetWin views::WidgetWin* widget = - static_cast<views::WidgetWin*>(view_->GetWidget()->native_widget()); + static_cast<views::WidgetWin*>(view_->GetWidget()); child_view = widget->GetAccessibilityViewEventAt(child_id); } diff --git a/views/controls/combobox/native_combobox_views_unittest.cc b/views/controls/combobox/native_combobox_views_unittest.cc index dce36af..1d3bbeb 100644 --- a/views/controls/combobox/native_combobox_views_unittest.cc +++ b/views/controls/combobox/native_combobox_views_unittest.cc @@ -101,7 +101,7 @@ class NativeComboboxViewsTest : public ViewsTestBase { combobox_ = new TestCombobox(model_.get()); combobox_->SetID(1); - widget_ = new Widget; + widget_ = Widget::CreateWidget(); Widget::InitParams params(Widget::InitParams::TYPE_POPUP); params.bounds = gfx::Rect(100, 100, 100, 100); widget_->Init(params); diff --git a/views/controls/menu/menu_host.cc b/views/controls/menu/menu_host.cc index abebdce..1b0f3a6 100644 --- a/views/controls/menu/menu_host.cc +++ b/views/controls/menu/menu_host.cc @@ -31,7 +31,8 @@ void MenuHost::InitMenuHost(gfx::NativeWindow parent, const gfx::Rect& bounds, View* contents_view, bool do_capture) { - Widget::InitParams params(Widget::InitParams::TYPE_MENU); + Widget::InitParams params; + params.type = Widget::InitParams::TYPE_MENU; params.has_dropshadow = true; #if defined(OS_WIN) params.parent = parent; @@ -39,7 +40,6 @@ void MenuHost::InitMenuHost(gfx::NativeWindow parent, params.parent = GTK_WIDGET(parent); #endif params.bounds = bounds; - params.native_widget = native_menu_host_->AsNativeWidget(); GetWidget()->Init(params); GetWidget()->SetContentsView(contents_view); ShowMenuHost(do_capture); @@ -85,18 +85,6 @@ NativeWidget* MenuHost::GetNativeWidget() { } //////////////////////////////////////////////////////////////////////////////// -// MenuHost, Widget overrides: - - -RootView* MenuHost::CreateRootView() { - return new MenuHostRootView(GetWidget(), submenu_); -} - -bool MenuHost::ShouldReleaseCaptureOnMouseReleased() const { - return false; -} - -//////////////////////////////////////////////////////////////////////////////// // MenuHost, internal::NativeMenuHostDelegate implementation: void MenuHost::OnNativeMenuHostDestroy() { @@ -117,8 +105,12 @@ void MenuHost::OnNativeMenuHostCancelCapture() { menu_controller->CancelAll(); } -internal::NativeWidgetDelegate* MenuHost::AsNativeWidgetDelegate() { - return this; +RootView* MenuHost::CreateRootView() { + return new MenuHostRootView(GetWidget(), submenu_); +} + +bool MenuHost::ShouldReleaseCaptureOnMouseRelease() const { + return false; } } // namespace views diff --git a/views/controls/menu/menu_host.h b/views/controls/menu/menu_host.h index 0ebd1ac..41ecf8e 100644 --- a/views/controls/menu/menu_host.h +++ b/views/controls/menu/menu_host.h @@ -10,7 +10,6 @@ #include "ui/gfx/native_widget_types.h" #include "ui/gfx/rect.h" #include "views/controls/menu/native_menu_host_delegate.h" -#include "views/widget/widget.h" namespace views { @@ -29,8 +28,7 @@ class Widget; // OS destroys the widget out from under us, in which case |MenuHostDestroyed| // is invoked back on the SubmenuView and the SubmenuView then drops references // to the MenuHost. -class MenuHost : public Widget, - public internal::NativeMenuHostDelegate { +class MenuHost : public internal::NativeMenuHostDelegate { public: explicit MenuHost(SubmenuView* submenu); virtual ~MenuHost(); @@ -67,14 +65,11 @@ class MenuHost : public Widget, NativeWidget* GetNativeWidget(); private: - // Overridden from Widget: - virtual RootView* CreateRootView() OVERRIDE; - virtual bool ShouldReleaseCaptureOnMouseReleased() const OVERRIDE; - // Overridden from NativeMenuHostDelegate: virtual void OnNativeMenuHostDestroy() OVERRIDE; virtual void OnNativeMenuHostCancelCapture() OVERRIDE; - virtual internal::NativeWidgetDelegate* AsNativeWidgetDelegate() OVERRIDE; + virtual RootView* CreateRootView() OVERRIDE; + virtual bool ShouldReleaseCaptureOnMouseRelease() const OVERRIDE; NativeMenuHost* native_menu_host_; diff --git a/views/controls/menu/menu_host_gtk.cc b/views/controls/menu/menu_host_gtk.cc index 553bca3..201d17f 100644 --- a/views/controls/menu/menu_host_gtk.cc +++ b/views/controls/menu/menu_host_gtk.cc @@ -23,8 +23,7 @@ namespace views { // MenuHostGtk, public: MenuHostGtk::MenuHostGtk(internal::NativeMenuHostDelegate* delegate) - : WidgetGtk(delegate->AsNativeWidgetDelegate()), - did_input_grab_(false), + : did_input_grab_(false), delegate_(delegate) { } @@ -83,6 +82,7 @@ NativeWidget* MenuHostGtk::AsNativeWidget() { // MenuHostGtk, WidgetGtk overrides: void MenuHostGtk::InitNativeWidget(const Widget::InitParams& params) { + make_transient_to_parent(); WidgetGtk::InitNativeWidget(params); // Make sure we get destroyed when the parent is destroyed. gtk_window_set_destroy_with_parent(GTK_WINDOW(GetNativeView()), TRUE); @@ -90,6 +90,15 @@ void MenuHostGtk::InitNativeWidget(const Widget::InitParams& params) { GDK_WINDOW_TYPE_HINT_MENU); } +// TODO(beng): remove once MenuHost is-a Widget +RootView* MenuHostGtk::CreateRootView() { + return delegate_->CreateRootView(); +} + +bool MenuHostGtk::ShouldReleaseCaptureOnMouseReleased() const { + return delegate_->ShouldReleaseCaptureOnMouseRelease(); +} + void MenuHostGtk::ReleaseMouseCapture() { WidgetGtk::ReleaseMouseCapture(); if (did_input_grab_) { diff --git a/views/controls/menu/menu_host_gtk.h b/views/controls/menu/menu_host_gtk.h index ac1e588..d0378c3 100644 --- a/views/controls/menu/menu_host_gtk.h +++ b/views/controls/menu/menu_host_gtk.h @@ -29,6 +29,8 @@ class MenuHostGtk : public WidgetGtk, // Overridden from WidgetGtk: virtual void InitNativeWidget(const Widget::InitParams& params) OVERRIDE; + virtual RootView* CreateRootView() OVERRIDE; + virtual bool ShouldReleaseCaptureOnMouseReleased() const OVERRIDE; virtual void ReleaseMouseCapture() OVERRIDE; virtual void OnDestroy(GtkWidget* object) OVERRIDE; virtual void HandleGtkGrabBroke() OVERRIDE; @@ -37,7 +39,7 @@ class MenuHostGtk : public WidgetGtk, // Have we done input grab? bool did_input_grab_; - internal::NativeMenuHostDelegate* delegate_; + scoped_ptr<internal::NativeMenuHostDelegate> delegate_; DISALLOW_COPY_AND_ASSIGN(MenuHostGtk); }; diff --git a/views/controls/menu/menu_host_win.cc b/views/controls/menu/menu_host_win.cc index cba5595..5c2435d 100644 --- a/views/controls/menu/menu_host_win.cc +++ b/views/controls/menu/menu_host_win.cc @@ -12,8 +12,7 @@ namespace views { // MenuHostWin, public: MenuHostWin::MenuHostWin(internal::NativeMenuHostDelegate* delegate) - : WidgetWin(delegate->AsNativeWidgetDelegate()), - delegate_(delegate) { + : delegate_(delegate) { } MenuHostWin::~MenuHostWin() { @@ -43,6 +42,16 @@ void MenuHostWin::OnCancelMode() { WidgetWin::OnCancelMode(); } +// TODO(beng): remove once MenuHost is-a Widget +RootView* MenuHostWin::CreateRootView() { + return delegate_->CreateRootView(); +} + +// TODO(beng): remove once MenuHost is-a Widget +bool MenuHostWin::ShouldReleaseCaptureOnMouseReleased() const { + return delegate_->ShouldReleaseCaptureOnMouseRelease(); +} + //////////////////////////////////////////////////////////////////////////////// // NativeMenuHost, public: diff --git a/views/controls/menu/menu_host_win.h b/views/controls/menu/menu_host_win.h index 7dfc8e8..01a1419 100644 --- a/views/controls/menu/menu_host_win.h +++ b/views/controls/menu/menu_host_win.h @@ -29,8 +29,10 @@ class MenuHostWin : public WidgetWin, // Overridden from WidgetWin: virtual void OnDestroy() OVERRIDE; virtual void OnCancelMode() OVERRIDE; + virtual RootView* CreateRootView() OVERRIDE; + virtual bool ShouldReleaseCaptureOnMouseReleased() const OVERRIDE; - internal::NativeMenuHostDelegate* delegate_; + scoped_ptr<internal::NativeMenuHostDelegate> delegate_; DISALLOW_COPY_AND_ASSIGN(MenuHostWin); }; diff --git a/views/controls/menu/native_menu_host_delegate.h b/views/controls/menu/native_menu_host_delegate.h index 8baf714..e6d3de8 100644 --- a/views/controls/menu/native_menu_host_delegate.h +++ b/views/controls/menu/native_menu_host_delegate.h @@ -9,7 +9,6 @@ namespace views { class MenuHost; class RootView; namespace internal { -class NativeWidgetDelegate; class NativeMenuHostDelegate { public: @@ -21,7 +20,10 @@ class NativeMenuHostDelegate { // Called when the NativeMenuHost is losing input capture. virtual void OnNativeMenuHostCancelCapture() = 0; - virtual NativeWidgetDelegate* AsNativeWidgetDelegate() = 0; + // Pass-thrus for Widget overrides. + // TODO(beng): Remove once MenuHost is-a Widget. + virtual RootView* CreateRootView() = 0; + virtual bool ShouldReleaseCaptureOnMouseRelease() const = 0; }; } // namespace internal diff --git a/views/controls/native/native_view_host_gtk.cc b/views/controls/native/native_view_host_gtk.cc index 2bc0e50..d5e4110 100644 --- a/views/controls/native/native_view_host_gtk.cc +++ b/views/controls/native/native_view_host_gtk.cc @@ -323,7 +323,7 @@ void NativeViewHostGtk::DestroyFixed() { } WidgetGtk* NativeViewHostGtk::GetHostWidget() const { - return static_cast<WidgetGtk*>(host_->GetWidget()->native_widget()); + return static_cast<WidgetGtk*>(host_->GetWidget()); } GtkWidget* NativeViewHostGtk::GetFocusedDescendant() { diff --git a/views/controls/tabbed_pane/native_tabbed_pane_gtk.cc b/views/controls/tabbed_pane/native_tabbed_pane_gtk.cc index 2fbdbe9..123ece2 100644 --- a/views/controls/tabbed_pane/native_tabbed_pane_gtk.cc +++ b/views/controls/tabbed_pane/native_tabbed_pane_gtk.cc @@ -77,8 +77,8 @@ View* NativeTabbedPaneGtk::RemoveTabAtIndex(int index) { GtkWidget* page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(native_view()), index); - Widget* widget = - NativeWidget::GetNativeWidgetForNativeView(page)->GetWidget(); + WidgetGtk* widget = + static_cast<WidgetGtk*>(NativeWidget::GetNativeWidgetForNativeView(page)); // detach the content view from widget so that we can delete widget // without destroying the content view. @@ -154,7 +154,7 @@ void NativeTabbedPaneGtk::DoAddTabAtIndex(int index, int tab_count = GetTabCount(); DCHECK(index <= tab_count); - Widget* page_container = new Widget; + Widget* page_container = Widget::CreateWidget(); page_container->Init( Widget::InitParams(Widget::InitParams::TYPE_CONTROL)); page_container->SetContentsView(contents); @@ -195,18 +195,18 @@ void NativeTabbedPaneGtk::DoAddTabAtIndex(int index, GetRootView()->Layout(); } -Widget* NativeTabbedPaneGtk::GetWidgetAt(int index) { +WidgetGtk* NativeTabbedPaneGtk::GetWidgetAt(int index) { DCHECK(index <= GetTabCount()); GtkWidget* page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(native_view()), index); - Widget* widget = - NativeWidget::GetNativeWidgetForNativeView(page)->GetWidget(); + WidgetGtk* widget = + static_cast<WidgetGtk*>(NativeWidget::GetNativeWidgetForNativeView(page)); DCHECK(widget); return widget; } View* NativeTabbedPaneGtk::GetTabViewAt(int index) { - Widget* widget = GetWidgetAt(index); + WidgetGtk* widget = GetWidgetAt(index); DCHECK(widget && widget->GetRootView()->child_count() == 1); return widget->GetRootView()->GetChildViewAt(0); } diff --git a/views/controls/tabbed_pane/native_tabbed_pane_gtk.h b/views/controls/tabbed_pane/native_tabbed_pane_gtk.h index bbe412d..6b25032 100644 --- a/views/controls/tabbed_pane/native_tabbed_pane_gtk.h +++ b/views/controls/tabbed_pane/native_tabbed_pane_gtk.h @@ -49,8 +49,8 @@ class NativeTabbedPaneGtk : public NativeControlGtk, View* contents, bool select_if_first_tab); - // Returns the Widget containing the tab contents at |index|. - Widget* GetWidgetAt(int index); + // Returns the WidgetGtk containing the tab contents at |index|. + WidgetGtk* GetWidgetAt(int index); View* GetTabViewAt(int index); void OnSwitchPage(int selected_tab_index); diff --git a/views/controls/tabbed_pane/native_tabbed_pane_win.cc b/views/controls/tabbed_pane/native_tabbed_pane_win.cc index 1a025cb..0054de0 100644 --- a/views/controls/tabbed_pane/native_tabbed_pane_win.cc +++ b/views/controls/tabbed_pane/native_tabbed_pane_win.cc @@ -292,7 +292,7 @@ void NativeTabbedPaneWin::CreateNativeControl() { SendMessage(tab_control, WM_SETFONT, reinterpret_cast<WPARAM>(font), FALSE); // Create the view container which is a child of the TabControl. - content_window_ = new Widget; + content_window_ = Widget::CreateWidget(); Widget::InitParams params(Widget::InitParams::TYPE_CONTROL); params.parent = tab_control; content_window_->Init(params); diff --git a/views/controls/tabbed_pane/tabbed_pane_unittest.cc b/views/controls/tabbed_pane/tabbed_pane_unittest.cc index 1ceef86..1cd1621 100644 --- a/views/controls/tabbed_pane/tabbed_pane_unittest.cc +++ b/views/controls/tabbed_pane/tabbed_pane_unittest.cc @@ -44,7 +44,7 @@ class TabbedPaneTest : public testing::Test, WindowDelegate { } virtual void TearDown() { - window_->Close(); + window_->CloseWindow(); message_loop_.RunAllPending(); } diff --git a/views/controls/table/table_view_unittest.cc b/views/controls/table/table_view_unittest.cc index 8e05a07..c34fe79 100644 --- a/views/controls/table/table_view_unittest.cc +++ b/views/controls/table/table_view_unittest.cc @@ -196,7 +196,7 @@ void TableViewTest::SetUp() { } void TableViewTest::TearDown() { - window_->Close(); + window_->CloseWindow(); // Temporary workaround to avoid leak of RootView::pending_paint_task_. message_loop_.RunAllPending(); OleUninitialize(); @@ -518,7 +518,7 @@ void TableView2Test::SetUp() { } void TableView2Test::TearDown() { - window_->Close(); + window_->CloseWindow(); // Temporary workaround to avoid leak of RootView::pending_paint_task_. message_loop_.RunAllPending(); #if defined(OS_WIN) diff --git a/views/controls/textfield/native_textfield_gtk.cc b/views/controls/textfield/native_textfield_gtk.cc index 30444bb..dd0dc8f 100644 --- a/views/controls/textfield/native_textfield_gtk.cc +++ b/views/controls/textfield/native_textfield_gtk.cc @@ -393,7 +393,7 @@ void NativeTextfieldGtk::OnActivate(GtkWidget* native_widget) { if (controller) handled = controller->HandleKeyEvent(textfield_, views_key_event); - WidgetGtk* widget = static_cast<WidgetGtk*>(GetWidget()->native_widget()); + WidgetGtk* widget = static_cast<WidgetGtk*>(GetWidget()); if (!handled && widget) handled = widget->HandleKeyboardEvent(views_key_event); diff --git a/views/controls/textfield/native_textfield_views_unittest.cc b/views/controls/textfield/native_textfield_views_unittest.cc index 6a3da48..8456cf7 100644 --- a/views/controls/textfield/native_textfield_views_unittest.cc +++ b/views/controls/textfield/native_textfield_views_unittest.cc @@ -157,7 +157,7 @@ class NativeTextfieldViewsTest : public ViewsTestBase, ASSERT_FALSE(textfield_); textfield_ = new TestTextfield(style); textfield_->SetController(this); - widget_ = new Widget; + widget_ = Widget::CreateWidget(); Widget::InitParams params(Widget::InitParams::TYPE_POPUP); params.bounds = gfx::Rect(100, 100, 100, 100); widget_->Init(params); diff --git a/views/examples/widget_example.cc b/views/examples/widget_example.cc index daa8c66..4ec3cbf 100644 --- a/views/examples/widget_example.cc +++ b/views/examples/widget_example.cc @@ -29,7 +29,7 @@ class CenterLayout : public views::LayoutManager { } virtual gfx::Size GetPreferredSize(views::View* host) { - return gfx::Size(); + return host->GetPreferredSize(); } private: @@ -108,7 +108,7 @@ void WidgetExample::InitWidget(views::Widget* widget, bool transparent) { #if defined(OS_LINUX) void WidgetExample::CreateChild(views::View* parent, bool transparent) { - views::Widget* widget = new views::Widget; + views::Widget* widget = views::Widget::CreateWidget(); // Compute where to place the child widget. // We'll place it at the center of the root widget. views::Widget* parent_widget = parent->GetWidget(); @@ -126,7 +126,7 @@ void WidgetExample::CreateChild(views::View* parent, bool transparent) { #endif void WidgetExample::CreatePopup(views::View* parent, bool transparent) { - views::Widget* widget = new views::Widget; + views::Widget* widget = views::Widget::CreateWidget(); // Compute where to place the popup widget. // We'll place it right below the create button. diff --git a/views/focus/accelerator_handler_gtk_unittest.cc b/views/focus/accelerator_handler_gtk_unittest.cc index bfe53a9..031226b 100644 --- a/views/focus/accelerator_handler_gtk_unittest.cc +++ b/views/focus/accelerator_handler_gtk_unittest.cc @@ -28,7 +28,8 @@ class AcceleratorHandlerGtkTest window_ = Window::CreateChromeWindow( NULL, gfx::Rect(0, 0, 500, 500), this); window_->Show(); - FocusManager* focus_manager = window_->GetFocusManager(); + FocusManager* focus_manager = static_cast<WindowGtk*>(window_)-> + GetFocusManager(); focus_manager->RegisterAccelerator(kMenuAccelerator, this); focus_manager->RegisterAccelerator(kHomepageAccelerator, this); menu_pressed_ = false; @@ -36,7 +37,7 @@ class AcceleratorHandlerGtkTest } virtual void TearDown() { - window_->Close(); + window_->CloseWindow(); // Flush the message loop to make Purify happy. message_loop_.RunAllPending(); diff --git a/views/focus/focus_manager_gtk.cc b/views/focus/focus_manager_gtk.cc index 29af1ef..327c785 100644 --- a/views/focus/focus_manager_gtk.cc +++ b/views/focus/focus_manager_gtk.cc @@ -13,7 +13,7 @@ namespace views { void FocusManager::ClearNativeFocus() { - static_cast<WidgetGtk*>(widget_->native_widget())->ClearNativeFocus(); + static_cast<WidgetGtk*>(widget_)->ClearNativeFocus(); } void FocusManager::FocusNativeView(gfx::NativeView native_view) { diff --git a/views/focus/focus_manager_unittest.cc b/views/focus/focus_manager_unittest.cc index 6f34241..2661e67 100644 --- a/views/focus/focus_manager_unittest.cc +++ b/views/focus/focus_manager_unittest.cc @@ -130,14 +130,20 @@ class FocusManagerTest : public testing::Test, public WindowDelegate { virtual void TearDown() { if (focus_change_listener_) GetFocusManager()->RemoveFocusChangeListener(focus_change_listener_); - window_->Close(); + window_->CloseWindow(); // Flush the message loop to make Purify happy. message_loop()->RunAllPending(); } FocusManager* GetFocusManager() { - return window_->GetFocusManager(); +#if defined(OS_WIN) + return static_cast<WindowWin*>(window_)->GetFocusManager(); +#elif defined(OS_LINUX) + return static_cast<WindowGtk*>(window_)->GetFocusManager(); +#else + NOTIMPLEMENTED(); +#endif } void FocusNativeView(gfx::NativeView native_view) { @@ -284,7 +290,7 @@ class BorderView : public NativeViewHost { if (child == this && is_add) { if (!widget_) { - widget_ = new Widget; + widget_ = Widget::CreateWidget(); Widget::InitParams params(Widget::InitParams::TYPE_CONTROL); #if defined(OS_WIN) params.parent = parent->GetRootView()->GetWidget()->GetNativeView(); @@ -1596,7 +1602,7 @@ TEST_F(FocusManagerTest, CreationForNativeRoot) { ASSERT_TRUE(hwnd); // Create a view window parented to native dialog. - scoped_ptr<Widget> widget1(new Widget); + scoped_ptr<Widget> widget1(Widget::CreateWidget()); Widget::InitParams params(Widget::InitParams::TYPE_CONTROL); params.delete_on_destroy = false; params.parent = hwnd; @@ -1609,7 +1615,7 @@ TEST_F(FocusManagerTest, CreationForNativeRoot) { EXPECT_TRUE(focus_manager_member1); // Create another view window parented to the first view window. - scoped_ptr<Widget> widget2(new Widget); + scoped_ptr<Widget> widget2(Widget::CreateWidget()); params.parent = widget1->GetNativeView(); widget2->Init(params); @@ -1636,6 +1642,7 @@ TEST_F(FocusManagerTest, CreationForNativeRoot) { } #endif +#if defined(OS_CHROMEOS) class FocusManagerDtorTest : public FocusManagerTest { protected: typedef std::vector<std::string> DtorTrackVector; @@ -1668,19 +1675,20 @@ class FocusManagerDtorTest : public FocusManagerTest { DtorTrackVector* dtor_tracker_; }; - class WindowDtorTracked : public Window { + class WindowGtkDtorTracked : public WindowGtk { public: - WindowDtorTracked(WindowDelegate* window_delegate, - DtorTrackVector* dtor_tracker) + WindowGtkDtorTracked(WindowDelegate* window_delegate, + DtorTrackVector* dtor_tracker) : dtor_tracker_(dtor_tracker) { - tracked_focus_manager_ = new FocusManagerDtorTracked(this, dtor_tracker_); + tracked_focus_manager_ = new FocusManagerDtorTracked(this, + dtor_tracker_); Window::InitParams params(window_delegate); params.widget_init_params.bounds = gfx::Rect(0, 0, 100, 100); - InitWindow(params); + GetWindow()->InitWindow(params); ReplaceFocusManager(tracked_focus_manager_); } - virtual ~WindowDtorTracked() { + virtual ~WindowGtkDtorTracked() { dtor_tracker_->push_back("WindowGtkDtorTracked"); } @@ -1690,16 +1698,17 @@ class FocusManagerDtorTest : public FocusManagerTest { public: virtual void SetUp() { - // Create WindowGtkDtorTracked that uses FocusManagerDtorTracked. - window_ = new WindowDtorTracked(this, &dtor_tracker_); - ASSERT_TRUE(GetFocusManager() == static_cast<WindowDtorTracked*>( - window_)->tracked_focus_manager_); - window_->Show(); + // Create WindowGtkDtorTracked that uses FocusManagerDtorTracked. + window_ = new WindowGtkDtorTracked(this, &dtor_tracker_); + ASSERT_TRUE(GetFocusManager() == + static_cast<WindowGtkDtorTracked*>(window_)->tracked_focus_manager_); + + window_->Show(); } virtual void TearDown() { if (window_) { - window_->Close(); + window_->CloseWindow(); message_loop()->RunAllPending(); } } @@ -1717,7 +1726,7 @@ TEST_F(FocusManagerDtorTest, FocusManagerDestructedLast) { tabbed_pane->AddTab(L"Awesome tab", button); // Close the window. - window_->Close(); + window_->CloseWindow(); message_loop()->RunAllPending(); // Test window, button and focus manager should all be destructed. @@ -1730,5 +1739,6 @@ TEST_F(FocusManagerDtorTest, FocusManagerDestructedLast) { window_ = NULL; } +#endif // defined(OS_CHROMEOS) } // namespace views diff --git a/views/focus/view_storage.cc b/views/focus/view_storage.cc index 053eb71b..1852044 100644 --- a/views/focus/view_storage.cc +++ b/views/focus/view_storage.cc @@ -62,7 +62,7 @@ void ViewStorage::RemoveView(int storage_id) { EraseView(storage_id, false); } -void ViewStorage::ViewRemoved(View* removed) { +void ViewStorage::ViewRemoved(View* parent, View* removed) { // Let's first retrieve the ids for that view. std::map<View*, std::vector<int>*>::iterator ids_iter = view_to_ids_.find(removed); diff --git a/views/focus/view_storage.h b/views/focus/view_storage.h index 129b90e..8673e59 100644 --- a/views/focus/view_storage.h +++ b/views/focus/view_storage.h @@ -39,7 +39,7 @@ class ViewStorage { void RemoveView(int storage_id); // Notifies the ViewStorage that a view was removed from its parent somewhere. - void ViewRemoved(View* removed); + void ViewRemoved(View* parent, View* removed); #ifdef UNIT_TEST size_t view_count() const { return view_to_ids_.size(); } diff --git a/views/view.cc b/views/view.cc index 820800a..52234d7 100644 --- a/views/view.cc +++ b/views/view.cc @@ -217,7 +217,7 @@ int View::GetIndexOf(const View* view) const { // TODO(beng): remove const Window* View::GetWindow() const { const Widget* widget = GetWidget(); - return widget ? widget->GetContainingWindow() : NULL; + return widget ? widget->GetWindow() : NULL; } // TODO(beng): remove diff --git a/views/view_unittest.cc b/views/view_unittest.cc index 72ae85b..039c534 100644 --- a/views/view_unittest.cc +++ b/views/view_unittest.cc @@ -41,8 +41,9 @@ #endif using ::testing::_; +using namespace views; -namespace views { +namespace { class ViewTest : public ViewsTestBase { public: @@ -53,6 +54,69 @@ class ViewTest : public ViewsTestBase { } }; +/* + +// Paints the RootView. +void PaintRootView(views::RootView* root, bool empty_paint) { + if (!empty_paint) { + root->PaintNow(); + } else { + // User isn't logged in, so that PaintNow will generate an empty rectangle. + // Invoke paint directly. + gfx::Rect paint_rect = root->GetScheduledPaintRect(); + gfx::CanvasSkia canvas(paint_rect.width(), paint_rect.height(), true); + canvas.TranslateInt(-paint_rect.x(), -paint_rect.y()); + canvas.ClipRectInt(0, 0, paint_rect.width(), paint_rect.height()); + root->Paint(&canvas); + } +} + +typedef CWinTraits<WS_VISIBLE|WS_CLIPCHILDREN|WS_CLIPSIBLINGS> CVTWTraits; + +// A trivial window implementation that tracks whether or not it has been +// painted. This is used by the painting test to determine if paint will result +// in an empty region. +class EmptyWindow : public CWindowImpl<EmptyWindow, + CWindow, + CVTWTraits> { + public: + DECLARE_FRAME_WND_CLASS(L"Chrome_ChromeViewsEmptyWindow", 0) + + BEGIN_MSG_MAP_EX(EmptyWindow) + MSG_WM_PAINT(OnPaint) + END_MSG_MAP() + + EmptyWindow::EmptyWindow(const CRect& bounds) : empty_paint_(false) { + Create(NULL, static_cast<RECT>(bounds)); + ShowWindow(SW_SHOW); + } + + EmptyWindow::~EmptyWindow() { + ShowWindow(SW_HIDE); + DestroyWindow(); + } + + void EmptyWindow::OnPaint(HDC dc) { + PAINTSTRUCT ps; + HDC paint_dc = BeginPaint(&ps); + if (!empty_paint_ && (ps.rcPaint.top - ps.rcPaint.bottom) == 0 && + (ps.rcPaint.right - ps.rcPaint.left) == 0) { + empty_paint_ = true; + } + EndPaint(&ps); + } + + bool empty_paint() { + return empty_paint_; + } + + private: + bool empty_paint_; + + DISALLOW_COPY_AND_ASSIGN(EmptyWindow); +}; +*/ + //////////////////////////////////////////////////////////////////////////////// // // A view subclass for testing purpose @@ -201,6 +265,8 @@ void TestView::ViewHierarchyChanged(bool is_add, View *parent, View *child) { child_ = child; } +} // namespace + TEST_F(ViewTest, AddRemoveNotifications) { TestView* v1 = new TestView(); v1->SetBounds(0, 0, 300, 300); @@ -295,7 +361,7 @@ TEST_F(ViewTest, MouseEvent) { TestView* v2 = new TestView(); v2->SetBounds(100, 100, 100, 100); - scoped_ptr<Widget> widget(new Widget); + scoped_ptr<Widget> widget(Widget::CreateWidget()); Widget::InitParams params(Widget::InitParams::TYPE_WINDOW); params.delete_on_destroy = false; params.bounds = gfx::Rect(50, 50, 650, 650); @@ -535,7 +601,7 @@ TEST_F(ViewTest, DISABLED_Painting) { RDW_UPDATENOW | RDW_INVALIDATE | RDW_ALLCHILDREN); bool empty_paint = paint_window.empty_paint(); - WidgetWin window; + views::WidgetWin window; window.set_delete_on_destroy(false); window.set_window_style(WS_OVERLAPPEDWINDOW); window.Init(NULL, gfx::Rect(50, 50, 650, 650), NULL); @@ -596,17 +662,10 @@ TEST_F(ViewTest, DISABLED_Painting) { } */ -#if defined(OS_WIN) TEST_F(ViewTest, RemoveNotification) { -#elif defined(TOOLKIT_USES_GTK) -// TODO(beng): stopped working with widget hierarchy split, -// http://crbug.com/82364 -TEST_F(ViewTest, DISABLED_RemoveNotification) { -#endif - ViewStorage* vs = ViewStorage::GetInstance(); - Widget* widget = new Widget; - widget->Init(Widget::InitParams(Widget::InitParams::TYPE_WINDOW)); - RootView* root_view = widget->GetRootView(); + views::ViewStorage* vs = views::ViewStorage::GetInstance(); + views::Widget* widget = Widget::CreateWidget(); + views::RootView* root_view = widget->GetRootView(); View* v1 = new View; int s1 = vs->CreateStorageID(); @@ -667,6 +726,7 @@ TEST_F(ViewTest, DISABLED_RemoveNotification) { // Now remove even more. root_view->RemoveChildView(v1); + EXPECT_EQ(stored_views - 8, vs->view_count()); EXPECT_EQ(NULL, vs->RetrieveView(s1)); EXPECT_EQ(NULL, vs->RetrieveView(s11)); EXPECT_EQ(NULL, vs->RetrieveView(s12)); @@ -677,9 +737,9 @@ TEST_F(ViewTest, DISABLED_RemoveNotification) { root_view->AddChildView(v1); vs->StoreView(s1, v1); - // Synchronously closing the window deletes the view hierarchy, which should - // remove all its views from ViewStorage. - widget->CloseNow(); + // Now delete the root view (deleting the window will trigger a delete of the + // RootView) and make sure we are notified that the views were removed. + delete widget; EXPECT_EQ(stored_views - 10, vs->view_count()); EXPECT_EQ(NULL, vs->RetrieveView(s1)); EXPECT_EQ(NULL, vs->RetrieveView(s12)); @@ -691,7 +751,7 @@ TEST_F(ViewTest, DISABLED_RemoveNotification) { } namespace { -class HitTestView : public View { +class HitTestView : public views::View { public: explicit HitTestView(bool has_hittest_mask) : has_hittest_mask_(has_hittest_mask) { @@ -699,7 +759,7 @@ class HitTestView : public View { virtual ~HitTestView() {} protected: - // Overridden from View: + // Overridden from views::View: virtual bool HasHitTestMask() const { return has_hittest_mask_; } @@ -723,17 +783,16 @@ class HitTestView : public View { DISALLOW_COPY_AND_ASSIGN(HitTestView); }; -gfx::Point ConvertPointToView(View* view, const gfx::Point& p) { +gfx::Point ConvertPointToView(views::View* view, const gfx::Point& p) { gfx::Point tmp(p); - View::ConvertPointToView(view->GetRootView(), view, &tmp); + views::View::ConvertPointToView(view->GetRootView(), view, &tmp); return tmp; } } TEST_F(ViewTest, HitTestMasks) { - Widget* widget = new Widget; - widget->Init(Widget::InitParams(Widget::InitParams::TYPE_WINDOW)); - RootView* root_view = widget->GetRootView(); + scoped_ptr<views::Widget> widget(Widget::CreateWidget()); + views::RootView* root_view = widget->GetRootView(); root_view->SetBounds(0, 0, 500, 500); gfx::Rect v1_bounds = gfx::Rect(0, 0, 100, 100); @@ -763,8 +822,6 @@ TEST_F(ViewTest, HitTestMasks) { EXPECT_EQ(v2, root_view->GetEventHandlerForPoint(v2_centerpoint)); EXPECT_EQ(v1, root_view->GetEventHandlerForPoint(v1_origin)); EXPECT_EQ(root_view, root_view->GetEventHandlerForPoint(v2_origin)); - - widget->CloseNow(); } TEST_F(ViewTest, Textfield) { @@ -775,7 +832,7 @@ TEST_F(ViewTest, Textfield) { ui::Clipboard clipboard; - Widget* widget = new Widget; + Widget* widget = Widget::CreateWidget(); Widget::InitParams params(Widget::InitParams::TYPE_WINDOW); params.bounds = gfx::Rect(0, 0, 100, 100); widget->Init(params); @@ -799,8 +856,6 @@ TEST_F(ViewTest, Textfield) { EXPECT_EQ(kText, textfield->text()); textfield->ClearSelection(); EXPECT_EQ(kEmptyString, textfield->GetSelectedText()); - - widget->CloseNow(); } #if defined(OS_WIN) @@ -813,7 +868,7 @@ TEST_F(ViewTest, TextfieldCutCopyPaste) { ui::Clipboard clipboard; - Widget* widget = new Widget; + Widget* widget = Widget::CreateWidget(); Widget::InitParams params(Widget::InitParams::TYPE_WINDOW); params.bounds = gfx::Rect(0, 0, 100, 100); widget->Init(params); @@ -913,7 +968,6 @@ TEST_F(ViewTest, TextfieldCutCopyPaste) { ::SendMessage(normal->GetTestingHandle(), WM_PASTE, 0, 0); ::GetWindowText(normal->GetTestingHandle(), buffer, 1024); EXPECT_EQ(kReadOnlyText, std::wstring(buffer)); - widget->CloseNow(); } #endif @@ -928,14 +982,14 @@ bool TestView::AcceleratorPressed(const Accelerator& accelerator) { #if defined(OS_WIN) TEST_F(ViewTest, ActivateAccelerator) { // Register a keyboard accelerator before the view is added to a window. - Accelerator return_accelerator(ui::VKEY_RETURN, false, false, false); + views::Accelerator return_accelerator(ui::VKEY_RETURN, false, false, false); TestView* view = new TestView(); view->Reset(); view->AddAccelerator(return_accelerator); EXPECT_EQ(view->accelerator_count_map_[return_accelerator], 0); // Create a window and add the view as its child. - scoped_ptr<Widget> widget(new Widget); + scoped_ptr<Widget> widget(Widget::CreateWidget()); Widget::InitParams params(Widget::InitParams::TYPE_WINDOW); params.delete_on_destroy = false; params.bounds = gfx::Rect(0, 0, 100, 100); @@ -944,8 +998,9 @@ TEST_F(ViewTest, ActivateAccelerator) { root->AddChildView(view); // Get the focus manager. - FocusManager* focus_manager = FocusManager::GetFocusManagerForNativeView( - widget->GetNativeView()); + views::FocusManager* focus_manager = + views::FocusManager::GetFocusManagerForNativeView( + widget->GetNativeView()); ASSERT_TRUE(focus_manager); // Hit the return key and see if it takes effect. @@ -953,7 +1008,7 @@ TEST_F(ViewTest, ActivateAccelerator) { EXPECT_EQ(view->accelerator_count_map_[return_accelerator], 1); // Hit the escape key. Nothing should happen. - Accelerator escape_accelerator(ui::VKEY_ESCAPE, false, false, false); + views::Accelerator escape_accelerator(ui::VKEY_ESCAPE, false, false, false); EXPECT_FALSE(focus_manager->ProcessAccelerator(escape_accelerator)); EXPECT_EQ(view->accelerator_count_map_[return_accelerator], 1); EXPECT_EQ(view->accelerator_count_map_[escape_accelerator], 0); @@ -994,13 +1049,13 @@ TEST_F(ViewTest, ActivateAccelerator) { #if defined(OS_WIN) TEST_F(ViewTest, HiddenViewWithAccelerator) { - Accelerator return_accelerator(ui::VKEY_RETURN, false, false, false); + views::Accelerator return_accelerator(ui::VKEY_RETURN, false, false, false); TestView* view = new TestView(); view->Reset(); view->AddAccelerator(return_accelerator); EXPECT_EQ(view->accelerator_count_map_[return_accelerator], 0); - scoped_ptr<Widget> widget(new Widget); + scoped_ptr<Widget> widget(Widget::CreateWidget()); Widget::InitParams params(Widget::InitParams::TYPE_WINDOW); params.delete_on_destroy = false; params.bounds = gfx::Rect(0, 0, 100, 100); @@ -1008,8 +1063,9 @@ TEST_F(ViewTest, HiddenViewWithAccelerator) { RootView* root = widget->GetRootView(); root->AddChildView(view); - FocusManager* focus_manager = FocusManager::GetFocusManagerForNativeView( - widget->GetNativeView()); + views::FocusManager* focus_manager = + views::FocusManager::GetFocusManagerForNativeView( + widget->GetNativeView()); ASSERT_TRUE(focus_manager); view->SetVisible(false); @@ -1101,15 +1157,16 @@ class SimpleWindowDelegate : public WindowDelegate { // area that it opens the test windows. --beng TEST_F(ViewTest, DISABLED_RerouteMouseWheelTest) { TestViewWithControls* view_with_controls = new TestViewWithControls(); - Window* window1 = Window::CreateChromeWindow( - NULL, gfx::Rect(0, 0, 100, 100), - new SimpleWindowDelegate(view_with_controls)); + views::Window* window1 = + views::Window::CreateChromeWindow( + NULL, gfx::Rect(0, 0, 100, 100), + new SimpleWindowDelegate(view_with_controls)); window1->Show(); ScrollView* scroll_view = new ScrollView(); scroll_view->SetContents(new ScrollableTestView()); - Window* window2 = Window::CreateChromeWindow( - NULL, gfx::Rect(200, 200, 100, 100), - new SimpleWindowDelegate(scroll_view)); + views::Window* window2 = + views::Window::CreateChromeWindow(NULL, gfx::Rect(200, 200, 100, 100), + new SimpleWindowDelegate(scroll_view)); window2->Show(); EXPECT_EQ(0, scroll_view->GetVisibleRect().y()); @@ -1144,9 +1201,6 @@ TEST_F(ViewTest, DISABLED_RerouteMouseWheelTest) { ::SendMessage(view_with_controls->text_field_->GetTestingHandle(), WM_MOUSEWHEEL, MAKEWPARAM(0, -20), MAKELPARAM(50, 50)); EXPECT_EQ(80, scroll_view->GetVisibleRect().y()); - - window1->CloseNow(); - window2->CloseNow(); } #endif @@ -1154,7 +1208,8 @@ TEST_F(ViewTest, DISABLED_RerouteMouseWheelTest) { // Dialogs' default button //////////////////////////////////////////////////////////////////////////////// -class MockMenuModel : public ui::MenuModel { +namespace ui { +class MockMenuModel : public MenuModel { public: MOCK_CONST_METHOD0(HasIcons, bool()); MOCK_CONST_METHOD1(GetFirstItemIndex, int(gfx::NativeMenu native_menu)); @@ -1169,7 +1224,7 @@ class MockMenuModel : public ui::MenuModel { MOCK_CONST_METHOD1(IsItemCheckedAt, bool(int index)); MOCK_CONST_METHOD1(GetGroupIdAt, int(int index)); MOCK_METHOD2(GetIconAt, bool(int index, SkBitmap* icon)); - MOCK_CONST_METHOD1(GetButtonMenuItemAt, ui::ButtonMenuItemModel*(int index)); + MOCK_CONST_METHOD1(GetButtonMenuItemAt, ButtonMenuItemModel*(int index)); MOCK_CONST_METHOD1(IsEnabledAt, bool(int index)); MOCK_CONST_METHOD1(IsVisibleAt, bool(int index)); MOCK_CONST_METHOD1(GetSubmenuModelAt, MenuModel*(int index)); @@ -1179,14 +1234,15 @@ class MockMenuModel : public ui::MenuModel { int disposition)); MOCK_METHOD0(MenuWillShow, void()); MOCK_METHOD0(MenuClosed, void()); - MOCK_METHOD1(SetMenuModelDelegate, void(ui::MenuModelDelegate* delegate)); + MOCK_METHOD1(SetMenuModelDelegate, void(MenuModelDelegate* delegate)); MOCK_METHOD3(GetModelAndIndexForCommandId, bool(int command_id, MenuModel** model, int* index)); }; +} class TestDialog : public DialogDelegate, public ButtonListener { public: - explicit TestDialog(MockMenuModel* mock_menu_model) + explicit TestDialog(ui::MockMenuModel* mock_menu_model) : contents_(NULL), button1_(NULL), button2_(NULL), @@ -1198,7 +1254,7 @@ class TestDialog : public DialogDelegate, public ButtonListener { oked_(false) { } - // DialogDelegate implementation: + // views::DialogDelegate implementation: virtual int GetDefaultDialogButton() const { return MessageBoxFlags::DIALOGBUTTON_OK; } @@ -1229,8 +1285,8 @@ class TestDialog : public DialogDelegate, public ButtonListener { return false; } - // ButtonListener implementation. - virtual void ButtonPressed(Button* sender, const Event& event) { + // views::ButtonListener implementation. + virtual void ButtonPressed(Button* sender, const views::Event& event) { last_pressed_button_ = sender; } @@ -1257,7 +1313,7 @@ class TestDialog : public DialogDelegate, public ButtonListener { NativeButtonBase* checkbox_; ButtonDropDown* button_drop_; Button* last_pressed_button_; - MockMenuModel* mock_menu_model_; + ui::MockMenuModel* mock_menu_model_; bool canceled_; bool oked_; @@ -1282,13 +1338,14 @@ class DefaultButtonTest : public ViewTest { virtual void SetUp() { test_dialog_ = new TestDialog(NULL); - Window* window = Window::CreateChromeWindow(NULL, gfx::Rect(0, 0, 100, 100), - test_dialog_); + views::Window* window = + views::Window::CreateChromeWindow(NULL, gfx::Rect(0, 0, 100, 100), + test_dialog_); window->Show(); focus_manager_ = test_dialog_->contents_->GetFocusManager(); ASSERT_TRUE(focus_manager_ != NULL); client_view_ = - static_cast<DialogClientView*>(window->client_view()); + static_cast<views::DialogClientView*>(window->client_view()); ok_button_ = client_view_->ok_button(); cancel_button_ = client_view_->cancel_button(); } @@ -1323,11 +1380,11 @@ class DefaultButtonTest : public ViewTest { test_dialog_->ResetStates(); } - FocusManager* focus_manager_; + views::FocusManager* focus_manager_; TestDialog* test_dialog_; DialogClientView* client_view_; - NativeButton* ok_button_; - NativeButton* cancel_button_; + views::NativeButton* ok_button_; + views::NativeButton* cancel_button_; }; TEST_F(DefaultButtonTest, DialogDefaultButtonTest) { @@ -1386,8 +1443,9 @@ class ButtonDropDownTest : public ViewTest { virtual void SetUp() { test_dialog_ = new TestDialog(&mock_menu_model_); - Window* window = Window::CreateChromeWindow(NULL, gfx::Rect(0, 0, 100, 100), - test_dialog_); + views::Window* window = + views::Window::CreateChromeWindow(NULL, gfx::Rect(0, 0, 100, 100), + test_dialog_); window->Show(); test_dialog_->button_drop_->SetBounds(0, 0, 100, 100); // We have to cast the button back into a View in order to invoke it's @@ -1396,7 +1454,7 @@ class ButtonDropDownTest : public ViewTest { } TestDialog* test_dialog_; - MockMenuModel mock_menu_model_; + ui::MockMenuModel mock_menu_model_; // This is owned by test_dialog_. View* button_as_view_; @@ -1441,9 +1499,9 @@ TEST_F(ViewTest, ChangeVisibility) { // TODO(oshima): we probably should enable this for entire tests on linux. g_log_set_always_fatal(G_LOG_LEVEL_CRITICAL); #endif - scoped_ptr<Widget> window(CreateWidget()); + scoped_ptr<views::Widget> window(CreateWidget()); window->Init(NULL, gfx::Rect(0, 0, 500, 300)); - RootView* root_view = window->GetRootView(); + views::RootView* root_view = window->GetRootView(); NativeButtonBase* native = new NativeButtonBase(NULL, L"Native"); root_view->SetContentsView(native); @@ -1462,7 +1520,7 @@ TEST_F(ViewTest, ChangeVisibility) { //////////////////////////////////////////////////////////////////////////////// // Native view hierachy //////////////////////////////////////////////////////////////////////////////// -class TestNativeViewHierarchy : public View { +class TestNativeViewHierarchy : public views::View { public: TestNativeViewHierarchy() { } @@ -1489,14 +1547,14 @@ class TestChangeNativeViewHierarchy { public: explicit TestChangeNativeViewHierarchy(ViewTest *view_test) { view_test_ = view_test; - native_host_ = new NativeViewHost(); - host_ = new Widget; + native_host_ = new views::NativeViewHost(); + host_ = Widget::CreateWidget(); Widget::InitParams params(Widget::InitParams::TYPE_WINDOW); params.bounds = gfx::Rect(0, 0, 500, 300); host_->Init(params); host_->GetRootView()->AddChildView(native_host_); for (size_t i = 0; i < TestNativeViewHierarchy::kTotalViews; ++i) { - windows_[i] = new Widget; + windows_[i] = Widget::CreateWidget(); Widget::InitParams params(Widget::InitParams::TYPE_WINDOW); params.parent = host_->GetNativeView(); params.bounds = gfx::Rect(0, 0, 500, 300); @@ -1517,7 +1575,7 @@ class TestChangeNativeViewHierarchy { } void CheckEnumeratingNativeWidgets() { - if (!host_->GetContainingWindow()) + if (!host_->GetWindow()) return; NativeWidget::NativeWidgets widgets; NativeWidget::GetAllNativeWidgets(host_->GetNativeView(), &widgets); @@ -1563,10 +1621,10 @@ class TestChangeNativeViewHierarchy { } } - NativeViewHost* native_host_; - Widget* host_; - Widget* windows_[TestNativeViewHierarchy::kTotalViews]; - RootView* root_views_[TestNativeViewHierarchy::kTotalViews]; + views::NativeViewHost* native_host_; + views::Widget* host_; + views::Widget* windows_[TestNativeViewHierarchy::kTotalViews]; + views::RootView* root_views_[TestNativeViewHierarchy::kTotalViews]; TestNativeViewHierarchy* test_views_[TestNativeViewHierarchy::kTotalViews]; ViewTest* view_test_; }; @@ -1621,7 +1679,7 @@ TEST_F(ViewTest, TransformPaint) { TestView* v2 = new TestView(); v2->SetBounds(100, 100, 200, 100); - Widget* widget = new Widget; + Widget* widget = Widget::CreateWidget(); Widget::InitParams params(Widget::InitParams::TYPE_WINDOW); params.bounds = gfx::Rect(50, 50, 650, 650); widget->Init(params); @@ -1658,7 +1716,7 @@ TEST_F(ViewTest, TransformEvent) { TestView* v2 = new TestView(); v2->SetBounds(100, 100, 200, 100); - Widget* widget = new Widget; + Widget* widget = Widget::CreateWidget(); Widget::InitParams params(Widget::InitParams::TYPE_WINDOW); params.bounds = gfx::Rect(50, 50, 650, 650); widget->Init(params); @@ -1808,7 +1866,7 @@ class VisibleBoundsView : public View { TEST_F(ViewTest, OnVisibleBoundsChanged) { gfx::Rect viewport_bounds(0, 0, 100, 100); - scoped_ptr<Widget> widget(new Widget); + scoped_ptr<Widget> widget(Widget::CreateWidget()); Widget::InitParams params(Widget::InitParams::TYPE_WINDOW); params.delete_on_destroy = false; params.bounds = viewport_bounds; @@ -1874,5 +1932,3 @@ TEST_F(ViewTest, SetBoundsPaint) { top_view->scheduled_paint_rects_[1]); EXPECT_EQ(gfx::Rect(10, 10, 40, 40), paint_rect); } - -} // namespace views diff --git a/views/widget/drop_target_gtk.cc b/views/widget/drop_target_gtk.cc index c135d91..5025ae4 100644 --- a/views/widget/drop_target_gtk.cc +++ b/views/widget/drop_target_gtk.cc @@ -167,7 +167,7 @@ gboolean DropTargetGtk::OnDragDrop(GdkDragContext* context, if (!pending_view_) { // User isn't over a view, no drop can occur. static_cast<WidgetGtk*>( - helper_.root_view()->GetWidget()->native_widget())->ResetDropTarget(); + helper_.root_view()->GetWidget())->ResetDropTarget(); // WARNING: we've been deleted. return FALSE; } @@ -246,8 +246,7 @@ void DropTargetGtk::FinishDrop(GdkDragContext* context, gtk_drag_finish(context, gdk_action != 0, (gdk_action & GDK_ACTION_MOVE), time); - static_cast<WidgetGtk*>(helper_.root_view()->GetWidget()->native_widget())-> - ResetDropTarget(); + static_cast<WidgetGtk*>(helper_.root_view()->GetWidget())->ResetDropTarget(); // WARNING: we've been deleted. } @@ -265,8 +264,9 @@ void DropTargetGtk::RequestFormats(GdkDragContext* context, int formats, const std::set<GdkAtom>& custom_formats, guint time) { - GtkWidget* widget = static_cast<WidgetGtk*>(helper_.root_view()->GetWidget()-> - native_widget())->window_contents(); + GtkWidget* widget = + static_cast<WidgetGtk*>(helper_.root_view()->GetWidget())-> + window_contents(); const std::set<GdkAtom>& known_formats = data_provider().known_custom_formats(); diff --git a/views/widget/native_widget.h b/views/widget/native_widget.h index c672044..451a0e9 100644 --- a/views/widget/native_widget.h +++ b/views/widget/native_widget.h @@ -36,11 +36,6 @@ class NativeWidget { virtual ~NativeWidget() {} - // Creates an appropriate default NativeWidget implementation for the current - // OS/circumstance. - static NativeWidget* CreateNativeWidget( - internal::NativeWidgetDelegate* delegate); - // Retrieves the NativeWidget implementation associated with the given // NativeView or Window, or NULL if the supplied handle has no associated // NativeView. @@ -69,19 +64,6 @@ class NativeWidget { // 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; - virtual const Widget* GetWidget() const = 0; - - // Returns the NativeView/Window associated with this NativeWidget. - virtual gfx::NativeView GetNativeView() const = 0; - virtual gfx::NativeWindow GetNativeWindow() const = 0; - - // Returns the enclosing Window, or NULL if there is no enclosing Window. - virtual Window* GetContainingWindow() = 0; - virtual const Window* GetContainingWindow() const = 0; - - // Notifies the NativeWidget that a view was removed from the Widget's view - // hierarchy. - virtual void ViewRemoved(View* view) = 0; // Sets/Gets a native window property on the underlying native window object. // Returns NULL if the property does not exist. Setting the property value to @@ -96,11 +78,6 @@ class NativeWidget { // Returns true if a system screen reader is active for the NativeWidget. virtual bool IsScreenReaderActive() const = 0; - // Notify native Accessibility clients of an event. - virtual void SendNativeAccessibilityEvent( - View* view, - ui::AccessibilityTypes::Event event_type) = 0; - // Sets or releases event capturing for this native widget. virtual void SetMouseCapture() = 0; virtual void ReleaseMouseCapture() = 0; @@ -108,9 +85,6 @@ class NativeWidget { // Returns true if this native widget is capturing all events. virtual bool HasMouseCapture() const = 0; - // Returns true if any mouse button is currently pressed. - virtual bool IsMouseButtonDown() const = 0; - // Returns the InputMethod for this native widget. // Note that all widgets in a widget hierarchy share the same input method. // TODO(suzhe): rename to GetInputMethod() when NativeWidget implementation diff --git a/views/widget/native_widget_delegate.h b/views/widget/native_widget_delegate.h index 05af457..036bb48 100644 --- a/views/widget/native_widget_delegate.h +++ b/views/widget/native_widget_delegate.h @@ -50,10 +50,6 @@ class NativeWidgetDelegate { virtual bool OnKeyEvent(const KeyEvent& event) = 0; virtual bool OnMouseEvent(const MouseEvent& event) = 0; virtual void OnMouseCaptureLost() = 0; - - // - virtual Widget* AsWidget() = 0; - virtual const Widget* AsWidget() const = 0; }; } // namespace internal diff --git a/views/widget/native_widget_test_utils_gtk.cc b/views/widget/native_widget_test_utils_gtk.cc index 2e0a820..6c478f2 100644 --- a/views/widget/native_widget_test_utils_gtk.cc +++ b/views/widget/native_widget_test_utils_gtk.cc @@ -16,7 +16,7 @@ NativeWidget* CreateNativeWidget() { } NativeWidget* CreateNativeWidgetWithContents(View* contents_view) { - Widget* widget = new Widget; + Widget* widget = Widget::CreateWidget(); Widget::InitParams params(Widget::InitParams::TYPE_WINDOW); params.delete_on_destroy = false; params.bounds = gfx::Rect(10, 10, 200, 200); @@ -25,7 +25,7 @@ NativeWidget* CreateNativeWidgetWithContents(View* contents_view) { } NativeWidget* CreateNativeWidgetWithParent(NativeWidget* parent) { - Widget* widget = new Widget; + Widget* widget = Widget::CreateWidget(); Widget::InitParams params(Widget::InitParams::TYPE_CONTROL); params.delete_on_destroy = false; params.parent = parent ? parent->GetWidget()->GetNativeView() : NULL; diff --git a/views/widget/native_widget_test_utils_win.cc b/views/widget/native_widget_test_utils_win.cc index fd89efe..59e1d8d 100644 --- a/views/widget/native_widget_test_utils_win.cc +++ b/views/widget/native_widget_test_utils_win.cc @@ -15,7 +15,7 @@ NativeWidget* CreateNativeWidget() { } NativeWidget* CreateNativeWidgetWithContents(View* contents_view) { - Widget* widget = new Widget; + Widget* widget = Widget::CreateWidget(); Widget::InitParams params(Widget::InitParams::TYPE_WINDOW); params.delete_on_destroy = false; params.bounds = gfx::Rect(10, 10, 200, 200); @@ -24,7 +24,7 @@ NativeWidget* CreateNativeWidgetWithContents(View* contents_view) { } NativeWidget* CreateNativeWidgetWithParent(NativeWidget* parent) { - Widget* widget = new Widget; + Widget* widget = Widget::CreateWidget(); Widget::InitParams params(Widget::InitParams::TYPE_CONTROL); params.delete_on_destroy = false; params.child = false; // Implicitly set to true by ctor with TYPE_CONTROL. diff --git a/views/widget/tooltip_manager_gtk.cc b/views/widget/tooltip_manager_gtk.cc index 7c8c0dd..dfc0e39 100644 --- a/views/widget/tooltip_manager_gtk.cc +++ b/views/widget/tooltip_manager_gtk.cc @@ -85,12 +85,12 @@ bool TooltipManagerGtk::ShowTooltip(int x, int y, bool for_keyboard, view = keyboard_view_; view_loc.SetPoint(view->width() / 2, view->height() / 2); } else if (!for_keyboard) { - RootView* root_view = widget_->GetWidget()->GetRootView(); + RootView* root_view = widget_->GetRootView(); view = root_view->GetEventHandlerForPoint(gfx::Point(x, y)); view_loc.SetPoint(x, y); View::ConvertPointFromWidget(view, &view_loc); } else { - FocusManager* focus_manager = widget_->GetWidget()->GetFocusManager(); + FocusManager* focus_manager = widget_->GetFocusManager(); if (focus_manager) { view = focus_manager->GetFocusedView(); if (view) @@ -116,7 +116,7 @@ bool TooltipManagerGtk::ShowTooltip(int x, int y, bool for_keyboard, int max_width, line_count; gfx::Point screen_loc(x, y); - View::ConvertPointToScreen(widget_->GetWidget()->GetRootView(), &screen_loc); + View::ConvertPointToScreen(widget_->GetRootView(), &screen_loc); TrimTooltipToFit(&text, &max_width, &line_count, screen_loc.x(), screen_loc.y()); tooltip_window_.SetTooltipText(text); diff --git a/views/widget/widget.cc b/views/widget/widget.cc index e02f8f9d..a7c03d9 100644 --- a/views/widget/widget.cc +++ b/views/widget/widget.cc @@ -9,7 +9,6 @@ #include "ui/gfx/compositor/compositor.h" #include "views/focus/view_storage.h" #include "views/ime/input_method.h" -#include "views/views_delegate.h" #include "views/widget/default_theme_provider.h" #include "views/widget/root_view.h" #include "views/widget/native_widget.h" @@ -22,7 +21,6 @@ namespace views { Widget::InitParams::InitParams() : type(TYPE_WINDOW), child(false), - transient(false), transparent(false), accept_events(true), can_activate(true), @@ -39,7 +37,6 @@ Widget::InitParams::InitParams() Widget::InitParams::InitParams(Type type) : type(type), child(type == TYPE_CONTROL), - transient(type == TYPE_POPUP || type == TYPE_MENU), transparent(false), accept_events(true), can_activate(type != TYPE_POPUP && type != TYPE_MENU), @@ -66,50 +63,41 @@ Widget::Widget() last_mouse_event_was_move_(false), native_widget_(NULL), widget_delegate_(NULL), - dragged_view_(NULL), - delete_on_destroy_(false), - is_secondary_widget_(true) { + dragged_view_(NULL) { } Widget::~Widget() { - DestroyRootView(); - - if (!delete_on_destroy_) - delete native_widget_; } void Widget::Init(const InitParams& params) { - delete_on_destroy_ = params.delete_on_destroy; - native_widget_ = - params.native_widget ? params.native_widget - : NativeWidget::CreateNativeWidget(this); GetRootView(); default_theme_provider_.reset(new DefaultThemeProvider); - if (params.type == InitParams::TYPE_MENU) - is_mouse_button_pressed_ = native_widget_->IsMouseButtonDown(); native_widget_->InitNativeWidget(params); } // Unconverted methods (see header) -------------------------------------------- gfx::NativeView Widget::GetNativeView() const { - return native_widget_->GetNativeView(); + return NULL; } gfx::NativeWindow Widget::GetNativeWindow() const { - return native_widget_->GetNativeWindow(); + return NULL; +} + +void Widget::GenerateMousePressedForView(View* view, const gfx::Point& point) { } bool Widget::GetAccelerator(int cmd_id, ui::Accelerator* accelerator) { return false; } -Window* Widget::GetContainingWindow() { - return native_widget_->GetContainingWindow(); +Window* Widget::GetWindow() { + return NULL; } -const Window* Widget::GetContainingWindow() const { - return native_widget_->GetContainingWindow(); +const Window* Widget::GetWindow() const { + return NULL; } void Widget::ViewHierarchyChanged(bool is_add, View* parent, View* child) { @@ -120,8 +108,7 @@ void Widget::ViewHierarchyChanged(bool is_add, View* parent, View* child) { FocusManager* focus_manager = GetFocusManager(); if (focus_manager) focus_manager->ViewRemoved(child); - ViewStorage::GetInstance()->ViewRemoved(child); - native_widget_->ViewRemoved(child); + ViewStorage::GetInstance()->ViewRemoved(parent, child); } } @@ -286,10 +273,6 @@ void Widget::SetCursor(gfx::NativeCursor cursor) { native_widget_->SetCursor(cursor); } -void Widget::ResetLastMouseMoveFlag() { - last_mouse_event_was_move_ = false; -} - FocusTraversable* Widget::GetFocusTraversable() { return root_view_.get(); } @@ -310,18 +293,6 @@ void Widget::SetFocusTraversableParentView(View* parent_view) { root_view_->SetFocusTraversableParentView(parent_view); } -void Widget::NotifyAccessibilityEvent( - View* view, - ui::AccessibilityTypes::Event event_type, - bool send_native_event) { - // Send the notification to the delegate. - if (ViewsDelegate::views_delegate) - ViewsDelegate::views_delegate->NotifyAccessibilityEvent(view, event_type); - - if (send_native_event) - native_widget_->SendNativeAccessibilityEvent(view, event_type); -} - //////////////////////////////////////////////////////////////////////////////// // Widget, NativeWidgetDelegate implementation: @@ -436,14 +407,6 @@ void Widget::OnMouseCaptureLost() { is_mouse_button_pressed_ = false; } -Widget* Widget::AsWidget() { - return this; -} - -const Widget* Widget::AsWidget() const { - return this; -} - //////////////////////////////////////////////////////////////////////////////// // Widget, FocusTraversable implementation: diff --git a/views/widget/widget.h b/views/widget/widget.h index 3c74618..110ee20 100644 --- a/views/widget/widget.h +++ b/views/widget/widget.h @@ -52,20 +52,12 @@ class Window; // Widget is a platform-independent type that communicates with a platform or // context specific NativeWidget implementation. // -// A special note on ownership: -// -// Depending on the value of "delete_on_destroy", the Widget either owns or -// is owned by its NativeWidget: -// -// delete_on_destroy = true (default) -// The Widget instance is owned by its NativeWidget. When the NativeWidget -// is destroyed (in response to a native destruction message), it deletes -// the Widget from its destructor. -// delete_on_destroy = false (non-default) -// The Widget instance owns its NativeWidget. This state implies someone -// else wants to control the lifetime of this object. When they destroy -// the Widget it is responsible for destroying the NativeWidget (from its -// destructor). +// TODO(beng): Note that this class being non-abstract means that we have a +// violation of Google style in that we are using multiple +// inheritance. The intention is to split this into a separate +// object associated with but not equal to a NativeWidget +// implementation. Multiple inheritance is required for this +// transitional step. // class Widget : public internal::NativeWidgetDelegate, public FocusTraversable { @@ -84,7 +76,6 @@ class Widget : public internal::NativeWidgetDelegate, Type type; bool child; - bool transient; bool transparent; bool accept_events; bool can_activate; @@ -104,14 +95,13 @@ class Widget : public internal::NativeWidgetDelegate, Widget(); virtual ~Widget(); + // Creates a Widget instance with the supplied params. + static Widget* CreateWidget(); + // Enumerates all windows pertaining to us and notifies their // view hierarchies that the locale has changed. static void NotifyLocaleChanged(); - // Closes all Widgets that aren't identified as "secondary widgets". Called - // during application shutdown when the last non-secondary widget is closed. - static void CloseAllSecondaryWidgets(); - // Converts a rectangle from one Widget's coordinate system to another's. // Returns false if the conversion couldn't be made, because either these two // Widgets do not have a common ancestor or they are not on the screen yet. @@ -124,15 +114,22 @@ class Widget : public internal::NativeWidgetDelegate, // Unconverted methods ------------------------------------------------------- - // TODO(beng): reorder, they've been converted now. + // TODO(beng): + // Widget subclasses are still implementing these methods by overriding from + // here rather than by implementing NativeWidget. // Returns the gfx::NativeView associated with this Widget. - gfx::NativeView GetNativeView() const; + virtual gfx::NativeView GetNativeView() const; // Returns the gfx::NativeWindow associated with this Widget. This may return // NULL on some platforms if the widget was created with a type other than // TYPE_WINDOW. - gfx::NativeWindow GetNativeWindow() const; + virtual gfx::NativeWindow GetNativeWindow() const; + + // Starts a drag operation for the specified view. |point| is a position in + // |view| coordinates that the drag was initiated from. + virtual void GenerateMousePressedForView(View* view, + const gfx::Point& point); // Returns the accelerator given a command id. Returns false if there is // no accelerator associated with a given id, which is a common condition. @@ -140,15 +137,15 @@ class Widget : public internal::NativeWidgetDelegate, // Returns the Window containing this Widget, or NULL if not contained in a // window. - Window* GetContainingWindow(); - const Window* GetContainingWindow() const; + virtual Window* GetWindow(); + virtual const Window* GetWindow() const; // Forwarded from the RootView so that the widget can do any cleanup. - void ViewHierarchyChanged(bool is_add, View* parent, View* child); + virtual void ViewHierarchyChanged(bool is_add, View* parent, View* child); // Performs any necessary cleanup and forwards to RootView. - void NotifyNativeViewHierarchyChanged(bool attached, - gfx::NativeView native_view); + virtual void NotifyNativeViewHierarchyChanged(bool attached, + gfx::NativeView native_view); // Converted methods --------------------------------------------------------- @@ -191,7 +188,7 @@ class Widget : public internal::NativeWidgetDelegate, void SetShape(gfx::NativeRegion shape); // Hides the widget then closes it after a return to the message loop. - virtual void Close(); + void Close(); // TODO(beng): Move off public API. // Closes the widget immediately. Compare to |Close|. This will destroy the @@ -215,16 +212,6 @@ class Widget : public internal::NativeWidgetDelegate, // Returns the RootView contained by this Widget. RootView* GetRootView(); - // A secondary widget is one that is automatically closed (via Close()) when - // all non-secondary widgets are closed. - // Default is true. - // TODO(beng): This is an ugly API, should be handled implicitly via - // transience. - void set_is_secondary_widget(bool is_secondary_widget) { - is_secondary_widget_ = is_secondary_widget; - } - bool is_secondary_widget() const { return is_secondary_widget_; } - // Returns whether the Widget is visible to the user. bool IsVisible() const; @@ -270,12 +257,6 @@ class Widget : public internal::NativeWidgetDelegate, // before the current is restored. void SetCursor(gfx::NativeCursor cursor); - // Resets the last move flag so that we can go around the optimization - // that disregards duplicate mouse moves when ending animation requires - // a new hit-test to do some highlighting as in TabStrip::RemoveTabAnimation - // to cause the close button to highlight. - void ResetLastMouseMoveFlag(); - // Retrieves the focus traversable for this widget. FocusTraversable* GetFocusTraversable(); @@ -299,10 +280,10 @@ class Widget : public internal::NativeWidgetDelegate, // cases where the view is a native control that's already sending a // native accessibility event and the duplicate event would cause // problems. - void NotifyAccessibilityEvent( + virtual void NotifyAccessibilityEvent( View* view, ui::AccessibilityTypes::Event event_type, - bool send_native_event); + bool send_native_event) = 0; NativeWidget* native_widget() { return native_widget_; } @@ -318,8 +299,6 @@ class Widget : public internal::NativeWidgetDelegate, virtual bool OnKeyEvent(const KeyEvent& event) OVERRIDE; virtual bool OnMouseEvent(const MouseEvent& event) OVERRIDE; virtual void OnMouseCaptureLost() OVERRIDE; - virtual Widget* AsWidget() OVERRIDE; - virtual const Widget* AsWidget() const OVERRIDE; // Overridden from FocusTraversable: virtual FocusSearch* GetFocusSearch() OVERRIDE; @@ -327,9 +306,6 @@ class Widget : public internal::NativeWidgetDelegate, virtual View* GetFocusTraversableParentView() OVERRIDE; protected: - // TODO(beng): Remove WidgetGtk's dependence on the mouse state flags. - friend class WidgetGtk; - // Creates the RootView to be used within this Widget. Subclasses may override // to create custom RootViews that do specialized event processing. // TODO(beng): Investigate whether or not this is needed. @@ -340,15 +316,19 @@ class Widget : public internal::NativeWidgetDelegate, // TODO(beng): remove once we fold those objects onto this one. void DestroyRootView(); + // TODO(beng): Temporarily provided as a way to associate the subclass' + // implementation of NativeWidget with this. + void set_native_widget(NativeWidget* native_widget) { + native_widget_ = native_widget; + } + // Used for testing. void ReplaceFocusManager(FocusManager* focus_manager); - // TODO(beng): Remove WidgetGtk's dependence on these: // TODO(msw): Make this mouse state member private. // If true, the mouse is currently down. bool is_mouse_button_pressed_; - // TODO(beng): Remove WidgetGtk's dependence on these: // TODO(msw): Make these mouse state members private. // The following are used to detect duplicate mouse move events and not // deliver them. Displaying a window may result in the system generating @@ -390,12 +370,6 @@ class Widget : public internal::NativeWidgetDelegate, // The compositor for accelerated drawing. scoped_refptr<ui::Compositor> compositor_; - // See class documentation for Widget above for a note about ownership. - bool delete_on_destroy_; - - // See set_is_secondary_widget(). - bool is_secondary_widget_; - DISALLOW_COPY_AND_ASSIGN(Widget); }; diff --git a/views/widget/widget_gtk.cc b/views/widget/widget_gtk.cc index bbb0fd5..b506dac 100644 --- a/views/widget/widget_gtk.cc +++ b/views/widget/widget_gtk.cc @@ -284,9 +284,9 @@ bool WidgetGtk::debug_paint_enabled_ = false; //////////////////////////////////////////////////////////////////////////////// // WidgetGtk, public: -WidgetGtk::WidgetGtk(internal::NativeWidgetDelegate* delegate) +WidgetGtk::WidgetGtk() : is_window_(false), - delegate_(delegate), + ALLOW_THIS_IN_INITIALIZER_LIST(delegate_(this)), widget_(NULL), window_contents_(NULL), child_(false), @@ -301,7 +301,6 @@ WidgetGtk::WidgetGtk(internal::NativeWidgetDelegate* delegate) transient_to_parent_(false), got_initial_focus_in_(false), has_focus_(false), - focus_on_creation_(true), always_on_top_(false), is_double_buffered_(false), should_handle_menu_key_release_(false), @@ -312,6 +311,7 @@ WidgetGtk::WidgetGtk(internal::NativeWidgetDelegate* delegate) // the widget. TouchFactory::GetInstance(); #endif + set_native_widget(this); static bool installed_message_loop_observer = false; if (!installed_message_loop_observer) { installed_message_loop_observer = true; @@ -325,9 +325,8 @@ WidgetGtk::~WidgetGtk() { // We need to delete the input method before calling DestroyRootView(), // because it'll set focus_manager_ to NULL. input_method_.reset(); + DestroyRootView(); DCHECK(delete_on_destroy_ || widget_ == NULL); - if (delete_on_destroy_) - delete delegate_; } GtkWindow* WidgetGtk::GetTransientParent() const { @@ -444,7 +443,7 @@ void WidgetGtk::DoDrag(const OSExchangeData& data, int operation) { } void WidgetGtk::IsActiveChanged() { - WidgetDelegate* d = GetWidget()->widget_delegate(); + WidgetDelegate* d = widget_delegate(); if (d) { bool a = IsActive(); d->OnWidgetActivated(a); @@ -452,11 +451,8 @@ void WidgetGtk::IsActiveChanged() { } void WidgetGtk::SetInitialFocus() { - if (!focus_on_creation_) - return; - - View* v = GetWidget()->widget_delegate() ? - GetWidget()->widget_delegate()->GetInitiallyFocusedView() : NULL; + View* v = widget_delegate() ? + widget_delegate()->GetInitiallyFocusedView() : NULL; if (v) v->RequestFocus(); } @@ -500,13 +496,52 @@ void WidgetGtk::ActiveWindowChanged(GdkWindow* active_window) { } if (was_active != IsActive()) { IsActiveChanged(); - GetWidget()->GetRootView()->SchedulePaint(); + GetRootView()->SchedulePaint(); } } //////////////////////////////////////////////////////////////////////////////// // WidgetGtk, Widget implementation: +gfx::NativeView WidgetGtk::GetNativeView() const { + return widget_; +} + +gfx::NativeWindow WidgetGtk::GetNativeWindow() const { + return child_ ? NULL : GTK_WINDOW(widget_); +} + +bool WidgetGtk::GetAccelerator(int cmd_id, ui::Accelerator* accelerator) { + NOTIMPLEMENTED(); + return false; +} + +Window* WidgetGtk::GetWindow() { + return GetWindowImpl(widget_); +} + +const Window* WidgetGtk::GetWindow() const { + return GetWindowImpl(widget_); +} + +void WidgetGtk::ViewHierarchyChanged(bool is_add, View* parent, View* child) { + Widget::ViewHierarchyChanged(is_add, parent, child); + if (drop_target_.get()) + drop_target_->ResetTargetViewIfEquals(child); +} + +void WidgetGtk::NotifyAccessibilityEvent( + View* view, + ui::AccessibilityTypes::Event event_type, + bool send_native_event) { + // Send the notification to the delegate. + if (ViewsDelegate::views_delegate) + ViewsDelegate::views_delegate->NotifyAccessibilityEvent(view, event_type); + + // In the future if we add native GTK accessibility support, the + // notification should be sent here. +} + void WidgetGtk::ClearNativeFocus() { DCHECK(!child_); if (!GetNativeView()) { @@ -517,7 +552,7 @@ void WidgetGtk::ClearNativeFocus() { } bool WidgetGtk::HandleKeyboardEvent(const KeyEvent& key) { - if (!GetWidget()->GetFocusManager()) + if (!GetFocusManager()) return false; const int key_code = key.key_code(); @@ -534,7 +569,7 @@ bool WidgetGtk::HandleKeyboardEvent(const KeyEvent& key) { // VKEY_MENU is triggered by key release event. // FocusManager::OnKeyEvent() returns false when the key has been consumed. if (key_code != ui::VKEY_MENU) - handled = !GetWidget()->GetFocusManager()->OnKeyEvent(key); + handled = !GetFocusManager()->OnKeyEvent(key); else should_handle_menu_key_release_ = true; } else if (key_code == ui::VKEY_MENU && should_handle_menu_key_release_ && @@ -542,7 +577,7 @@ bool WidgetGtk::HandleKeyboardEvent(const KeyEvent& key) { // Trigger VKEY_MENU when only this key is pressed and released, and both // press and release events are not handled by others. Accelerator accelerator(ui::VKEY_MENU, false, false, false); - handled = GetWidget()->GetFocusManager()->ProcessAccelerator(accelerator); + handled = GetFocusManager()->ProcessAccelerator(accelerator); } return handled; @@ -591,10 +626,10 @@ void WidgetGtk::RegisterChildExposeHandler(GtkWidget* child) { //////////////////////////////////////////////////////////////////////////////// // WidgetGtk, NativeWidget implementation: -void WidgetGtk::InitNativeWidget(const Widget::InitParams& params) { +void WidgetGtk::InitNativeWidget(const InitParams& params) { SetInitParams(params); - Widget::InitParams modified_params = params; + InitParams modified_params = params; gfx::NativeView parent = params.parent; if (params.parent_widget) { WidgetGtk* parent_gtk = @@ -731,32 +766,7 @@ void WidgetGtk::InitNativeWidget(const Widget::InitParams& params) { } Widget* WidgetGtk::GetWidget() { - return delegate_->AsWidget(); -} - -const Widget* WidgetGtk::GetWidget() const { - return delegate_->AsWidget(); -} - -gfx::NativeView WidgetGtk::GetNativeView() const { - return widget_; -} - -gfx::NativeWindow WidgetGtk::GetNativeWindow() const { - return child_ ? NULL : GTK_WINDOW(widget_); -} - -Window* WidgetGtk::GetContainingWindow() { - return GetWindowImpl(widget_); -} - -const Window* WidgetGtk::GetContainingWindow() const { - return GetWindowImpl(widget_); -} - -void WidgetGtk::ViewRemoved(View* view) { - if (drop_target_.get()) - drop_target_->ResetTargetViewIfEquals(view); + return this; } void WidgetGtk::SetNativeWindowProperty(const char* name, void* value) { @@ -775,13 +785,6 @@ bool WidgetGtk::IsScreenReaderActive() const { return false; } -void WidgetGtk::SendNativeAccessibilityEvent( - View* view, - ui::AccessibilityTypes::Event event_type) { - // In the future if we add native GTK accessibility support, the - // notification should be sent here. -} - void WidgetGtk::SetMouseCapture() { DCHECK(!HasMouseCapture()); gtk_grab_add(window_contents_); @@ -798,18 +801,6 @@ bool WidgetGtk::HasMouseCapture() const { return GTK_WIDGET_HAS_GRAB(window_contents_); } -bool WidgetGtk::IsMouseButtonDown() const { - bool button_pressed = false; - GdkEvent* event = gtk_get_current_event(); - if (event) { - button_pressed = event->type == GDK_BUTTON_PRESS || - event->type == GDK_2BUTTON_PRESS || - event->type == GDK_3BUTTON_PRESS; - gdk_event_free(event); - } - return button_pressed; -} - InputMethod* WidgetGtk::GetInputMethodNative() { return input_method_.get(); } @@ -1027,7 +1018,7 @@ void WidgetGtk::OnSizeRequest(GtkWidget* widget, GtkRequisition* requisition) { // preferred size for these would prevents us from setting smaller window // sizes. if (child_) { - gfx::Size size(GetWidget()->GetRootView()->GetPreferredSize()); + gfx::Size size(GetRootView()->GetPreferredSize()); requisition->width = size.width(); requisition->height = size.height(); } @@ -1162,7 +1153,7 @@ gboolean WidgetGtk::OnDragMotion(GtkWidget* widget, gint y, guint time) { if (!drop_target_.get()) - drop_target_.reset(new DropTargetGtk(GetWidget()->GetRootView(), context)); + drop_target_.reset(new DropTargetGtk(GetRootView(), context)); return drop_target_->OnDragMotion(context, x, y, time); } @@ -1173,8 +1164,7 @@ gboolean WidgetGtk::OnEnterNotify(GtkWidget* widget, GdkEventCrossing* event) { return false; } - if (!GetWidget()->last_mouse_event_was_move_ && - !GetWidget()->is_mouse_button_pressed_) { + if (!last_mouse_event_was_move_ && !is_mouse_button_pressed_) { // When a mouse button is pressed gtk generates a leave, enter, press. // RootView expects to get a mouse move before a press, otherwise enter is // not set. So we generate a move here. @@ -1190,13 +1180,13 @@ gboolean WidgetGtk::OnEnterNotify(GtkWidget* widget, GdkEventCrossing* event) { MouseEvent mouse_event(TransformEvent(&motion)); delegate_->OnMouseEvent(mouse_event); } + return false; } gboolean WidgetGtk::OnLeaveNotify(GtkWidget* widget, GdkEventCrossing* event) { - GetWidget()->ResetLastMouseMoveFlag(); - - if (!HasMouseCapture() && !GetWidget()->is_mouse_button_pressed_) { + last_mouse_event_was_move_ = false; + if (!HasMouseCapture() && !is_mouse_button_pressed_) { MouseEvent mouse_event(TransformEvent(event)); delegate_->OnMouseEvent(mouse_event); } @@ -1356,6 +1346,10 @@ void WidgetGtk::HandleGtkGrabBroke() { //////////////////////////////////////////////////////////////////////////////// // WidgetGtk, private: +RootView* WidgetGtk::CreateRootView() { + return new RootView(this); +} + gfx::AcceleratedWidget WidgetGtk::GetAcceleratedWidget() { DCHECK(window_contents_ && window_contents_->window); return GDK_WINDOW_XID(window_contents_->window); @@ -1398,24 +1392,28 @@ void WidgetGtk::DispatchKeyEventPostIME(const KeyEvent& key) { gtk_bindings_activate_event(GTK_OBJECT(widget_), event); } -void WidgetGtk::SetInitParams(const Widget::InitParams& params) { +void WidgetGtk::SetInitParams(const InitParams& params) { DCHECK(!GetNativeView()); delete_on_destroy_ = params.delete_on_destroy; child_ = params.child; - // TODO(beng): The secondary checks here actually obviate the need for - // params.transient but that's only because WidgetGtk considers - // any top-level widget to be a transient widget. We will probably - // want to ammend this assumption at some point. - if (params.transient || params.parent || params.parent_widget) - transient_to_parent_ = true; if (params.transparent) MakeTransparent(); if (!params.accept_events && !child_) ignore_events_ = true; if (params.double_buffer) EnableDoubleBuffer(true); + + if (params.type == InitParams::TYPE_MENU) { + GdkEvent* event = gtk_get_current_event(); + if (event) { + is_mouse_button_pressed_ = event->type == GDK_BUTTON_PRESS || + event->type == GDK_2BUTTON_PRESS || + event->type == GDK_3BUTTON_PRESS; + gdk_event_free(event); + } + } } gboolean WidgetGtk::OnWindowPaint(GtkWidget* widget, GdkEventExpose* event) { @@ -1462,13 +1460,13 @@ Window* WidgetGtk::GetWindowImpl(GtkWidget* widget) { WidgetGtk* widget_gtk = static_cast<WidgetGtk*>( NativeWidget::GetNativeWidgetForNativeView(parent)); if (widget_gtk && widget_gtk->is_window_) - return static_cast<WindowGtk*>(widget_gtk)->GetWindow(); + return static_cast<WindowGtk*>(widget_gtk); parent = gtk_widget_get_parent(parent); } return NULL; } -void WidgetGtk::CreateGtkWidget(const Widget::InitParams& params) { +void WidgetGtk::CreateGtkWidget(const InitParams& params) { // We turn off double buffering for two reasons: // 1. We draw to a canvas then composite to the screen, which means we're // doing our own double buffering already. @@ -1522,8 +1520,8 @@ void WidgetGtk::CreateGtkWidget(const Widget::InitParams& params) { } else { // Use our own window class to override GtkWindow's move_focus method. widget_ = gtk_views_window_new( - params.type == Widget::InitParams::TYPE_WINDOW ? GTK_WINDOW_TOPLEVEL - : GTK_WINDOW_POPUP); + params.type == InitParams::TYPE_WINDOW ? GTK_WINDOW_TOPLEVEL + : GTK_WINDOW_POPUP); gtk_widget_set_name(widget_, "views-gtkwidget-window"); if (transient_to_parent_) { gtk_window_set_transient_for(GTK_WINDOW(widget_), @@ -1562,7 +1560,7 @@ void WidgetGtk::CreateGtkWidget(const Widget::InitParams& params) { gtk_container_add(GTK_CONTAINER(widget_), window_contents_); gtk_widget_show(window_contents_); g_object_set_data(G_OBJECT(window_contents_), kNativeWidgetKey, - static_cast<WidgetGtk*>(this)); + static_cast<Widget*>(this)); if (transparent_) ConfigureWidgetForTransparentBackground(NULL); @@ -1645,6 +1643,11 @@ void WidgetGtk::DrawTransparentBackground(GtkWidget* widget, // Widget, public: // static +Widget* Widget::CreateWidget() { + return new WidgetGtk(); +} + +// static void Widget::NotifyLocaleChanged() { GList *window_list = gtk_window_list_toplevels(); for (GList* element = window_list; element; element = g_list_next(element)) { @@ -1657,22 +1660,6 @@ void Widget::NotifyLocaleChanged() { } // static -void Widget::CloseAllSecondaryWidgets() { - GList* windows = gtk_window_list_toplevels(); - for (GList* window = windows; window; - window = g_list_next(window)) { - NativeWidget* native_widget = NativeWidget::GetNativeWidgetForNativeView( - GTK_WIDGET(window->data)); - if (native_widget) { - Widget* widget = native_widget->GetWidget(); - if (widget->is_secondary_widget()) - widget->Close(); - } - } - g_list_free(windows); -} - -// static bool Widget::ConvertRect(const Widget* source, const Widget* target, gfx::Rect* rect) { @@ -1702,12 +1689,6 @@ bool Widget::ConvertRect(const Widget* source, // NativeWidget, public: // static -NativeWidget* NativeWidget::CreateNativeWidget( - internal::NativeWidgetDelegate* delegate) { - return new WidgetGtk(delegate); -} - -// static NativeWidget* NativeWidget::GetNativeWidgetForNativeView( gfx::NativeView native_view) { if (!native_view) @@ -1759,40 +1740,4 @@ void NativeWidget::GetAllNativeWidgets(gfx::NativeView native_view, reinterpret_cast<gpointer>(children)); } -// static -void NativeWidget::ReparentNativeView(gfx::NativeView native_view, - gfx::NativeView new_parent) { - if (!native_view) - return; - - gfx::NativeView previous_parent = gtk_widget_get_parent(native_view); - if (previous_parent == new_parent) - return; - - NativeWidgets widgets; - GetAllNativeWidgets(native_view, &widgets); - - // First notify all the widgets that they are being disassociated - // from their previous parent. - for (NativeWidgets::iterator it = widgets.begin(); - it != widgets.end(); ++it) { - // TODO(beng): Rename this notification to NotifyNativeViewChanging() - // and eliminate the bool parameter. - (*it)->GetWidget()->NotifyNativeViewHierarchyChanged(false, - previous_parent); - } - - if (gtk_widget_get_parent(native_view)) - gtk_widget_reparent(native_view, new_parent); - else - gtk_container_add(GTK_CONTAINER(new_parent), native_view); - - // And now, notify them that they have a brand new parent. - for (NativeWidgets::iterator it = widgets.begin(); - it != widgets.end(); ++it) { - (*it)->GetWidget()->NotifyNativeViewHierarchyChanged(true, - new_parent); - } -} - } // namespace views diff --git a/views/widget/widget_gtk.h b/views/widget/widget_gtk.h index 54acfa6..eaa29cd 100644 --- a/views/widget/widget_gtk.h +++ b/views/widget/widget_gtk.h @@ -41,13 +41,25 @@ class NativeWidgetDelegate; } // Widget implementation for GTK. -class WidgetGtk : public NativeWidget, +class WidgetGtk : public Widget, + public NativeWidget, public ui::ActiveWindowWatcherX::Observer, public internal::InputMethodDelegate { public: - explicit WidgetGtk(internal::NativeWidgetDelegate* delegate); + WidgetGtk(); virtual ~WidgetGtk(); + // Marks this window as transient to its parent. A window that is transient + // to its parent results in the parent rendering active when the child is + // active. + // This must be invoked before Init. This is only used for types other than + // TYPE_CHILD. The default is false. + // See gtk_window_set_transient_for for details. + void make_transient_to_parent() { + DCHECK(!widget_); + transient_to_parent_ = true; + } + // Returns the transient parent. See make_transient_to_parent for details on // what the transient parent is. GtkWindow* GetTransientParent() const; @@ -111,6 +123,19 @@ class WidgetGtk : public NativeWidget, // Overridden from ui::ActiveWindowWatcherX::Observer. virtual void ActiveWindowChanged(GdkWindow* active_window); + // Overridden from Widget: + virtual gfx::NativeView GetNativeView() const; + virtual gfx::NativeWindow GetNativeWindow() const; + virtual bool GetAccelerator(int cmd_id, ui::Accelerator* accelerator); + virtual Window* GetWindow(); + virtual const Window* GetWindow() const; + virtual void ViewHierarchyChanged(bool is_add, View *parent, + View *child); + virtual void NotifyAccessibilityEvent( + View* view, + ui::AccessibilityTypes::Event event_type, + bool send_native_event); + // Clears the focus on the native widget having the focus. virtual void ClearNativeFocus(); @@ -143,30 +168,16 @@ class WidgetGtk : public NativeWidget, // detached widget. static void RegisterChildExposeHandler(GtkWidget* widget); - void set_focus_on_creation(bool focus_on_creation) { - focus_on_creation_ = focus_on_creation; - } - // Overridden from NativeWidget: - virtual void InitNativeWidget(const Widget::InitParams& params) OVERRIDE; + virtual void InitNativeWidget(const InitParams& params) OVERRIDE; virtual Widget* GetWidget() OVERRIDE; - virtual const Widget* GetWidget() const OVERRIDE; - virtual gfx::NativeView GetNativeView() const OVERRIDE; - virtual gfx::NativeWindow GetNativeWindow() const OVERRIDE; - virtual Window* GetContainingWindow() OVERRIDE; - virtual const Window* GetContainingWindow() const OVERRIDE; - virtual void ViewRemoved(View* view) OVERRIDE; virtual void SetNativeWindowProperty(const char* name, void* value) OVERRIDE; virtual void* GetNativeWindowProperty(const char* name) OVERRIDE; virtual TooltipManager* GetTooltipManager() const OVERRIDE; virtual bool IsScreenReaderActive() const OVERRIDE; - virtual void SendNativeAccessibilityEvent( - View* view, - ui::AccessibilityTypes::Event event_type) OVERRIDE; virtual void SetMouseCapture() OVERRIDE; virtual void ReleaseMouseCapture() OVERRIDE; virtual bool HasMouseCapture() const OVERRIDE; - virtual bool IsMouseButtonDown() const OVERRIDE; virtual InputMethod* GetInputMethodNative() OVERRIDE; virtual void ReplaceInputMethod(InputMethod* input_method) OVERRIDE; virtual gfx::Rect GetWindowScreenBounds() const OVERRIDE; @@ -257,13 +268,16 @@ class WidgetGtk : public NativeWidget, class DropObserver; friend class DropObserver; + // Overridden from Widget + virtual RootView* CreateRootView() OVERRIDE; + // Overridden from NativeWidget virtual gfx::AcceleratedWidget GetAcceleratedWidget() OVERRIDE; // Overridden from internal::InputMethodDelegate virtual void DispatchKeyEventPostIME(const KeyEvent& key) OVERRIDE; - void SetInitParams(const Widget::InitParams& params); + void SetInitParams(const InitParams& params); // This is called only when the window is transparent. CHROMEGTK_CALLBACK_1(WidgetGtk, gboolean, OnWindowPaint, GdkEventExpose*); @@ -277,7 +291,7 @@ class WidgetGtk : public NativeWidget, static Window* GetWindowImpl(GtkWidget* widget); // Creates the GtkWidget. - void CreateGtkWidget(const Widget::InitParams& params); + void CreateGtkWidget(const InitParams& params); // Invoked from create widget to enable the various bits needed for a // transparent background. This is only invoked if MakeTransparent has been @@ -293,7 +307,6 @@ class WidgetGtk : public NativeWidget, GdkEventExpose* event); // A delegate implementation that handles events received here. - // See class documentation for Widget in widget.h for a note about ownership. internal::NativeWidgetDelegate* delegate_; // Our native views. If we're a window/popup, then widget_ is the window and @@ -320,7 +333,7 @@ class WidgetGtk : public NativeWidget, // The following factory is used to delay destruction. ScopedRunnableMethodFactory<WidgetGtk> close_widget_factory_; - // See class documentation for Widget in widget.h for a note about ownership. + // See description above setter. bool delete_on_destroy_; // See description above make_transparent for details. @@ -372,10 +385,6 @@ class WidgetGtk : public NativeWidget, // this to determine whether we should process the event. bool has_focus_; - // Whether we should SetFocus() on a newly created window after - // Init(). Defaults to true. - bool focus_on_creation_; - // If true, the window stays on top of the screen. This is only used // for types other than TYPE_CHILD. bool always_on_top_; diff --git a/views/widget/widget_win.cc b/views/widget/widget_win.cc index 67166ff..a5d2044 100644 --- a/views/widget/widget_win.cc +++ b/views/widget/widget_win.cc @@ -132,8 +132,8 @@ bool WidgetWin::screen_reader_active_ = false; //////////////////////////////////////////////////////////////////////////////// // WidgetWin, public: -WidgetWin::WidgetWin(internal::NativeWidgetDelegate* delegate) - : delegate_(delegate), +WidgetWin::WidgetWin() + : ALLOW_THIS_IN_INITIALIZER_LIST(delegate_(this)), close_widget_factory_(this), active_mouse_tracking_flags_(0), use_layered_buffer_(false), @@ -147,14 +147,14 @@ WidgetWin::WidgetWin(internal::NativeWidgetDelegate* delegate) accessibility_view_events_(kMaxAccessibilityViewEvents), previous_cursor_(NULL), is_input_method_win_(false) { + set_native_widget(this); } WidgetWin::~WidgetWin() { // We need to delete the input method before calling DestroyRootView(), // because it'll set focus_manager_ to NULL. input_method_.reset(); - if (delete_on_destroy_) - delete delegate_; + DestroyRootView(); } // static @@ -192,24 +192,7 @@ void WidgetWin::ClearAccessibilityViewEvent(View* view) { } //////////////////////////////////////////////////////////////////////////////// -// WidgetWin, NativeWidget implementation: - -void WidgetWin::InitNativeWidget(const Widget::InitParams& params) { - SetInitParams(params); - - // Create the window. - gfx::NativeView parent = params.parent_widget ? - params.parent_widget->GetNativeView() : params.parent; - WindowImpl::Init(parent, params.bounds); -} - -Widget* WidgetWin::GetWidget() { - return delegate_->AsWidget(); -} - -const Widget* WidgetWin::GetWidget() const { - return delegate_->AsWidget(); -} +// WidgetWin, Widget implementation: gfx::NativeView WidgetWin::GetNativeView() const { return WindowImpl::hwnd(); @@ -219,19 +202,42 @@ gfx::NativeWindow WidgetWin::GetNativeWindow() const { return WindowImpl::hwnd(); } -Window* WidgetWin::GetContainingWindow() { +bool WidgetWin::GetAccelerator(int cmd_id, ui::Accelerator* accelerator) { + return false; +} + +Window* WidgetWin::GetWindow() { return GetWindowImpl(hwnd()); } -const Window* WidgetWin::GetContainingWindow() const { +const Window* WidgetWin::GetWindow() const { return GetWindowImpl(hwnd()); } -void WidgetWin::ViewRemoved(View* view) { +void WidgetWin::ViewHierarchyChanged(bool is_add, View* parent, + View* child) { + Widget::ViewHierarchyChanged(is_add, parent, child); if (drop_target_.get()) - drop_target_->ResetTargetViewIfEquals(view); + drop_target_->ResetTargetViewIfEquals(child); - ClearAccessibilityViewEvent(view); + if (!is_add) + ClearAccessibilityViewEvent(child); +} + +//////////////////////////////////////////////////////////////////////////////// +// WidgetWin, NativeWidget implementation: + +void WidgetWin::InitNativeWidget(const Widget::InitParams& params) { + SetInitParams(params); + + // Create the window. + gfx::NativeView parent = params.parent_widget ? + params.parent_widget->GetNativeView() : params.parent; + WindowImpl::Init(parent, params.bounds); +} + +Widget* WidgetWin::GetWidget() { + return this; } void WidgetWin::SetNativeWindowProperty(const char* name, void* value) { @@ -259,19 +265,6 @@ bool WidgetWin::IsScreenReaderActive() const { return screen_reader_active_; } -void WidgetWin::SendNativeAccessibilityEvent( - View* view, - ui::AccessibilityTypes::Event event_type) { - // Now call the Windows-specific method to notify MSAA clients of this - // event. The widget gives us a temporary unique child ID to associate - // with this view so that clients can call get_accChild in - // NativeViewAccessibilityWin to retrieve the IAccessible associated - // with this view. - int child_id = AddAccessibilityViewEvent(view); - ::NotifyWinEvent(NativeViewAccessibilityWin::MSAAEvent(event_type), - GetNativeView(), OBJID_CLIENT, child_id); -} - void WidgetWin::SetMouseCapture() { DCHECK(!HasMouseCapture()); SetCapture(hwnd()); @@ -285,14 +278,6 @@ bool WidgetWin::HasMouseCapture() const { return GetCapture() == hwnd(); } -bool WidgetWin::IsMouseButtonDown() const { - return (GetKeyState(VK_LBUTTON) & 0x80) || - (GetKeyState(VK_RBUTTON) & 0x80) || - (GetKeyState(VK_MBUTTON) & 0x80) || - (GetKeyState(VK_XBUTTON1) & 0x80) || - (GetKeyState(VK_XBUTTON2) & 0x80); -} - InputMethod* WidgetWin::GetInputMethodNative() { return input_method_.get(); } @@ -462,6 +447,26 @@ void WidgetWin::SetCursor(gfx::NativeCursor cursor) { } } +void WidgetWin::NotifyAccessibilityEvent( + View* view, + ui::AccessibilityTypes::Event event_type, + bool send_native_event) { + // Send the notification to the delegate. + if (ViewsDelegate::views_delegate) + ViewsDelegate::views_delegate->NotifyAccessibilityEvent(view, event_type); + + // Now call the Windows-specific method to notify MSAA clients of this + // event. The widget gives us a temporary unique child ID to associate + // with this view so that clients can call get_accChild in + // NativeViewAccessibilityWin to retrieve the IAccessible associated + // with this view. + if (send_native_event) { + int child_id = AddAccessibilityViewEvent(view); + ::NotifyWinEvent(NativeViewAccessibilityWin::MSAAEvent(event_type), + GetNativeView(), OBJID_CLIENT, child_id); + } +} + //////////////////////////////////////////////////////////////////////////////// // WidgetWin, MessageLoop::Observer implementation: @@ -502,7 +507,7 @@ LRESULT WidgetWin::OnWndProc(UINT message, WPARAM w_param, LPARAM l_param) { PostProcessActivateMessage(this, LOWORD(w_param)); if (message == WM_ENABLE && restore_focus_when_enabled_) { restore_focus_when_enabled_ = false; - GetWidget()->GetFocusManager()->RestoreFocusedView(); + GetFocusManager()->RestoreFocusedView(); } return result; } @@ -553,7 +558,7 @@ LRESULT WidgetWin::OnCreate(CREATESTRUCT* create_struct) { props_.push_back(SetWindowSupportsRerouteMouseWheel(hwnd())); - drop_target_ = new DropTargetWin(GetWidget()->GetRootView()); + drop_target_ = new DropTargetWin(GetRootView()); // We need to add ourselves as a message loop observer so that we can repaint // aggressively if the contents of our window become invalid. Unfortunately @@ -564,10 +569,10 @@ LRESULT WidgetWin::OnCreate(CREATESTRUCT* create_struct) { // Windows special DWM window frame requires a special tooltip manager so // that window controls in Chrome windows don't flicker when you move your // mouse over them. See comment in aero_tooltip_manager.h. - if (GetWidget()->GetThemeProvider()->ShouldUseNativeFrame()) { - tooltip_manager_.reset(new AeroTooltipManager(GetWidget())); + if (GetThemeProvider()->ShouldUseNativeFrame()) { + tooltip_manager_.reset(new AeroTooltipManager(this)); } else { - tooltip_manager_.reset(new TooltipManagerWin(GetWidget())); + tooltip_manager_.reset(new TooltipManagerWin(this)); } // This message initializes the window so that focus border are shown for @@ -607,8 +612,8 @@ void WidgetWin::OnDestroy() { } void WidgetWin::OnDisplayChange(UINT bits_per_pixel, CSize screen_size) { - if (GetWidget()->widget_delegate()) - GetWidget()->widget_delegate()->OnDisplayChanged(); + if (widget_delegate()) + widget_delegate()->OnDisplayChanged(); } LRESULT WidgetWin::OnDwmCompositionChanged(UINT msg, @@ -646,8 +651,7 @@ LRESULT WidgetWin::OnGetObject(UINT uMsg, WPARAM w_param, LPARAM l_param) { if (OBJID_CLIENT == l_param) { // Retrieve MSAA dispatch object for the root view. base::win::ScopedComPtr<IAccessible> root( - NativeViewAccessibilityWin::GetAccessibleForView( - GetWidget()->GetRootView())); + NativeViewAccessibilityWin::GetAccessibleForView(GetRootView())); // Create a reference that MSAA will marshall to the client. reference_result = LresultFromObject(IID_IAccessible, w_param, @@ -785,16 +789,14 @@ LRESULT WidgetWin::OnMouseRange(UINT message, WPARAM w_param, LPARAM l_param) { } void WidgetWin::OnMove(const CPoint& point) { - // TODO(beng): move to Widget. - if (GetWidget()->widget_delegate()) - GetWidget()->widget_delegate()->OnWidgetMove(); + if (widget_delegate()) + widget_delegate()->OnWidgetMove(); SetMsgHandled(FALSE); } void WidgetWin::OnMoving(UINT param, const LPRECT new_bounds) { - // TODO(beng): move to Widget. - if (GetWidget()->widget_delegate()) - GetWidget()->widget_delegate()->OnWidgetMove(); + if (widget_delegate()) + widget_delegate()->OnWidgetMove(); } LRESULT WidgetWin::OnNCActivate(BOOL active) { @@ -891,9 +893,8 @@ LRESULT WidgetWin::OnSetText(const wchar_t* text) { } void WidgetWin::OnSettingChange(UINT flags, const wchar_t* section) { - // TODO(beng): move to Widget. - if (flags == SPI_SETWORKAREA && GetWidget()->widget_delegate()) - GetWidget()->widget_delegate()->OnWorkAreaChanged(); + if (flags == SPI_SETWORKAREA && widget_delegate()) + widget_delegate()->OnWorkAreaChanged(); SetMsgHandled(FALSE); } @@ -960,9 +961,8 @@ void WidgetWin::OnScreenReaderDetected() { } void WidgetWin::SetInitialFocus() { - // TODO(beng): move to Widget. - View* v = GetWidget()->widget_delegate() ? - GetWidget()->widget_delegate()->GetInitiallyFocusedView() : NULL; + View* v = widget_delegate() ? + widget_delegate()->GetInitiallyFocusedView() : NULL; if (v) v->RequestFocus(); } @@ -979,7 +979,7 @@ Window* WidgetWin::GetWindowImpl(HWND hwnd) { WidgetWin* widget = reinterpret_cast<WidgetWin*>(ui::GetWindowUserData(parent)); if (widget && widget->is_window_) - return static_cast<WindowWin*>(widget)->GetWindow(); + return static_cast<WindowWin*>(widget); parent = ::GetParent(parent); } return NULL; @@ -1016,7 +1016,7 @@ void WidgetWin::PostProcessActivateMessage(WidgetWin* widget, } } -void WidgetWin::SetInitParams(const Widget::InitParams& params) { +void WidgetWin::SetInitParams(const InitParams& params) { // Set non-style attributes. delete_on_destroy_ = params.delete_on_destroy; @@ -1044,15 +1044,21 @@ void WidgetWin::SetInitParams(const Widget::InitParams& params) { // Set type-dependent style attributes. switch (params.type) { - case Widget::InitParams::TYPE_WINDOW: - case Widget::InitParams::TYPE_CONTROL: + case InitParams::TYPE_WINDOW: + case InitParams::TYPE_CONTROL: break; - case Widget::InitParams::TYPE_POPUP: + case InitParams::TYPE_POPUP: style |= WS_POPUP; ex_style |= WS_EX_TOOLWINDOW; break; - case Widget::InitParams::TYPE_MENU: + case InitParams::TYPE_MENU: style |= WS_POPUP; + is_mouse_button_pressed_ = + ((GetKeyState(VK_LBUTTON) & 0x80) || + (GetKeyState(VK_RBUTTON) & 0x80) || + (GetKeyState(VK_MBUTTON) & 0x80) || + (GetKeyState(VK_XBUTTON1) & 0x80) || + (GetKeyState(VK_XBUTTON2) & 0x80)); break; default: NOTREACHED(); @@ -1083,7 +1089,7 @@ void WidgetWin::RedrawLayeredWindowContents() { layered_window_invalid_rect_.y(), layered_window_invalid_rect_.width(), layered_window_invalid_rect_.height()); - GetWidget()->GetRootView()->Paint(layered_window_contents_.get()); + GetRootView()->Paint(layered_window_contents_.get()); layered_window_contents_->restore(); RECT wr; @@ -1101,7 +1107,7 @@ void WidgetWin::RedrawLayeredWindowContents() { void WidgetWin::ClientAreaSizeChanged() { RECT r; - if (GetWidget()->GetThemeProvider()->ShouldUseNativeFrame() || IsZoomed()) + if (GetThemeProvider()->ShouldUseNativeFrame() || IsZoomed()) GetClientRect(&r); else GetWindowRect(&r); @@ -1127,26 +1133,13 @@ void WidgetWin::DispatchKeyEventPostIME(const KeyEvent& key) { // Widget, public: // static -void Widget::NotifyLocaleChanged() { - NOTIMPLEMENTED(); +Widget* Widget::CreateWidget() { + return new WidgetWin; } -namespace { -BOOL CALLBACK WindowCallbackProc(HWND hwnd, LPARAM lParam) { - NativeWidget* native_widget = - NativeWidget::GetNativeWidgetForNativeView(hwnd); - if (native_widget) { - Widget* widget = native_widget->GetWidget(); - if (widget->is_secondary_widget()) - widget->Close(); - } - return TRUE; -} -} // namespace - // static -void Widget::CloseAllSecondaryWidgets() { - EnumThreadWindows(GetCurrentThreadId(), WindowCallbackProc, 0); +void Widget::NotifyLocaleChanged() { + NOTIMPLEMENTED(); } bool Widget::ConvertRect(const Widget* source, @@ -1174,26 +1167,17 @@ bool Widget::ConvertRect(const Widget* source, //////////////////////////////////////////////////////////////////////////////// // NativeWidget, public: -// static -NativeWidget* NativeWidget::CreateNativeWidget( - internal::NativeWidgetDelegate* delegate) { - return new WidgetWin(delegate); -} - -// static NativeWidget* NativeWidget::GetNativeWidgetForNativeView( gfx::NativeView native_view) { return reinterpret_cast<WidgetWin*>( ViewProp::GetValue(native_view, kNativeWidgetKey)); } -// static NativeWidget* NativeWidget::GetNativeWidgetForNativeWindow( gfx::NativeWindow native_window) { return GetNativeWidgetForNativeView(native_window); } -// static NativeWidget* NativeWidget::GetTopLevelNativeWidget( gfx::NativeView native_view) { if (!native_view) @@ -1222,7 +1206,6 @@ NativeWidget* NativeWidget::GetTopLevelNativeWidget( return widget; } -// static void NativeWidget::GetAllNativeWidgets(gfx::NativeView native_view, NativeWidgets* children) { if (!native_view) @@ -1235,7 +1218,6 @@ void NativeWidget::GetAllNativeWidgets(gfx::NativeView native_view, reinterpret_cast<LPARAM>(children)); } -// static void NativeWidget::ReparentNativeView(gfx::NativeView native_view, gfx::NativeView new_parent) { if (!native_view) diff --git a/views/widget/widget_win.h b/views/widget/widget_win.h index d013ddb..3c2974b 100644 --- a/views/widget/widget_win.h +++ b/views/widget/widget_win.h @@ -23,6 +23,7 @@ #include "views/ime/input_method_delegate.h" #include "views/layout/layout_manager.h" #include "views/widget/native_widget.h" +#include "views/widget/widget.h" namespace ui { class ViewProp; @@ -44,6 +45,8 @@ namespace internal { class NativeWidgetDelegate; } +RootView* GetRootViewForHWND(HWND hwnd); + // A Windows message reflected from other windows. This message is sent // with the following arguments: // hWnd - Target window @@ -77,11 +80,12 @@ const int WM_NCUAHDRAWFRAME = 0xAF; // /////////////////////////////////////////////////////////////////////////////// class WidgetWin : public ui::WindowImpl, + public Widget, public NativeWidget, public MessageLoopForUI::Observer, public internal::InputMethodDelegate { public: - explicit WidgetWin(internal::NativeWidgetDelegate* delegate); + WidgetWin(); virtual ~WidgetWin(); // Returns true if we are on Windows Vista or greater and composition is @@ -109,6 +113,20 @@ class WidgetWin : public ui::WindowImpl, // Clear a view that has recently been removed on a hierarchy change. void ClearAccessibilityViewEvent(View* view); + // Overridden from Widget: + virtual gfx::NativeView GetNativeView() const OVERRIDE; + virtual gfx::NativeWindow GetNativeWindow() const OVERRIDE; + virtual bool GetAccelerator(int cmd_id, + ui::Accelerator* accelerator) OVERRIDE; + virtual Window* GetWindow() OVERRIDE; + virtual const Window* GetWindow() const OVERRIDE; + virtual void ViewHierarchyChanged(bool is_add, View *parent, + View *child) OVERRIDE; + virtual void NotifyAccessibilityEvent( + View* view, + ui::AccessibilityTypes::Event event_type, + bool send_native_event); + BOOL IsWindow() const { return ::IsWindow(GetNativeView()); } @@ -165,26 +183,24 @@ class WidgetWin : public ui::WindowImpl, return ::GetClientRect(GetNativeView(), rect); } + // Resets the last move flag so that we can go around the optimization + // that disregards duplicate mouse moves when ending animation requires + // a new hit-test to do some highlighting as in TabStrip::RemoveTabAnimation + // to cause the close button to highlight. + void ResetLastMouseMoveFlag() { + last_mouse_event_was_move_ = false; + } + // Overridden from NativeWidget: virtual void InitNativeWidget(const Widget::InitParams& params) OVERRIDE; virtual Widget* GetWidget() OVERRIDE; - virtual const Widget* GetWidget() const OVERRIDE; - virtual gfx::NativeView GetNativeView() const OVERRIDE; - virtual gfx::NativeWindow GetNativeWindow() const OVERRIDE; - virtual Window* GetContainingWindow() OVERRIDE; - virtual const Window* GetContainingWindow() const OVERRIDE; - virtual void ViewRemoved(View* view) OVERRIDE; virtual void SetNativeWindowProperty(const char* name, void* value) OVERRIDE; virtual void* GetNativeWindowProperty(const char* name) OVERRIDE; virtual TooltipManager* GetTooltipManager() const OVERRIDE; virtual bool IsScreenReaderActive() const OVERRIDE; - virtual void SendNativeAccessibilityEvent( - View* view, - ui::AccessibilityTypes::Event event_type) OVERRIDE; virtual void SetMouseCapture() OVERRIDE; virtual void ReleaseMouseCapture() OVERRIDE; virtual bool HasMouseCapture() const OVERRIDE; - virtual bool IsMouseButtonDown() const OVERRIDE; virtual InputMethod* GetInputMethodNative() OVERRIDE; virtual void ReplaceInputMethod(InputMethod* input_method) OVERRIDE; virtual gfx::Rect GetWindowScreenBounds() const OVERRIDE; @@ -427,7 +443,6 @@ class WidgetWin : public ui::WindowImpl, virtual void DispatchKeyEventPostIME(const KeyEvent& key) OVERRIDE; // A delegate implementation that handles events received here. - // See class documentation for Widget in widget.h for a note about ownership. internal::NativeWidgetDelegate* delegate_; // The following factory is used for calls to close the WidgetWin @@ -466,7 +481,8 @@ class WidgetWin : public ui::WindowImpl, // A factory that allows us to schedule a redraw for layered windows. ScopedRunnableMethodFactory<WidgetWin> paint_layered_window_factory_; - // See class documentation for Widget in widget.h for a note about ownership. + // Whether or not the window should delete itself when it is destroyed. + // Set this to false via its setter for stack allocated instances. bool delete_on_destroy_; // True if we are allowed to update the layered window from the DIB backing diff --git a/views/widget/widget_win_unittest.cc b/views/widget/widget_win_unittest.cc index c9a33e8..3c13138 100644 --- a/views/widget/widget_win_unittest.cc +++ b/views/widget/widget_win_unittest.cc @@ -43,7 +43,7 @@ class WidgetWinTest : public testing::Test { }; WidgetWin* WidgetWinTest::CreateWidgetWin() { - scoped_ptr<Widget> widget(new Widget); + scoped_ptr<Widget> widget(Widget::CreateWidget()); Widget::InitParams params(Widget::InitParams::TYPE_WINDOW); params.delete_on_destroy = false; params.bounds = gfx::Rect(50, 50, 650, 650); diff --git a/views/window/custom_frame_view.cc b/views/window/custom_frame_view.cc index 305eae1..e86cd10 100644 --- a/views/window/custom_frame_view.cc +++ b/views/window/custom_frame_view.cc @@ -236,7 +236,7 @@ gfx::Size CustomFrameView::GetPreferredSize() { void CustomFrameView::ButtonPressed(Button* sender, const views::Event& event) { if (sender == close_button_) - frame_->Close(); + frame_->CloseWindow(); else if (sender == minimize_button_) frame_->Minimize(); else if (sender == maximize_button_) diff --git a/views/window/dialog_client_view.cc b/views/window/dialog_client_view.cc index b3b5c9a..e2cc5ef 100644 --- a/views/window/dialog_client_view.cc +++ b/views/window/dialog_client_view.cc @@ -541,7 +541,7 @@ DialogDelegate* DialogClientView::GetDialogDelegate() const { } void DialogClientView::Close() { - window()->Close(); + window()->CloseWindow(); GetDialogDelegate()->OnClose(); } diff --git a/views/window/native_frame_view.cc b/views/window/native_frame_view.cc index c78d6d1..397b6f3 100644 --- a/views/window/native_frame_view.cc +++ b/views/window/native_frame_view.cc @@ -4,16 +4,14 @@ #include "views/window/native_frame_view.h" -#include "views/widget/widget_win.h" -#include "views/window/native_window.h" -#include "views/window/window.h" +#include "views/window/window_win.h" namespace views { //////////////////////////////////////////////////////////////////////////////// // NativeFrameView, public: -NativeFrameView::NativeFrameView(Window* frame) +NativeFrameView::NativeFrameView(WindowWin* frame) : NonClientFrameView(), frame_(frame) { } @@ -31,10 +29,8 @@ gfx::Rect NativeFrameView::GetBoundsForClientView() const { gfx::Rect NativeFrameView::GetWindowBoundsForClientBounds( const gfx::Rect& client_bounds) const { RECT rect = client_bounds.ToRECT(); - WidgetWin* widget_win = - static_cast<WidgetWin*>(frame_->native_window()->AsNativeWidget()); - AdjustWindowRectEx(&rect, widget_win->window_style(), FALSE, - widget_win->window_ex_style()); + AdjustWindowRectEx(&rect, frame_->window_style(), FALSE, + frame_->window_ex_style()); return gfx::Rect(rect); } diff --git a/views/window/native_frame_view.h b/views/window/native_frame_view.h index 9bc943f..ac68ddf 100644 --- a/views/window/native_frame_view.h +++ b/views/window/native_frame_view.h @@ -10,11 +10,11 @@ namespace views { -class Window; +class WindowWin; class NativeFrameView : public NonClientFrameView { public: - explicit NativeFrameView(Window* frame); + explicit NativeFrameView(WindowWin* frame); virtual ~NativeFrameView(); // NonClientFrameView overrides: @@ -33,7 +33,7 @@ class NativeFrameView : public NonClientFrameView { private: // Our containing frame. - Window* frame_; + WindowWin* frame_; DISALLOW_COPY_AND_ASSIGN(NativeFrameView); }; diff --git a/views/window/native_window.h b/views/window/native_window.h index 0e83f30..63da12a 100644 --- a/views/window/native_window.h +++ b/views/window/native_window.h @@ -37,13 +37,9 @@ class NativeWindow { virtual ~NativeWindow() {} - // Creates an appropriate default NativeWindow implementation for the current - // OS/circumstance. - static NativeWindow* CreateNativeWindow( - internal::NativeWindowDelegate* delegate); + static Window* CreateNativeWindow(); virtual Window* GetWindow() = 0; - virtual const Window* GetWindow() const = 0; virtual NativeWidget* AsNativeWidget() = 0; virtual const NativeWidget* AsNativeWidget() const = 0; @@ -104,6 +100,7 @@ class NativeWindow { virtual void SetFullscreen(bool fullscreen) = 0; virtual bool IsFullscreen() const = 0; virtual void SetAlwaysOnTop(bool always_on_top) = 0; + virtual bool IsAppWindow() const = 0; virtual void SetUseDragFrame(bool use_drag_frame) = 0; virtual NonClientFrameView* CreateFrameViewForWindow() = 0; virtual void UpdateFrameAfterFrameChange() = 0; diff --git a/views/window/native_window_delegate.h b/views/window/native_window_delegate.h index c88924b..23705a5 100644 --- a/views/window/native_window_delegate.h +++ b/views/window/native_window_delegate.h @@ -6,10 +6,6 @@ #define VIEWS_WIDGET_NATIVE_WINDOW_DELEGATE_H_ #pragma once -namespace ui { -class ThemeProvider; -} - namespace views { namespace internal { @@ -68,12 +64,6 @@ class NativeWindowDelegate { // Called when the native window's position or size has changed. virtual void OnNativeWindowBoundsChanged() = 0; - - // - virtual Window* AsWindow() = 0; - - // - virtual NativeWidgetDelegate* AsNativeWidgetDelegate() = 0; }; } // namespace internal diff --git a/views/window/window.cc b/views/window/window.cc index efc9f15..13f2515 100644 --- a/views/window/window.cc +++ b/views/window/window.cc @@ -47,7 +47,7 @@ Window::~Window() { Window* Window::CreateChromeWindow(gfx::NativeWindow parent, const gfx::Rect& bounds, WindowDelegate* window_delegate) { - Window* window = new Window; + Window* window = NativeWindow::CreateNativeWindow(); Window::InitParams params(window_delegate); params.parent_window = parent; params.widget_init_params.bounds = bounds; @@ -74,24 +74,34 @@ gfx::Size Window::GetLocalizedContentsSize(int col_resource_id, GetLocalizedContentsHeight(row_resource_id)); } +// static +void Window::CloseSecondaryWidget(Widget* widget) { + if (!widget) + return; + + // Close widget if it's identified as a secondary window. + Window* window = widget->GetWindow(); + if (window) { + if (!window->IsAppWindow()) + window->CloseWindow(); + } else { + // If it's not a Window, then close it anyway since it probably is + // secondary. + widget->Close(); + } +} + void Window::InitWindow(const InitParams& params) { window_delegate_ = params.window_delegate; AsWidget()->set_widget_delegate(window_delegate_); DCHECK(window_delegate_); DCHECK(!window_delegate_->window_); window_delegate_->window_ = this; - set_widget_delegate(window_delegate_); - 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.native_widget = - native_window_->AsNativeWidget(); - Init(modified_params.widget_init_params); - OnNativeWindowCreated(modified_params.widget_init_params.bounds); + AsWidget()->Init(params.widget_init_params); + OnNativeWindowCreated(params.widget_init_params.bounds); } gfx::Rect Window::GetBounds() const { @@ -139,7 +149,7 @@ void Window::Deactivate() { native_window_->Deactivate(); } -void Window::Close() { +void Window::CloseWindow() { if (window_closed_) { // It appears we can hit this code path if you close a modal dialog then // close the last browser before the destructor is hit, which triggers @@ -149,7 +159,9 @@ void Window::Close() { if (non_client_view_->CanClose()) { SaveWindowPosition(); - Widget::Close(); + // TODO(beng): This can be simplified to Widget::Close() once Window + // subclasses Widget. + native_window_->AsNativeWidget()->GetWidget()->Close(); window_closed_ = true; } } @@ -194,6 +206,10 @@ void Window::SetUseDragFrame(bool use_drag_frame) { native_window_->SetUseDragFrame(use_drag_frame); } +bool Window::IsAppWindow() const { + return native_window_->IsAppWindow(); +} + void Window::EnableClose(bool enable) { non_client_view_->EnableClose(enable); native_window_->EnableClose(enable); @@ -245,6 +261,21 @@ void Window::FrameTypeChanged() { native_window_->FrameTypeChanged(); } +Widget* Window::AsWidget() { + return const_cast<Widget*>(const_cast<const Window*>(this)->AsWidget()); +} + +const Widget* Window::AsWidget() const { + return native_window_->AsNativeWidget()->GetWidget(); +} + +//////////////////////////////////////////////////////////////////////////////// +// Window, protected: + +void Window::SetNativeWindow(NativeWindow* native_window) { + native_window_ = native_window; +} + //////////////////////////////////////////////////////////////////////////////// // Window, internal::NativeWindowDelegate implementation: @@ -333,14 +364,6 @@ void Window::OnNativeWindowBoundsChanged() { SaveWindowPosition(); } -Window* Window::AsWindow() { - return this; -} - -internal::NativeWidgetDelegate* Window::AsNativeWidgetDelegate() { - return this; -} - //////////////////////////////////////////////////////////////////////////////// // Window, private: diff --git a/views/window/window.h b/views/window/window.h index 191aba4..76fdb76 100644 --- a/views/window/window.h +++ b/views/window/window.h @@ -39,8 +39,7 @@ class WindowDelegate; // implementation. Multiple inheritance is required for this // transitional step. // -class Window : public Widget, - public internal::NativeWindowDelegate { +class Window : public internal::NativeWindowDelegate { public: struct InitParams { // |window_delegate| cannot be NULL. @@ -72,6 +71,16 @@ class Window : public Widget, static gfx::Size GetLocalizedContentsSize(int col_resource_id, int row_resource_id); + // Closes all windows that aren't identified as "app windows" via + // IsAppWindow. Called during application shutdown when the last "app window" + // is closed. + static void CloseAllSecondaryWindows(); + + // Used by |CloseAllSecondaryWindows|. If |widget|'s window is a secondary + // window, the window is closed. If |widget| has no window, it is closed. + // Does nothing if |widget| is null. + static void CloseSecondaryWidget(Widget* widget); + // Initializes the window. Must be called before any post-configuration // operations are performed. void InitWindow(const InitParams& params); @@ -115,7 +124,7 @@ class Window : public Widget, // Closes the window, ultimately destroying it. The window hides immediately, // and is destroyed after a return to the message loop. Close() can be called // multiple times. - virtual void Close() OVERRIDE; + void CloseWindow(); // Maximizes/minimizes/restores the window. void Maximize(); @@ -129,7 +138,7 @@ class Window : public Widget, bool IsVisible() const; // Whether or not the window is maximized or minimized. - virtual bool IsMaximized() const; + bool IsMaximized() const; bool IsMinimized() const; // Accessors for fullscreen state. @@ -140,6 +149,11 @@ class Window : public Widget, // frame" - slightly transparent and without the standard window controls. void SetUseDragFrame(bool use_drag_frame); + // Returns true if the Window is considered to be an "app window" - i.e. + // any window which when it is the last of its type closed causes the + // application to exit. + virtual bool IsAppWindow() const; + // Toggles the enable state for the Close button (and the Close menu item in // the system menu). void EnableClose(bool enable); @@ -168,6 +182,10 @@ class Window : public Widget, // Tell the window that something caused the frame type to change. void FrameTypeChanged(); + // TODO(beng): remove once Window subclasses Widget. + Widget* AsWidget(); + const Widget* AsWidget() const; + WindowDelegate* window_delegate() { return const_cast<WindowDelegate*>( const_cast<const Window*>(this)->window_delegate()); @@ -195,6 +213,10 @@ class Window : public Widget, NativeWindow* native_window() { return native_window_; } protected: + // TODO(beng): Temporarily provided as a way to associate the subclass' + // implementation of NativeWidget with this. + void SetNativeWindow(NativeWindow* native_window); + // Overridden from NativeWindowDelegate: virtual bool CanActivate() const OVERRIDE; virtual bool IsInactiveRenderingDisabled() const OVERRIDE; @@ -212,8 +234,6 @@ class Window : public Widget, virtual void OnNativeWindowDestroying() OVERRIDE; virtual void OnNativeWindowDestroyed() OVERRIDE; virtual void OnNativeWindowBoundsChanged() OVERRIDE; - virtual Window* AsWindow() OVERRIDE; - virtual internal::NativeWidgetDelegate* AsNativeWidgetDelegate() OVERRIDE; private: // Sizes and positions the window just after it is created. diff --git a/views/window/window_gtk.cc b/views/window/window_gtk.cc index 5d72ed8..0e7a6f2 100644 --- a/views/window/window_gtk.cc +++ b/views/window/window_gtk.cc @@ -79,17 +79,37 @@ GdkCursorType HitTestCodeToGdkCursorType(int hittest_code) { namespace views { -WindowGtk::WindowGtk(internal::NativeWindowDelegate* delegate) - : WidgetGtk(delegate->AsNativeWidgetDelegate()), - delegate_(delegate), +WindowGtk::WindowGtk() + : ALLOW_THIS_IN_INITIALIZER_LIST(delegate_(this)), window_state_(GDK_WINDOW_STATE_WITHDRAWN), window_closed_(false) { + SetNativeWindow(this); is_window_ = true; } WindowGtk::~WindowGtk() { } +// static +void Window::CloseAllSecondaryWindows() { + GList* windows = gtk_window_list_toplevels(); + for (GList* window = windows; window; + window = g_list_next(window)) { + Window::CloseSecondaryWidget( + NativeWidget::GetNativeWidgetForNativeView( + GTK_WIDGET(window->data))->GetWidget()); + } + g_list_free(windows); +} + +Window* WindowGtk::AsWindow() { + return this; +} + +const Window* WindowGtk::AsWindow() const { + return this; +} + //////////////////////////////////////////////////////////////////////////////// // WindowGtk, WidgetGtk overrides: @@ -109,7 +129,7 @@ gboolean WindowGtk::OnButtonPress(GtkWidget* widget, GdkEventButton* event) { if (event->type == GDK_BUTTON_PRESS && !mouse_event.IsOnlyRightMouseButton()) { gfx::Point screen_point(event->x, event->y); - View::ConvertPointToScreen(GetWindow()->GetRootView(), &screen_point); + View::ConvertPointToScreen(GetRootView(), &screen_point); gtk_window_begin_move_drag(GetNativeWindow(), event->button, screen_point.x(), screen_point.y(), event->time); @@ -127,7 +147,7 @@ gboolean WindowGtk::OnButtonPress(GtkWidget* widget, GdkEventButton* event) { case HTTOPLEFT: case HTTOPRIGHT: { gfx::Point screen_point(event->x, event->y); - View::ConvertPointToScreen(GetWindow()->GetRootView(), &screen_point); + View::ConvertPointToScreen(GetRootView(), &screen_point); // TODO(beng): figure out how to get a good minimum size. gtk_widget_set_size_request(GetNativeView(), 100, 100); gtk_window_begin_resize_drag(GetNativeWindow(), @@ -201,6 +221,9 @@ void WindowGtk::IsActiveChanged() { } void WindowGtk::InitNativeWidget(const Widget::InitParams& params) { + if (params.parent) + make_transient_to_parent(); + WidgetGtk::InitNativeWidget(params); g_signal_connect(G_OBJECT(GetNativeWindow()), "configure-event", @@ -287,11 +310,7 @@ void WindowGtk::SetAccessibleState(ui::AccessibilityTypes::State state) { } Window* WindowGtk::GetWindow() { - return delegate_->AsWindow(); -} - -const Window* WindowGtk::GetWindow() const { - return delegate_->AsWindow(); + return this; } void WindowGtk::SetWindowBounds(const gfx::Rect& bounds, @@ -301,7 +320,7 @@ void WindowGtk::SetWindowBounds(const gfx::Rect& bounds, } void WindowGtk::HideWindow() { - GetWindow()->Hide(); + Hide(); } void WindowGtk::Activate() { @@ -360,14 +379,20 @@ void WindowGtk::SetUseDragFrame(bool use_drag_frame) { NOTIMPLEMENTED(); } -NonClientFrameView* WindowGtk::CreateFrameViewForWindow() { - return new CustomFrameView(delegate_->AsWindow()); -} - void WindowGtk::SetAlwaysOnTop(bool always_on_top) { gtk_window_set_keep_above(GetNativeWindow(), always_on_top); } +bool WindowGtk::IsAppWindow() const { + return false; +} + +NonClientFrameView* WindowGtk::CreateFrameViewForWindow() { + // TODO(erg): Always use a custom frame view? Are there cases where we let + // the window manager deal with the X11 equivalent of the "non-client" area? + return new CustomFrameView(this); +} + void WindowGtk::UpdateFrameAfterFrameChange() { // We currently don't support different frame types on Gtk, so we don't // need to implement this. @@ -385,8 +410,8 @@ bool WindowGtk::ShouldUseNativeFrame() const { void WindowGtk::FrameTypeChanged() { // This is called when the Theme has changed, so forward the event to the root // widget. - GetWidget()->ThemeChanged(); - GetWidget()->GetRootView()->SchedulePaint(); + ThemeChanged(); + GetRootView()->SchedulePaint(); } //////////////////////////////////////////////////////////////////////////////// @@ -412,9 +437,7 @@ void WindowGtk::SaveWindowPosition() { return; bool maximized = window_state_ & GDK_WINDOW_STATE_MAXIMIZED; - GetWindow()->window_delegate()->SaveWindowPlacement( - GetWidget()->GetWindowScreenBounds(), - maximized); + GetWindow()->window_delegate()->SaveWindowPlacement(GetBounds(), maximized); } void WindowGtk::OnDestroy(GtkWidget* widget) { @@ -427,10 +450,8 @@ void WindowGtk::OnDestroy(GtkWidget* widget) { // NativeWindow, public: // static -NativeWindow* NativeWindow::CreateNativeWindow( - internal::NativeWindowDelegate* delegate) { - return new WindowGtk(delegate); +Window* NativeWindow::CreateNativeWindow() { + return new WindowGtk; } } // namespace views - diff --git a/views/window/window_gtk.h b/views/window/window_gtk.h index b235349..e659e4a 100644 --- a/views/window/window_gtk.h +++ b/views/window/window_gtk.h @@ -25,13 +25,13 @@ class Client; class WindowDelegate; // Window implementation for GTK. -class WindowGtk : public WidgetGtk, public NativeWindow { +class WindowGtk : public WidgetGtk, public NativeWindow, public Window { public: - explicit WindowGtk(internal::NativeWindowDelegate* delegate); + WindowGtk(); virtual ~WindowGtk(); - virtual Window* GetWindow() OVERRIDE; - virtual const Window* GetWindow() const OVERRIDE; + virtual Window* AsWindow(); + virtual const Window* AsWindow() const; // Overridden from WidgetGtk: virtual gboolean OnButtonPress(GtkWidget* widget, GdkEventButton* event); @@ -63,6 +63,7 @@ class WindowGtk : public WidgetGtk, public NativeWindow { virtual void SetAccessibleName(const std::wstring& name) OVERRIDE; virtual void SetAccessibleRole(ui::AccessibilityTypes::Role role) OVERRIDE; virtual void SetAccessibleState(ui::AccessibilityTypes::State state) OVERRIDE; + virtual Window* GetWindow() OVERRIDE; virtual void SetWindowBounds(const gfx::Rect& bounds, gfx::NativeWindow other_window) OVERRIDE; virtual void HideWindow() OVERRIDE; @@ -78,6 +79,7 @@ class WindowGtk : public WidgetGtk, public NativeWindow { virtual void SetFullscreen(bool fullscreen) OVERRIDE; virtual bool IsFullscreen() const OVERRIDE; virtual void SetAlwaysOnTop(bool always_on_top) OVERRIDE; + virtual bool IsAppWindow() const OVERRIDE; virtual void SetUseDragFrame(bool use_drag_frame) OVERRIDE; virtual NonClientFrameView* CreateFrameViewForWindow() OVERRIDE; virtual void UpdateFrameAfterFrameChange() OVERRIDE; diff --git a/views/window/window_win.cc b/views/window/window_win.cc index 621af5a..d421647 100644 --- a/views/window/window_win.cc +++ b/views/window/window_win.cc @@ -233,30 +233,6 @@ class WindowWin::ScopedRedrawLock { //////////////////////////////////////////////////////////////////////////////// // WindowWin, public: -WindowWin::WindowWin(internal::NativeWindowDelegate* delegate) - : WidgetWin(delegate->AsNativeWidgetDelegate()), - delegate_(delegate), - focus_on_creation_(true), - restored_enabled_(false), - fullscreen_(false), - is_active_(false), - lock_updates_(false), - saved_window_style_(0), - ignore_window_pos_changes_(false), - ignore_pos_changes_factory_(this), - force_hidden_count_(0), - is_right_mouse_pressed_on_caption_(false), - last_monitor_(NULL), - is_in_size_move_(false) { - is_window_ = true; - // Initialize these values to 0 so that subclasses can override the default - // behavior before calling Init. - set_window_style(0); - set_window_ex_style(0); -} - - - WindowWin::~WindowWin() { } @@ -307,6 +283,28 @@ gfx::Font WindowWin::GetWindowTitleFont() { /////////////////////////////////////////////////////////////////////////////// // WindowWin, protected: +WindowWin::WindowWin() + : ALLOW_THIS_IN_INITIALIZER_LIST(delegate_(this)), + focus_on_creation_(true), + restored_enabled_(false), + fullscreen_(false), + is_active_(false), + lock_updates_(false), + saved_window_style_(0), + ignore_window_pos_changes_(false), + ignore_pos_changes_factory_(this), + force_hidden_count_(0), + is_right_mouse_pressed_on_caption_(false), + last_monitor_(NULL), + is_in_size_move_(false) { + SetNativeWindow(this); + is_window_ = true; + // Initialize these values to 0 so that subclasses can override the default + // behavior before calling Init. + set_window_style(0); + set_window_ex_style(0); +} + gfx::Insets WindowWin::GetClientAreaInsets() const { // Returning an empty Insets object causes the default handling in // WidgetWin::OnNCCalcSize() to be invoked. @@ -373,7 +371,7 @@ LRESULT WindowWin::OnAppCommand(HWND window, short app_command, WORD device, } void WindowWin::OnClose() { - GetWindow()->Close(); + GetWindow()->CloseWindow(); } void WindowWin::OnCommand(UINT notification_code, int command_id, HWND window) { @@ -414,7 +412,7 @@ void WindowWin::OnExitSizeMove() { WidgetWin::OnExitSizeMove(); delegate_->OnNativeWindowEndUserBoundsChange(); - if (!ShouldUseNativeFrame()) { + if (!GetThemeProvider()->ShouldUseNativeFrame()) { // Sending SWP_FRAMECHANGED forces a non-client repaint, which fixes the // glitch in rendering the bottom pixel of the window caused by us // offsetting the client rect there (See comment in GetClientAreaInsets()). @@ -775,8 +773,7 @@ void WindowWin::OnSysCommand(UINT notification_code, CPoint click) { !!(GetKeyState(VK_SHIFT) & 0x8000), !!(GetKeyState(VK_CONTROL) & 0x8000), false); - AsNativeWidget()->GetWidget()->GetFocusManager()-> - ProcessAccelerator(accelerator); + GetFocusManager()->ProcessAccelerator(accelerator); return; } @@ -895,14 +892,6 @@ void WindowWin::SetInitialFocus() { //////////////////////////////////////////////////////////////////////////////// // WindowWin, NativeWindow implementation: -Window* WindowWin::GetWindow() { - return delegate_->AsWindow(); -} - -const Window* WindowWin::GetWindow() const { - return delegate_->AsWindow(); -} - NativeWidget* WindowWin::AsNativeWidget() { return this; } @@ -1174,6 +1163,10 @@ void WindowWin::SetAlwaysOnTop(bool always_on_top) { 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); } +bool WindowWin::IsAppWindow() const { + return false; +} + void WindowWin::SetUseDragFrame(bool use_drag_frame) { if (use_drag_frame) { // Make the frame slightly transparent during the drag operation. @@ -1194,8 +1187,8 @@ void WindowWin::SetUseDragFrame(bool use_drag_frame) { NonClientFrameView* WindowWin::CreateFrameViewForWindow() { if (ShouldUseNativeFrame()) - return new NativeFrameView(GetWindow()); - return new CustomFrameView(GetWindow()); + return new NativeFrameView(this); + return new CustomFrameView(this); } void WindowWin::UpdateFrameAfterFrameChange() { @@ -1208,7 +1201,10 @@ gfx::NativeWindow WindowWin::GetNativeWindow() const { } bool WindowWin::ShouldUseNativeFrame() const { - return WidgetWin::IsAeroGlassEnabled(); + ui::ThemeProvider* tp = GetThemeProvider(); + if (!tp) + return WidgetWin::IsAeroGlassEnabled(); + return tp->ShouldUseNativeFrame(); } void WindowWin::FrameTypeChanged() { @@ -1348,13 +1344,26 @@ void WindowWin::ExecuteSystemMenuCommand(int command) { SendMessage(GetNativeView(), WM_SYSCOMMAND, command, 0); } +namespace { +BOOL CALLBACK WindowCallbackProc(HWND hwnd, LPARAM lParam) { + NativeWidget* native_widget = + NativeWidget::GetNativeWidgetForNativeView(hwnd); + if (native_widget) + Window::CloseSecondaryWidget(native_widget->GetWidget()); + return TRUE; +} +} // namespace + +void Window::CloseAllSecondaryWindows() { + EnumThreadWindows(GetCurrentThreadId(), WindowCallbackProc, 0); +} + //////////////////////////////////////////////////////////////////////////////// // NativeWindow, public: // static -NativeWindow* NativeWindow::CreateNativeWindow( - internal::NativeWindowDelegate* delegate) { - return new WindowWin(delegate); +Window* NativeWindow::CreateNativeWindow() { + return new WindowWin; } } // namespace views diff --git a/views/window/window_win.h b/views/window/window_win.h index 71f2273..5ade949 100644 --- a/views/window/window_win.h +++ b/views/window/window_win.h @@ -41,9 +41,10 @@ class WindowDelegate; // /////////////////////////////////////////////////////////////////////////////// class WindowWin : public WidgetWin, - public NativeWindow { + public NativeWindow, + public Window { public: - explicit WindowWin(internal::NativeWindowDelegate* delegate); + WindowWin(); virtual ~WindowWin(); // Show the window with the specified show command. @@ -66,10 +67,6 @@ class WindowWin : public WidgetWin, // Returns the system set window title font. static gfx::Font GetWindowTitleFont(); - // Overridden from NativeWindow: - virtual Window* GetWindow() OVERRIDE; - virtual const Window* GetWindow() const OVERRIDE; - protected: friend Window; @@ -126,6 +123,8 @@ class WindowWin : public WidgetWin, virtual void OnSize(UINT size_param, const CSize& new_size) OVERRIDE; virtual void OnSysCommand(UINT notification_code, CPoint click) OVERRIDE; virtual void OnWindowPosChanging(WINDOWPOS* window_pos) OVERRIDE; + virtual Window* GetWindow() OVERRIDE { return this; } + virtual const Window* GetWindow() const OVERRIDE { return this; } virtual void Close() OVERRIDE; virtual void SetInitialFocus() OVERRIDE; @@ -160,6 +159,7 @@ class WindowWin : public WidgetWin, virtual void SetFullscreen(bool fullscreen) OVERRIDE; virtual bool IsFullscreen() const OVERRIDE; virtual void SetAlwaysOnTop(bool always_on_top) OVERRIDE; + virtual bool IsAppWindow() const OVERRIDE; virtual void SetUseDragFrame(bool use_drag_frame) OVERRIDE; virtual NonClientFrameView* CreateFrameViewForWindow() OVERRIDE; virtual void UpdateFrameAfterFrameChange() OVERRIDE; |