summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorben@chromium.org <ben@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-03-02 01:13:38 +0000
committerben@chromium.org <ben@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-03-02 01:13:38 +0000
commitd8d70b1414befb63913ada0abfc135eafd97a8a1 (patch)
tree3d4a290b8121549acfd8aefbb01170624726ab78
parentb472d4f576eb17916ab3444218dcb4586f60a247 (diff)
downloadchromium_src-d8d70b1414befb63913ada0abfc135eafd97a8a1.zip
chromium_src-d8d70b1414befb63913ada0abfc135eafd97a8a1.tar.gz
chromium_src-d8d70b1414befb63913ada0abfc135eafd97a8a1.tar.bz2
Remove/replace RootView/Widget getters with new NativeWidget getters.
BUG=72040 TEST=existing unittests. Review URL: http://codereview.chromium.org/6598069 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@76483 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/browser/automation/testing_automation_provider_views.cc7
-rw-r--r--chrome/browser/bookmarks/bookmark_utils.cc13
-rw-r--r--chrome/browser/chromeos/setting_level_bubble.cc10
-rw-r--r--chrome/browser/download/download_util.cc3
-rw-r--r--chrome/browser/speech/speech_input_bubble_views.cc11
-rw-r--r--chrome/browser/ui/views/find_bar_host_gtk.cc2
-rw-r--r--views/controls/native/native_view_host.cc12
-rw-r--r--views/controls/native/native_view_host_win.cc29
-rw-r--r--views/controls/tabbed_pane/native_tabbed_pane_gtk.cc6
-rw-r--r--views/focus/accelerator_handler_touch.cc6
-rw-r--r--views/focus/focus_manager_gtk.cc4
-rw-r--r--views/focus/focus_manager_win.cc6
-rw-r--r--views/test/views_test_base.h4
-rw-r--r--views/view_unittest.cc33
-rw-r--r--views/views.gyp4
-rw-r--r--views/widget/native_widget.h28
-rw-r--r--views/widget/native_widget_test_utils.h22
-rw-r--r--views/widget/native_widget_test_utils_gtk.cc33
-rw-r--r--views/widget/native_widget_test_utils_win.cc33
-rw-r--r--views/widget/native_widget_unittest.cc81
-rw-r--r--views/widget/widget.cc16
-rw-r--r--views/widget/widget.h32
-rw-r--r--views/widget/widget_gtk.cc209
-rw-r--r--views/widget/widget_gtk.h14
-rw-r--r--views/widget/widget_utils.cc2
-rw-r--r--views/widget/widget_win.cc184
-rw-r--r--views/widget/widget_win.h14
-rw-r--r--views/window/window_gtk.cc3
-rw-r--r--views/window/window_win.cc14
29 files changed, 475 insertions, 360 deletions
diff --git a/chrome/browser/automation/testing_automation_provider_views.cc b/chrome/browser/automation/testing_automation_provider_views.cc
index 99b4065..01fedb8 100644
--- a/chrome/browser/automation/testing_automation_provider_views.cc
+++ b/chrome/browser/automation/testing_automation_provider_views.cc
@@ -13,6 +13,7 @@
#include "ui/gfx/point.h"
#include "views/controls/menu/menu_wrapper.h"
#include "views/view.h"
+#include "views/widget/native_widget.h"
#include "views/widget/root_view.h"
#include "views/widget/widget.h"
@@ -121,8 +122,10 @@ void TestingAutomationProvider::WindowGetViewBounds(int handle,
if (window_tracker_->ContainsHandle(handle)) {
gfx::NativeWindow window = window_tracker_->GetResource(handle);
- views::RootView* root_view = views::Widget::FindRootView(window);
- if (root_view) {
+ views::NativeWidget* native_widget =
+ views::NativeWidget::GetNativeWidgetForNativeWindow(window);
+ if (native_widget) {
+ views::View* root_view = native_widget->GetWidget()->GetRootView();
views::View* view = root_view->GetViewByID(view_id);
if (view) {
*success = true;
diff --git a/chrome/browser/bookmarks/bookmark_utils.cc b/chrome/browser/bookmarks/bookmark_utils.cc
index 80d2bf0..eb75b1b 100644
--- a/chrome/browser/bookmarks/bookmark_utils.cc
+++ b/chrome/browser/bookmarks/bookmark_utils.cc
@@ -40,7 +40,7 @@
#include "ui/base/dragdrop/os_exchange_data.h"
#include "views/drag_utils.h"
#include "views/events/event.h"
-#include "views/widget/root_view.h"
+#include "views/widget/native_widget.h"
#include "views/widget/widget.h"
#elif defined(TOOLKIT_GTK)
#include "chrome/browser/ui/gtk/custom_drag.h"
@@ -335,10 +335,13 @@ void DragBookmarks(Profile* profile,
bool was_nested = MessageLoop::current()->IsNested();
MessageLoop::current()->SetNestableTasksAllowed(true);
- views::Widget* widget = views::Widget::GetWidgetFromNativeView(view);
- widget->StartDragForViewFromMouseEvent(NULL, data,
- ui::DragDropTypes::DRAG_COPY | ui::DragDropTypes::DRAG_MOVE |
- ui::DragDropTypes::DRAG_LINK);
+ views::NativeWidget* native_widget =
+ views::NativeWidget::GetNativeWidgetForNativeView(view);
+ if (native_widget) {
+ native_widget->GetWidget()->StartDragForViewFromMouseEvent(NULL, data,
+ ui::DragDropTypes::DRAG_COPY | ui::DragDropTypes::DRAG_MOVE |
+ ui::DragDropTypes::DRAG_LINK);
+ }
MessageLoop::current()->SetNestableTasksAllowed(was_nested);
#elif defined(OS_MACOSX)
diff --git a/chrome/browser/chromeos/setting_level_bubble.cc b/chrome/browser/chromeos/setting_level_bubble.cc
index 55aec2e..6633ab8 100644
--- a/chrome/browser/chromeos/setting_level_bubble.cc
+++ b/chrome/browser/chromeos/setting_level_bubble.cc
@@ -45,14 +45,10 @@ static views::Widget* GetToplevelWidget() {
if (!browser)
return NULL;
- views::RootView* root =
- views::Widget::FindRootView(
+ views::NativeWidget* native_widget =
+ views::NativeWidget::GetNativeWidgetForNativeWindow(
GTK_WINDOW(browser->window()->GetNativeHandle()));
- DCHECK(root);
- if (!root)
- return NULL;
-
- return root->GetWidget();
+ return native_widget->GetWidget();
}
SettingLevelBubble::SettingLevelBubble(SkBitmap* increase_icon,
diff --git a/chrome/browser/download/download_util.cc b/chrome/browser/download/download_util.cc
index 215997f..ae0f398 100644
--- a/chrome/browser/download/download_util.cc
+++ b/chrome/browser/download/download_util.cc
@@ -540,7 +540,8 @@ void DragDownload(const DownloadItem* download,
GtkWidget* root = gtk_widget_get_toplevel(view);
if (!root)
return;
- views::WidgetGtk* widget = views::WidgetGtk::GetViewForNative(root);
+ views::WidgetGtk* widget = static_cast<views::WidgetGtk*>(
+ views::NativeWidget::GetNativeWidgetForNativeView(root));
if (!widget)
return;
diff --git a/chrome/browser/speech/speech_input_bubble_views.cc b/chrome/browser/speech/speech_input_bubble_views.cc
index 6abe5d5..37f53bc 100644
--- a/chrome/browser/speech/speech_input_bubble_views.cc
+++ b/chrome/browser/speech/speech_input_bubble_views.cc
@@ -281,12 +281,11 @@ void SpeechInputBubbleImpl::Show() {
bubble_content_ = new ContentView(delegate_);
UpdateLayout();
- views::Widget* tab = views::Widget::GetWidgetFromNativeView(
- tab_contents()->view()->GetNativeView());
- views::Widget* parent = tab ? tab->GetRootWidget() : NULL;
-
- if (parent) {
- info_bubble_ = InfoBubble::Show(parent,
+ views::NativeWidget* toplevel_widget =
+ views::NativeWidget::GetTopLevelNativeWidget(
+ tab_contents()->view()->GetNativeView());
+ if (toplevel_widget) {
+ info_bubble_ = InfoBubble::Show(toplevel_widget->GetWidget(),
GetInfoBubbleTarget(element_rect_),
BubbleBorder::TOP_LEFT, bubble_content_,
this);
diff --git a/chrome/browser/ui/views/find_bar_host_gtk.cc b/chrome/browser/ui/views/find_bar_host_gtk.cc
index bacb9d8..c0819df 100644
--- a/chrome/browser/ui/views/find_bar_host_gtk.cc
+++ b/chrome/browser/ui/views/find_bar_host_gtk.cc
@@ -18,7 +18,7 @@ void FindBarHost::AudibleAlert() {
void FindBarHost::GetWidgetPositionNative(gfx::Rect* avoid_overlapping_rect) {
gfx::Rect frame_rect, webcontents_rect;
- host()->GetRootWidget()->GetBounds(&frame_rect, true);
+ host()->GetTopLevelWidget()->GetBounds(&frame_rect, true);
TabContentsView* tab_view = find_bar_controller_->tab_contents()->view();
tab_view->GetViewBounds(&webcontents_rect);
avoid_overlapping_rect->Offset(0, webcontents_rect.y() - frame_rect.y());
diff --git a/views/controls/native/native_view_host.cc b/views/controls/native/native_view_host.cc
index 9b6dff2..162b1f6 100644
--- a/views/controls/native/native_view_host.cc
+++ b/views/controls/native/native_view_host.cc
@@ -8,7 +8,7 @@
#include "ui/gfx/canvas.h"
#include "views/controls/native/native_view_host_wrapper.h"
#include "views/controls/native/native_view_host_views.h"
-#include "views/widget/root_view.h"
+#include "views/widget/native_widget.h"
#include "views/widget/widget.h"
namespace views {
@@ -188,12 +188,12 @@ bool NativeViewHost::ContainsNativeView(gfx::NativeView native_view) const {
if (!native_view_)
return false;
- views::Widget* native_widget =
- views::Widget::GetWidgetFromNativeView(native_view_);
- views::RootView* root_view =
- native_widget ? native_widget->GetRootView() : NULL;
- if (root_view && root_view->ContainsNativeView(native_view))
+ views::NativeWidget* native_widget =
+ views::NativeWidget::GetNativeWidgetForNativeView(native_view_);
+ if (native_widget &&
+ native_widget->GetWidget()->ContainsNativeView(native_view)) {
return true;
+ }
return View::ContainsNativeView(native_view);
}
diff --git a/views/controls/native/native_view_host_win.cc b/views/controls/native/native_view_host_win.cc
index 88feac7..dbb8461 100644
--- a/views/controls/native/native_view_host_win.cc
+++ b/views/controls/native/native_view_host_win.cc
@@ -8,6 +8,7 @@
#include "ui/gfx/canvas.h"
#include "views/controls/native/native_view_host.h"
#include "views/focus/focus_manager.h"
+#include "views/widget/native_widget.h"
#include "views/widget/root_view.h"
#include "views/widget/widget.h"
@@ -37,13 +38,13 @@ void NativeViewHostWin::NativeViewAttached() {
// Need to set the HWND's parent before changing its size to avoid flashing.
SetParent(host_->native_view(), host_->GetWidget()->GetNativeView());
host_->Layout();
- // Notify children that parent changed, so they could adjust the focus
- std::vector<RootView*> root_views;
- Widget::FindAllRootViews(host_->native_view(), &root_views);
- for (std::vector<RootView*>::iterator it = root_views.begin();
- it < root_views.end();
- ++it) {
- (*it)->NotifyNativeViewHierarchyChanged(true,
+ // Notify children that parent changed, so they can adjust focus.
+ NativeWidget::NativeWidgets widgets;
+ NativeWidget::GetAllNativeWidgets(host_->native_view(), &widgets);
+ for (NativeWidget::NativeWidgets::iterator it = widgets.begin();
+ it != widgets.end(); ++it) {
+ (*it)->GetWidget()->GetRootView()->NotifyNativeViewHierarchyChanged(
+ true,
host_->GetWidget()->GetNativeView());
}
}
@@ -52,13 +53,13 @@ void NativeViewHostWin::NativeViewDetaching(bool destroyed) {
if (!destroyed && installed_clip_)
UninstallClip();
installed_clip_ = false;
- // Notify children that parent is removed
- std::vector<RootView*> root_views;
- Widget::FindAllRootViews(host_->native_view(), &root_views);
- for (std::vector<RootView*>::iterator it = root_views.begin();
- it < root_views.end();
- ++it) {
- (*it)->NotifyNativeViewHierarchyChanged(false,
+ // Notify children that parent is removed.
+ NativeWidget::NativeWidgets widgets;
+ NativeWidget::GetAllNativeWidgets(host_->native_view(), &widgets);
+ for (NativeWidget::NativeWidgets::iterator it = widgets.begin();
+ it != widgets.end(); ++it) {
+ (*it)->GetWidget()->GetRootView()->NotifyNativeViewHierarchyChanged(
+ false,
host_->GetWidget()->GetNativeView());
}
}
diff --git a/views/controls/tabbed_pane/native_tabbed_pane_gtk.cc b/views/controls/tabbed_pane/native_tabbed_pane_gtk.cc
index 02d5fe6..50b62c6 100644
--- a/views/controls/tabbed_pane/native_tabbed_pane_gtk.cc
+++ b/views/controls/tabbed_pane/native_tabbed_pane_gtk.cc
@@ -64,7 +64,8 @@ View* NativeTabbedPaneGtk::RemoveTabAtIndex(int index) {
GtkWidget* page =
gtk_notebook_get_nth_page(GTK_NOTEBOOK(native_view()), index);
- WidgetGtk* widget = WidgetGtk::GetViewForNative(page);
+ 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.
@@ -194,7 +195,8 @@ WidgetGtk* NativeTabbedPaneGtk::GetWidgetAt(int index) {
DCHECK(index <= GetTabCount());
GtkWidget* page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(native_view()),
index);
- WidgetGtk* widget = WidgetGtk::GetViewForNative(page);
+ WidgetGtk* widget =
+ static_cast<WidgetGtk*>(NativeWidget::GetNativeWidgetForNativeView(page));
DCHECK(widget);
return widget;
}
diff --git a/views/focus/accelerator_handler_touch.cc b/views/focus/accelerator_handler_touch.cc
index d4b072a..389fe7d 100644
--- a/views/focus/accelerator_handler_touch.cc
+++ b/views/focus/accelerator_handler_touch.cc
@@ -31,13 +31,13 @@ RootView* FindRootViewForGdkWindow(GdkWindow* gdk_window) {
DLOG(WARNING) << "no GtkWidget found for that GdkWindow";
return NULL;
}
- WidgetGtk* widget_gtk = WidgetGtk::GetViewForNative(gtk_widget);
- if (!widget_gtk) {
+ NativeWidget* widget = NativeWidget::GetNativeWidgetForNativeView(gtk_widget);
+ if (!widget) {
DLOG(WARNING) << "no WidgetGtk found for that GtkWidget";
return NULL;
}
- return widget_gtk->GetRootView();
+ return widget->GetWidget()->GetRootView();
}
#if defined(HAVE_XINPUT2)
diff --git a/views/focus/focus_manager_gtk.cc b/views/focus/focus_manager_gtk.cc
index 6e9dbcf..327c785 100644
--- a/views/focus/focus_manager_gtk.cc
+++ b/views/focus/focus_manager_gtk.cc
@@ -28,7 +28,7 @@ FocusManager* FocusManager::GetFocusManagerForNativeView(
if (!root || !GTK_WIDGET_TOPLEVEL(root))
return NULL;
- WidgetGtk* widget = WidgetGtk::GetViewForNative(root);
+ NativeWidget* widget = NativeWidget::GetNativeWidgetForNativeView(root);
if (!widget) {
// TODO(jcampan): http://crbug.com/21378 Reenable this NOTREACHED() when the
// options page is only based on views.
@@ -36,7 +36,7 @@ FocusManager* FocusManager::GetFocusManagerForNativeView(
NOTIMPLEMENTED();
return NULL;
}
- FocusManager* focus_manager = widget->GetFocusManager();
+ FocusManager* focus_manager = widget->GetWidget()->GetFocusManager();
DCHECK(focus_manager) << "no FocusManager for top level Widget";
return focus_manager;
}
diff --git a/views/focus/focus_manager_win.cc b/views/focus/focus_manager_win.cc
index faf3815..d6f1e02 100644
--- a/views/focus/focus_manager_win.cc
+++ b/views/focus/focus_manager_win.cc
@@ -23,8 +23,10 @@ void FocusManager::FocusNativeView(gfx::NativeView native_view) {
// static
FocusManager* FocusManager::GetFocusManagerForNativeView(
gfx::NativeView native_view) {
- WidgetWin* widget = WidgetWin::GetRootWidget(native_view);
- return widget ? widget->GetFocusManager() : NULL;
+ // TODO(beng): This method probably isn't necessary.
+ views::NativeWidget* native_widget =
+ views::NativeWidget::GetTopLevelNativeWidget(native_view);
+ return native_widget ? native_widget->GetWidget()->GetFocusManager() : NULL;
}
// static
diff --git a/views/test/views_test_base.h b/views/test/views_test_base.h
index 080eca5..d66a1d8 100644
--- a/views/test/views_test_base.h
+++ b/views/test/views_test_base.h
@@ -10,6 +10,10 @@
#include "base/message_loop.h"
+#if defined(OS_WIN)
+#include <ole2.h>
+#endif
+
namespace views {
// A base class for views unit test. It creates a message loop necessary
diff --git a/views/view_unittest.cc b/views/view_unittest.cc
index 8207c76b..16109f7 100644
--- a/views/view_unittest.cc
+++ b/views/view_unittest.cc
@@ -1439,33 +1439,22 @@ class TestChangeNativeViewHierarchy {
view_test_->RunPendingMessages();
}
- void CheckEnumeratingRootViews() {
- std::vector<RootView*> enumerated_root_views;
-#if defined(OS_WIN)
- views::Widget::FindAllRootViews(host_->GetNativeView(),
- &enumerated_root_views);
-#else
- // host_->GetNativeView() returns gfx::NativeView which is GtkWidget on
- // systems other than Windows and views::Widget::FindAllRootViews()
- // requires GtkWindow.
- if (host_->GetWindow()) {
- views::Widget::FindAllRootViews(host_->GetWindow()->GetNativeWindow(),
- &enumerated_root_views);
- } else {
+ void CheckEnumeratingNativeWidgets() {
+ if (!host_->GetWindow())
return;
- }
-#endif
- EXPECT_EQ(TestNativeViewHierarchy::kTotalViews + 1,
- enumerated_root_views.size());
+ NativeWidget::NativeWidgets widgets;
+ NativeWidget::GetAllNativeWidgets(host_->GetNativeView(), &widgets);
+ EXPECT_EQ(TestNativeViewHierarchy::kTotalViews + 1, widgets.size());
// Unfortunately there is no guarantee the sequence of views here so always
// go through all of them.
- for (std::vector<RootView*>::iterator i = enumerated_root_views.begin();
- i != enumerated_root_views.end(); ++i) {
- if (host_->GetRootView() == *i)
+ for (NativeWidget::NativeWidgets::iterator i = widgets.begin();
+ i != widgets.end(); ++i) {
+ RootView* root_view = (*i)->GetWidget()->GetRootView();
+ if (host_->GetRootView() == root_view)
continue;
size_t j;
for (j = 0; j < TestNativeViewHierarchy::kTotalViews; ++j)
- if (root_views_[j] == *i)
+ if (root_views_[j] == root_view)
break;
// EXPECT_LT/GT/GE() fails to compile with class-defined constants
// with gcc, with error
@@ -1509,7 +1498,7 @@ TEST_F(ViewTest, ChangeNativeViewHierarchyFindRoots) {
// TODO(georgey): Fix the test for Linux
#if defined(OS_WIN)
TestChangeNativeViewHierarchy test(this);
- test.CheckEnumeratingRootViews();
+ test.CheckEnumeratingNativeWidgets();
#endif
}
diff --git a/views/views.gyp b/views/views.gyp
index f81e669..a8c1fa3 100644
--- a/views/views.gyp
+++ b/views/views.gyp
@@ -489,6 +489,10 @@
'run_all_unittests.cc',
'test/test_views_delegate.h',
'view_unittest.cc',
+ 'widget/native_widget_test_utils.h',
+ 'widget/native_widget_test_utils_gtk.cc',
+ 'widget/native_widget_test_utils_win.cc',
+ 'widget/native_widget_unittest.cc',
'widget/widget_win_unittest.cc',
'window/window_win_unittest.cc',
diff --git a/views/widget/native_widget.h b/views/widget/native_widget.h
index 2700f8c..dffbf93 100644
--- a/views/widget/native_widget.h
+++ b/views/widget/native_widget.h
@@ -6,8 +6,11 @@
#define VIEWS_WIDGET_NATIVE_WIDGET_H_
#pragma once
+#include <set>
+
namespace views {
-namespace internal {
+
+class Widget;
////////////////////////////////////////////////////////////////////////////////
// NativeWidget interface
@@ -18,9 +21,30 @@ namespace internal {
class NativeWidget {
public:
virtual ~NativeWidget() {}
+
+ // Retrieves the NativeWidget implementation associated with the given
+ // NativeView or Window, or NULL if the supplied handle has no associated
+ // NativeView.
+ static NativeWidget* GetNativeWidgetForNativeView(
+ gfx::NativeView native_view);
+ static NativeWidget* GetNativeWidgetForNativeWindow(
+ gfx::NativeWindow native_window);
+
+ // Retrieves the top NativeWidget in the hierarchy containing the given
+ // NativeView, or NULL if there is no NativeWidget that contains it.
+ static NativeWidget* GetTopLevelNativeWidget(gfx::NativeView native_view);
+
+ // Returns all NativeWidgets in |native_view|'s hierarchy, including itself if
+ // it is one.
+ typedef std::set<NativeWidget*> NativeWidgets;
+ static void GetAllNativeWidgets(gfx::NativeView native_view,
+ NativeWidgets* children);
+
+ // 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;
};
-} // namespace internal
} // namespace views
#endif // VIEWS_WIDGET_NATIVE_WIDGET_H_
diff --git a/views/widget/native_widget_test_utils.h b/views/widget/native_widget_test_utils.h
new file mode 100644
index 0000000..ac3e5b4
--- /dev/null
+++ b/views/widget/native_widget_test_utils.h
@@ -0,0 +1,22 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef VIEWS_WIDGET_NATIVE_WIDGET_TEST_UTILS_H_
+#define VIEWS_WIDGET_NATIVE_WIDGET_TEST_UTILS_H_
+#pragma once
+
+namespace views {
+class View;
+class NativeWidget;
+namespace internal {
+
+// Create dummy Widgets for use in testing.
+NativeWidget* CreateNativeWidget();
+NativeWidget* CreateNativeWidgetWithContents(View* contents_view);
+NativeWidget* CreateNativeWidgetWithParent(NativeWidget* parent);
+
+} // namespace internal
+} // namespace views
+
+#endif // VIEWS_WIDGET_NATIVE_WIDGET_TEST_UTILS_H_
diff --git a/views/widget/native_widget_test_utils_gtk.cc b/views/widget/native_widget_test_utils_gtk.cc
new file mode 100644
index 0000000..43c0279
--- /dev/null
+++ b/views/widget/native_widget_test_utils_gtk.cc
@@ -0,0 +1,33 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "views/widget/native_widget_test_utils.h"
+
+#include "views/view.h"
+#include "views/widget/widget_gtk.h"
+
+namespace views {
+namespace internal {
+
+NativeWidget* CreateNativeWidget() {
+ return CreateNativeWidgetWithContents(new View);
+}
+
+NativeWidget* CreateNativeWidgetWithContents(View* contents_view) {
+ WidgetGtk* widget = new WidgetGtk(WidgetGtk::TYPE_WINDOW);
+ widget->set_delete_on_destroy(false);
+ widget->Init(NULL, gfx::Rect(10, 10, 200, 200));
+ return widget;
+}
+
+NativeWidget* CreateNativeWidgetWithParent(NativeWidget* parent) {
+ WidgetGtk* widget = new WidgetGtk(WidgetGtk::TYPE_CHILD);
+ widget->set_delete_on_destroy(false);
+ widget->Init(parent ? parent->GetWidget()->GetNativeView() : NULL,
+ gfx::Rect(10, 10, 200, 200));
+ return widget;
+}
+
+} // namespace internal
+} // namespace ui
diff --git a/views/widget/native_widget_test_utils_win.cc b/views/widget/native_widget_test_utils_win.cc
new file mode 100644
index 0000000..2d016e9
--- /dev/null
+++ b/views/widget/native_widget_test_utils_win.cc
@@ -0,0 +1,33 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "views/widget/native_widget_test_utils.h"
+
+#include "views/view.h"
+#include "views/widget/widget_win.h"
+
+namespace views {
+namespace internal {
+
+NativeWidget* CreateNativeWidget() {
+ return CreateNativeWidgetWithContents(new View);
+}
+
+NativeWidget* CreateNativeWidgetWithContents(View* contents_view) {
+ WidgetWin* widget = new WidgetWin;
+ widget->set_delete_on_destroy(false);
+ widget->Init(NULL, gfx::Rect(10, 10, 200, 200));
+ return widget;
+}
+
+NativeWidget* CreateNativeWidgetWithParent(NativeWidget* parent) {
+ WidgetWin* widget = new WidgetWin;
+ widget->set_delete_on_destroy(false);
+ widget->Init(parent ? parent->GetWidget()->GetNativeView() : NULL,
+ gfx::Rect(10, 10, 200, 200));
+ return widget;
+}
+
+} // namespace internal
+} // namespace ui
diff --git a/views/widget/native_widget_unittest.cc b/views/widget/native_widget_unittest.cc
new file mode 100644
index 0000000..91c29a3
--- /dev/null
+++ b/views/widget/native_widget_unittest.cc
@@ -0,0 +1,81 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "testing/gtest/include/gtest/gtest.h"
+#include "views/test/views_test_base.h"
+#include "views/view.h"
+#include "views/controls/native/native_view_host.h"
+#include "views/widget/native_widget.h"
+#include "views/widget/widget.h"
+#include "views/widget/native_widget_test_utils.h"
+
+#if defined(TOOLKIT_USES_GTK)
+#include "views/widget/widget_gtk.h"
+#endif
+
+namespace views {
+
+class ScopedTestWidget {
+ public:
+ ScopedTestWidget(NativeWidget* native_widget)
+ : native_widget_(native_widget) {
+ }
+ ~ScopedTestWidget() {
+ native_widget_->GetWidget()->CloseNow();
+ }
+
+ NativeWidget* operator->() const {
+ return native_widget_.get();
+ }
+ NativeWidget* get() const { return native_widget_.get(); }
+
+ private:
+ scoped_ptr<NativeWidget> native_widget_;
+ DISALLOW_COPY_AND_ASSIGN(ScopedTestWidget);
+};
+
+class NativeWidgetTest : public ViewsTestBase {
+ public:
+ NativeWidgetTest() {}
+ virtual ~NativeWidgetTest() {}
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(NativeWidgetTest);
+};
+
+TEST_F(NativeWidgetTest, CreateNativeWidget) {
+ ScopedTestWidget widget(internal::CreateNativeWidget());
+ EXPECT_TRUE(widget->GetWidget()->GetNativeView() != NULL);
+}
+
+TEST_F(NativeWidgetTest, GetNativeWidgetForNativeView) {
+ ScopedTestWidget widget(internal::CreateNativeWidget());
+ EXPECT_EQ(widget.get(),
+ NativeWidget::GetNativeWidgetForNativeView(
+ widget->GetWidget()->GetNativeView()));
+}
+
+// |widget| has the toplevel NativeWidget.
+TEST_F(NativeWidgetTest, GetTopLevelNativeWidget1) {
+ ScopedTestWidget widget(internal::CreateNativeWidget());
+ EXPECT_EQ(widget.get(),
+ NativeWidget::GetTopLevelNativeWidget(
+ widget->GetWidget()->GetNativeView()));
+}
+
+// |toplevel_widget| has the toplevel NativeWidget.
+TEST_F(NativeWidgetTest, GetTopLevelNativeWidget2) {
+ ScopedTestWidget child_widget(internal::CreateNativeWidgetWithParent(NULL));
+ ScopedTestWidget toplevel_widget(internal::CreateNativeWidget());
+
+ NativeViewHost* child_host = new NativeViewHost;
+ toplevel_widget->GetWidget()->SetContentsView(child_host);
+ child_host->Attach(child_widget->GetWidget()->GetNativeView());
+
+ EXPECT_EQ(toplevel_widget.get(),
+ NativeWidget::GetTopLevelNativeWidget(
+ child_widget->GetWidget()->GetNativeView()));
+}
+
+} // namespace views
diff --git a/views/widget/widget.cc b/views/widget/widget.cc
index 0299c2d..c280206 100644
--- a/views/widget/widget.cc
+++ b/views/widget/widget.cc
@@ -7,6 +7,7 @@
#include "base/logging.h"
#include "views/widget/default_theme_provider.h"
#include "views/widget/root_view.h"
+#include "views/widget/native_widget.h"
namespace views {
@@ -28,6 +29,17 @@ void Widget::Init(gfx::NativeView parent, const gfx::Rect& bounds) {
void Widget::InitWithWidget(Widget* parent, const gfx::Rect& bounds) {
}
+Widget* Widget::GetTopLevelWidget() {
+ return const_cast<Widget*>(
+ const_cast<const Widget*>(this)->GetTopLevelWidget());
+}
+
+const Widget* Widget::GetTopLevelWidget() const {
+ NativeWidget* native_widget =
+ NativeWidget::GetTopLevelNativeWidget(GetNativeView());
+ return native_widget ? native_widget->GetWidget() : NULL;
+}
+
WidgetDelegate* Widget::GetWidgetDelegate() {
return delegate_;
}
@@ -82,10 +94,6 @@ RootView* Widget::GetRootView() {
return root_view_.get();
}
-Widget* Widget::GetRootWidget() const {
- return NULL;
-}
-
bool Widget::IsVisible() const {
return false;
}
diff --git a/views/widget/widget.h b/views/widget/widget.h
index 89e9061..b1860d1 100644
--- a/views/widget/widget.h
+++ b/views/widget/widget.h
@@ -29,16 +29,13 @@ using ui::ThemeProvider;
namespace views {
class DefaultThemeProvider;
+class NativeWidget;
class RootView;
class TooltipManager;
class View;
class WidgetDelegate;
class Window;
-namespace internal {
-class NativeWidget;
-}
-
////////////////////////////////////////////////////////////////////////////////
// Widget class
//
@@ -91,21 +88,6 @@ class Widget : public internal::NativeWidgetDelegate,
DeleteParam delete_on_destroy,
MirroringParam mirror_in_rtl);
- // Returns the root view for |native_window|. If |native_window| does not have
- // a rootview, this recurses through all of |native_window|'s children until
- // one is found. If a root view isn't found, null is returned.
- static RootView* FindRootView(gfx::NativeWindow native_window);
-
- // Returns list of all root views for the native window and its
- // children.
- static void FindAllRootViews(gfx::NativeWindow native_window,
- std::vector<RootView*>* root_views);
-
- // Retrieve the Widget corresponding to the specified native_view, or NULL
- // if there is no such Widget.
- static Widget* GetWidgetFromNativeView(gfx::NativeView native_view);
- static Widget* GetWidgetFromNativeWindow(gfx::NativeWindow native_window);
-
// Enumerates all windows pertaining to us and notifies their
// view hierarchies that the locale has changed.
static void NotifyLocaleChanged();
@@ -128,6 +110,11 @@ class Widget : public internal::NativeWidgetDelegate,
// |parent| is same as invoking |Init(NULL, bounds)|.
virtual void InitWithWidget(Widget* parent, const gfx::Rect& bounds);
+ // Returns the topmost Widget in a hierarchy. Will return NULL if called
+ // before the underlying Native Widget has been initialized.
+ Widget* GetTopLevelWidget();
+ const Widget* GetTopLevelWidget() const;
+
// Returns the WidgetDelegate for delegating certain events.
virtual WidgetDelegate* GetWidgetDelegate();
@@ -183,9 +170,6 @@ class Widget : public internal::NativeWidgetDelegate,
// Returns the RootView contained by this Widget.
virtual RootView* GetRootView();
- // Returns the Widget associated with the root ancestor.
- virtual Widget* GetRootWidget() const;
-
// Returns whether the Widget is visible to the user.
virtual bool IsVisible() const;
@@ -280,7 +264,7 @@ class Widget : public internal::NativeWidgetDelegate,
// TODO(beng): Temporarily provided as a way to associate the subclass'
// implementation of NativeWidget with this.
- void set_native_widget(internal::NativeWidget* native_widget) {
+ void set_native_widget(NativeWidget* native_widget) {
native_widget_ = native_widget;
}
@@ -290,7 +274,7 @@ class Widget : public internal::NativeWidgetDelegate,
virtual View* GetFocusTraversableParentView();
private:
- internal::NativeWidget* native_widget_;
+ NativeWidget* native_widget_;
// Non-owned pointer to the Widget's delegate. May be NULL if no delegate is
// being used.
diff --git a/views/widget/widget_gtk.cc b/views/widget/widget_gtk.cc
index 0eca3d7..cb9eddf 100644
--- a/views/widget/widget_gtk.cc
+++ b/views/widget/widget_gtk.cc
@@ -44,10 +44,12 @@ using ui::OSExchangeData;
using ui::OSExchangeDataProviderGtk;
using ui::ActiveWindowWatcherX;
+namespace views {
+
namespace {
-// g_object data keys to associate a WidgetGtk object to a GtkWidget.
-const char* kWidgetKey = "__VIEWS_WIDGET__";
+// Links the GtkWidget to its NativeWidget.
+const char* const kNativeWidgetKey = "__VIEWS_NATIVE_WIDGET__";
// A g_object data key to associate a CompositePainter object to a GtkWidget.
const char* kCompositePainterKey = "__VIEWS_COMPOSITE_PAINTER__";
// A g_object data key to associate the flag whether or not the widget
@@ -134,9 +136,25 @@ class CompositePainter {
DISALLOW_COPY_AND_ASSIGN(CompositePainter);
};
-} // namespace
+void EnumerateChildWidgetsForNativeWidgets(GtkWidget* child_widget,
+ gpointer param) {
+ // Walk child widgets, if necessary.
+ if (GTK_IS_CONTAINER(child_widget)) {
+ gtk_container_foreach(GTK_CONTAINER(child_widget),
+ EnumerateChildWidgetsForNativeWidgets,
+ param);
+ }
-namespace views {
+ NativeWidget* native_widget =
+ NativeWidget::GetNativeWidgetForNativeView(child_widget);
+ if (native_widget) {
+ NativeWidget::NativeWidgets* widgets =
+ reinterpret_cast<NativeWidget::NativeWidgets*>(param);
+ widgets->insert(native_widget);
+ }
+}
+
+} // namespace
// During drag and drop GTK sends a drag-leave during a drop. This means we
// have no way to tell the difference between a normal drag leave and a drop.
@@ -167,7 +185,8 @@ class WidgetGtk::DropObserver : public MessageLoopForUI::Observer {
if (!gtk_widget)
return NULL;
- return WidgetGtk::GetViewForNative(gtk_widget);
+ return static_cast<WidgetGtk*>(
+ NativeWidget::GetNativeWidgetForNativeView(gtk_widget));
}
DISALLOW_COPY_AND_ASSIGN(DropObserver);
@@ -421,22 +440,11 @@ void WidgetGtk::IsActiveChanged() {
GetWidgetDelegate()->IsActiveChanged(IsActive());
}
-// static
-WidgetGtk* WidgetGtk::GetViewForNative(GtkWidget* widget) {
- return static_cast<WidgetGtk*>(GetWidgetFromNativeView(widget));
-}
-
void WidgetGtk::ResetDropTarget() {
ignore_drag_leave_ = false;
drop_target_.reset(NULL);
}
-// static
-RootView* WidgetGtk::GetRootViewForWidget(GtkWidget* widget) {
- gpointer user_data = g_object_get_data(G_OBJECT(widget), "root-view");
- return static_cast<RootView*>(user_data);
-}
-
void WidgetGtk::GetRequestedSize(gfx::Size* out) const {
int width, height;
if (GTK_IS_VIEWS_FIXED(widget_) &&
@@ -517,7 +525,6 @@ void WidgetGtk::Init(GtkWidget* parent,
GDK_POINTER_MOTION_MASK |
GDK_KEY_PRESS_MASK |
GDK_KEY_RELEASE_MASK);
- SetRootViewForWidget(widget_, GetRootView());
g_signal_connect_after(G_OBJECT(window_contents_), "size_request",
G_CALLBACK(&OnSizeRequestThunk), this);
@@ -630,7 +637,8 @@ void WidgetGtk::SetBounds(const gfx::Rect& bounds) {
if (type_ == TYPE_CHILD) {
GtkWidget* parent = gtk_widget_get_parent(widget_);
if (GTK_IS_VIEWS_FIXED(parent)) {
- WidgetGtk* parent_widget = GetViewForNative(parent);
+ WidgetGtk* parent_widget = static_cast<WidgetGtk*>(
+ NativeWidget::GetNativeWidgetForNativeView(parent));
parent_widget->PositionChild(widget_, bounds.x(), bounds.y(),
bounds.width(), bounds.height());
} else {
@@ -735,16 +743,6 @@ void WidgetGtk::SetAlwaysOnTop(bool on_top) {
gtk_window_set_keep_above(GTK_WINDOW(widget_), on_top);
}
-Widget* WidgetGtk::GetRootWidget() const {
- GtkWidget* parent = widget_;
- GtkWidget* last_parent = parent;
- while (parent) {
- last_parent = parent;
- parent = gtk_widget_get_parent(parent);
- }
- return last_parent ? GetViewForNative(last_parent) : NULL;
-}
-
bool WidgetGtk::IsVisible() const {
return GTK_WIDGET_VISIBLE(widget_);
}
@@ -796,11 +794,11 @@ FocusManager* WidgetGtk::GetFocusManager() {
if (focus_manager_)
return focus_manager_;
- Widget* root = GetRootWidget();
- if (root && root != this) {
- // Widget subclasses may override GetFocusManager(), for example for
+ NativeWidget* native_widget = GetTopLevelNativeWidget(GetNativeView());
+ if (native_widget && native_widget != this) {
+ // WidgetGtk subclasses may override GetFocusManager(), for example for
// dealing with cases where the widget has been unparented.
- return root->GetFocusManager();
+ return native_widget->GetWidget()->GetFocusManager();
}
return NULL;
}
@@ -936,6 +934,13 @@ void WidgetGtk::EnableDebugPaint() {
}
////////////////////////////////////////////////////////////////////////////////
+// WidgetGtk, NativeWidget implementation:
+
+Widget* WidgetGtk::GetWidget() {
+ return this;
+}
+
+////////////////////////////////////////////////////////////////////////////////
// WidgetGtk, protected:
void WidgetGtk::OnSizeRequest(GtkWidget* widget, GtkRequisition* requisition) {
@@ -1373,15 +1378,11 @@ bool WidgetGtk::ProcessScroll(GdkEventScroll* event) {
}
// static
-void WidgetGtk::SetRootViewForWidget(GtkWidget* widget, RootView* root_view) {
- g_object_set_data(G_OBJECT(widget), "root-view", root_view);
-}
-
-// static
Window* WidgetGtk::GetWindowImpl(GtkWidget* widget) {
GtkWidget* parent = widget;
while (parent) {
- WidgetGtk* widget_gtk = GetViewForNative(parent);
+ WidgetGtk* widget_gtk = static_cast<WidgetGtk*>(
+ NativeWidget::GetNativeWidgetForNativeView(parent));
if (widget_gtk && widget_gtk->is_window_)
return static_cast<WindowGtk*>(widget_gtk);
parent = gtk_widget_get_parent(parent);
@@ -1478,7 +1479,7 @@ void WidgetGtk::CreateGtkWidget(GtkWidget* parent, const gfx::Rect& bounds) {
gtk_fixed_set_has_window(GTK_FIXED(window_contents_), true);
gtk_container_add(GTK_CONTAINER(widget_), window_contents_);
gtk_widget_show(window_contents_);
- g_object_set_data(G_OBJECT(window_contents_), kWidgetKey,
+ g_object_set_data(G_OBJECT(window_contents_), kNativeWidgetKey,
static_cast<Widget*>(this));
if (transparent_)
@@ -1492,9 +1493,7 @@ void WidgetGtk::CreateGtkWidget(GtkWidget* parent, const gfx::Rect& bounds) {
// function properly.
gtk_widget_realize(widget_);
}
- // Setting the WidgetKey property to widget_, which is used by
- // GetWidgetFromNativeWindow.
- SetNativeWindowProperty(kWidgetKey, this);
+ SetNativeWindowProperty(kNativeWidgetKey, this);
}
void WidgetGtk::ConfigureWidgetForTransparentBackground(GtkWidget* parent) {
@@ -1573,95 +1572,71 @@ Widget* Widget::CreatePopupWidget(TransparencyParam transparent,
return popup;
}
-// Callback from gtk_container_foreach. Locates the first root view of widget
-// or one of it's descendants.
-static void RootViewLocatorCallback(GtkWidget* widget,
- gpointer root_view_p) {
- RootView** root_view = static_cast<RootView**>(root_view_p);
- if (!*root_view) {
- *root_view = WidgetGtk::GetRootViewForWidget(widget);
- if (!*root_view && GTK_IS_CONTAINER(widget)) {
- // gtk_container_foreach only iterates over children, not all descendants,
- // so we have to recurse here to get all descendants.
- gtk_container_foreach(GTK_CONTAINER(widget), RootViewLocatorCallback,
- root_view_p);
- }
- }
-}
-
// static
-RootView* Widget::FindRootView(GtkWindow* window) {
- RootView* root_view = WidgetGtk::GetRootViewForWidget(GTK_WIDGET(window));
- if (root_view)
- return root_view;
-
- // Enumerate all children and check if they have a RootView.
- gtk_container_foreach(GTK_CONTAINER(window), RootViewLocatorCallback,
- static_cast<gpointer>(&root_view));
- return root_view;
-}
-
-static void AllRootViewsLocatorCallback(GtkWidget* widget,
- gpointer root_view_p) {
- std::set<RootView*>* root_views_set =
- reinterpret_cast<std::set<RootView*>*>(root_view_p);
- RootView *root_view = WidgetGtk::GetRootViewForWidget(widget);
- if (!root_view && GTK_IS_CONTAINER(widget)) {
- // gtk_container_foreach only iterates over children, not all descendants,
- // so we have to recurse here to get all descendants.
- gtk_container_foreach(GTK_CONTAINER(widget), AllRootViewsLocatorCallback,
- root_view_p);
- } else {
- if (root_view)
- root_views_set->insert(root_view);
+void Widget::NotifyLocaleChanged() {
+ GList *window_list = gtk_window_list_toplevels();
+ for (GList* element = window_list; element; element = g_list_next(element)) {
+ NativeWidget* widget =
+ NativeWidget::GetNativeWidgetForNativeWindow(GTK_WINDOW(element->data));
+ if (widget)
+ widget->GetWidget()->LocaleChanged();
}
+ g_list_free(window_list);
}
-// static
-void Widget::FindAllRootViews(GtkWindow* window,
- std::vector<RootView*>* root_views) {
- RootView* root_view = WidgetGtk::GetRootViewForWidget(GTK_WIDGET(window));
- if (root_view)
- root_views->push_back(root_view);
-
- std::set<RootView*> root_views_set;
+////////////////////////////////////////////////////////////////////////////////
+// NativeWidget, public:
- // Enumerate all children and check if they have a RootView.
- gtk_container_foreach(GTK_CONTAINER(window), AllRootViewsLocatorCallback,
- reinterpret_cast<gpointer>(&root_views_set));
- root_views->clear();
- root_views->reserve(root_views_set.size());
- for (std::set<RootView*>::iterator it = root_views_set.begin();
- it != root_views_set.end();
- ++it)
- root_views->push_back(*it);
+// static
+NativeWidget* NativeWidget::GetNativeWidgetForNativeView(
+ gfx::NativeView native_view) {
+ if (!native_view)
+ return NULL;
+ return reinterpret_cast<WidgetGtk*>(
+ g_object_get_data(G_OBJECT(native_view), kNativeWidgetKey));
}
// static
-Widget* Widget::GetWidgetFromNativeView(gfx::NativeView native_view) {
- gpointer raw_widget = g_object_get_data(G_OBJECT(native_view), kWidgetKey);
- if (raw_widget)
- return reinterpret_cast<Widget*>(raw_widget);
- return NULL;
+NativeWidget* NativeWidget::GetNativeWidgetForNativeWindow(
+ gfx::NativeWindow native_window) {
+ if (!native_window)
+ return NULL;
+ return reinterpret_cast<WidgetGtk*>(
+ g_object_get_data(G_OBJECT(native_window), kNativeWidgetKey));
}
// static
-Widget* Widget::GetWidgetFromNativeWindow(gfx::NativeWindow native_window) {
- gpointer raw_widget = g_object_get_data(G_OBJECT(native_window), kWidgetKey);
- if (raw_widget)
- return reinterpret_cast<Widget*>(raw_widget);
- return NULL;
+NativeWidget* NativeWidget::GetTopLevelNativeWidget(
+ gfx::NativeView native_view) {
+ if (!native_view)
+ return NULL;
+
+ NativeWidget* widget = NULL;
+
+ GtkWidget* parent_gtkwidget = native_view;
+ NativeWidget* parent_widget;
+ do {
+ parent_widget = GetNativeWidgetForNativeView(parent_gtkwidget);
+ if (parent_widget)
+ widget = parent_widget;
+ parent_gtkwidget = gtk_widget_get_parent(parent_gtkwidget);
+ } while (parent_gtkwidget);
+
+ return widget;
}
// static
-void Widget::NotifyLocaleChanged() {
- GList *window_list = gtk_window_list_toplevels();
- for (GList* element = window_list; element; element = g_list_next(element)) {
- Widget* widget = GetWidgetFromNativeWindow(GTK_WINDOW(element->data));
- if (widget)
- widget->LocaleChanged();
- }
- g_list_free(window_list);
+void NativeWidget::GetAllNativeWidgets(gfx::NativeView native_view,
+ NativeWidgets* children) {
+ if (!native_view)
+ return;
+
+ NativeWidget* native_widget = GetNativeWidgetForNativeView(native_view);
+ if (native_widget)
+ children->insert(native_widget);
+ gtk_container_foreach(GTK_CONTAINER(native_view),
+ EnumerateChildWidgetsForNativeWidgets,
+ reinterpret_cast<gpointer>(children));
}
} // namespace views
diff --git a/views/widget/widget_gtk.h b/views/widget/widget_gtk.h
index 8c0cacd..91b8024 100644
--- a/views/widget/widget_gtk.h
+++ b/views/widget/widget_gtk.h
@@ -40,7 +40,7 @@ class NativeWidgetDelegate;
// Widget implementation for GTK.
class WidgetGtk : public Widget,
- public internal::NativeWidget,
+ public NativeWidget,
public ui::ActiveWindowWatcherX::Observer {
public:
// Type of widget.
@@ -137,16 +137,10 @@ class WidgetGtk : public Widget,
// gets created. This will not be called on a TYPE_CHILD widget.
virtual void SetInitialFocus() {}
- // Gets the WidgetGtk in the userdata section of the widget.
- static WidgetGtk* GetViewForNative(GtkWidget* widget);
-
// Sets the drop target to NULL. This is invoked by DropTargetGTK when the
// drop is done.
void ResetDropTarget();
- // Returns the RootView for |widget|.
- static RootView* GetRootViewForWidget(GtkWidget* widget);
-
// Gets the requested size of the widget. This can be the size
// stored in properties for a GtkViewsFixed, or in the requisitioned
// size of other kinds of widgets.
@@ -169,7 +163,6 @@ class WidgetGtk : public Widget,
virtual gfx::NativeView GetNativeView() const;
virtual void SetOpacity(unsigned char opacity);
virtual void SetAlwaysOnTop(bool on_top);
- virtual Widget* GetRootWidget() const;
virtual bool IsVisible() const;
virtual bool IsActive() const;
virtual bool IsAccessibleWidget() const;
@@ -207,6 +200,9 @@ class WidgetGtk : public Widget,
static void EnableDebugPaint();
protected:
+ // Overridden from NativeWidget:
+ virtual Widget* GetWidget();
+
// If widget contains another widget, translates event coordinates to the
// contained widget's coordinates, else returns original event coordinates.
template<class Event> bool GetContainedWidgetEventCoordinates(Event* event,
@@ -306,8 +302,6 @@ class WidgetGtk : public Widget,
// Process scroll event.
bool ProcessScroll(GdkEventScroll* event);
- static void SetRootViewForWidget(GtkWidget* widget, RootView* root_view);
-
// Returns the first ancestor of |widget| that is a window.
static Window* GetWindowImpl(GtkWidget* widget);
diff --git a/views/widget/widget_utils.cc b/views/widget/widget_utils.cc
index 70b946d..d63a00c 100644
--- a/views/widget/widget_utils.cc
+++ b/views/widget/widget_utils.cc
@@ -11,7 +11,7 @@
namespace views {
ThemeProvider* GetWidgetThemeProvider(const Widget* widget) {
- Widget* root_widget = widget->GetRootWidget();
+ const Widget* root_widget = widget->GetTopLevelWidget();
if (root_widget && root_widget != widget) {
// Attempt to get the theme provider, and fall back to the default theme
// provider if not found.
diff --git a/views/widget/widget_win.cc b/views/widget/widget_win.cc
index 8cde70f..817ca77 100644
--- a/views/widget/widget_win.cc
+++ b/views/widget/widget_win.cc
@@ -94,32 +94,22 @@ bool ProcessChildWindowMessage(UINT message,
return false;
}
-BOOL CALLBACK EnumChildProc(HWND hwnd, LPARAM l_param) {
- RootView* root_view = GetRootViewForHWND(hwnd);
- if (root_view) {
- *reinterpret_cast<RootView**>(l_param) = root_view;
- return FALSE; // Stop enumerating.
+// Enumeration callback for NativeWidget::GetAllNativeWidgets(). Called for each
+// child HWND beneath the original HWND.
+BOOL CALLBACK EnumerateChildWindowsForNativeWidgets(HWND hwnd, LPARAM l_param) {
+ NativeWidget* native_widget =
+ NativeWidget::GetNativeWidgetForNativeView(hwnd);
+ if (native_widget) {
+ NativeWidget::NativeWidgets* native_widgets =
+ reinterpret_cast<NativeWidget::NativeWidgets*>(l_param);
+ native_widgets->insert(native_widget);
}
- return TRUE; // Keep enumerating.
-}
-// Enumerate child windows as they could have RootView distinct from
-// the HWND's root view.
-BOOL CALLBACK EnumAllRootViewsChildProc(HWND hwnd, LPARAM l_param) {
- RootView* root_view = GetRootViewForHWND(hwnd);
- if (root_view) {
- std::set<RootView*>* root_views_set =
- reinterpret_cast<std::set<RootView*>*>(l_param);
- root_views_set->insert(root_view);
- }
- return TRUE; // Keep enumerating.
+ return TRUE;
}
-// Property used to link the HWND to its RootView.
-const char* const kRootViewWindowProperty = "__ROOT_VIEW__";
-
-// Links the HWND to it's Widget (as a Widget, not a WidgetWin).
-const char* const kWidgetKey = "__VIEWS_WIDGET__";
+// Links the HWND to its NativeWidget.
+const char* const kNativeWidgetKey = "__VIEWS_NATIVE_WIDGET__";
// A custom MSAA object id used to determine if a screen reader is actively
// listening for MSAA events.
@@ -130,11 +120,6 @@ const int kCustomObjectID = 1;
// static
bool WidgetWin::screen_reader_active_ = false;
-RootView* GetRootViewForHWND(HWND hwnd) {
- return reinterpret_cast<RootView*>(
- ViewProp::GetValue(hwnd, kRootViewWindowProperty));
-}
-
////////////////////////////////////////////////////////////////////////////////
// WidgetWin, public:
@@ -160,41 +145,7 @@ WidgetWin::WidgetWin()
WidgetWin::~WidgetWin() {
DestroyRootView();
-}
-
-// static
-WidgetWin* WidgetWin::GetWidget(HWND hwnd) {
- // TODO(jcivelli): http://crbug.com/44499 We need a way to test that hwnd is
- // associated with a WidgetWin (it might be a pure
- // WindowImpl).
- if (!WindowImpl::IsWindowImpl(hwnd))
- return NULL;
- return reinterpret_cast<WidgetWin*>(ui::GetWindowUserData(hwnd));
-}
-
-// static
-WidgetWin* WidgetWin::GetRootWidget(HWND hwnd) {
- // First, check if the top-level window is a Widget.
- HWND root = ::GetAncestor(hwnd, GA_ROOT);
- if (!root)
- return NULL;
-
- WidgetWin* widget = WidgetWin::GetWidget(root);
- if (widget)
- return widget;
-
- // Second, try to locate the last Widget window in the parent hierarchy.
- HWND parent_hwnd = hwnd;
- WidgetWin* parent_widget;
- do {
- parent_widget = WidgetWin::GetWidget(parent_hwnd);
- if (parent_widget) {
- widget = parent_widget;
- parent_hwnd = ::GetAncestor(parent_hwnd, GA_PARENT);
- }
- } while (parent_hwnd != NULL && parent_widget != NULL);
-
- return widget;
+ CloseNow();
}
// static
@@ -252,8 +203,7 @@ void WidgetWin::Init(gfx::NativeView parent, const gfx::Rect& bounds) {
drop_target_ = new DropTargetWin(GetRootView());
if ((window_style() & WS_CHILD) == 0 ||
- (WidgetWin::GetRootWidget(parent) == NULL &&
- parent != GetDesktopWindow())) {
+ (!GetTopLevelNativeWidget(parent) && parent != GetDesktopWindow())) {
// Top-level widgets and child widgets who do not have a top-level widget
// ancestor get a FocusManager. Child widgets parented to the desktop do not
// get a FocusManager because parenting to the desktop is the technique used
@@ -261,9 +211,6 @@ void WidgetWin::Init(gfx::NativeView parent, const gfx::Rect& bounds) {
focus_manager_.reset(new FocusManager(this));
}
- // Sets the RootView as a property, so the automation can introspect windows.
- SetNativeWindowProperty(kRootViewWindowProperty, 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
// WM_PAINT messages are starved and we get flickery redrawing when resizing
@@ -388,10 +335,6 @@ void WidgetWin::SetAlwaysOnTop(bool on_top) {
set_window_ex_style(window_ex_style() & ~WS_EX_TOPMOST);
}
-Widget* WidgetWin::GetRootWidget() const {
- return GetRootWidget(hwnd());
-}
-
bool WidgetWin::IsVisible() const {
return !!::IsWindowVisible(hwnd());
}
@@ -453,11 +396,11 @@ FocusManager* WidgetWin::GetFocusManager() {
if (focus_manager_.get())
return focus_manager_.get();
- WidgetWin* widget = static_cast<WidgetWin*>(GetRootWidget());
- if (widget && widget != this) {
+ NativeWidget* native_widget = GetTopLevelNativeWidget(hwnd());
+ if (native_widget && native_widget != this) {
// WidgetWin subclasses may override GetFocusManager(), for example for
// dealing with cases where the widget has been unparented.
- return widget->GetFocusManager();
+ return native_widget->GetWidget()->GetFocusManager();
}
return NULL;
}
@@ -548,6 +491,13 @@ void WidgetWin::SetCursor(gfx::NativeCursor cursor) {
}
////////////////////////////////////////////////////////////////////////////////
+// WidgetWin, NativeWidget implementation:
+
+Widget* WidgetWin::GetWidget() {
+ return this;
+}
+
+////////////////////////////////////////////////////////////////////////////////
// WidgetWin, MessageLoop::Observer implementation:
void WidgetWin::WillProcessMessage(const MSG& msg) {
@@ -632,9 +582,7 @@ void WidgetWin::OnCommand(UINT notification_code, int command_id, HWND window) {
}
LRESULT WidgetWin::OnCreate(CREATESTRUCT* create_struct) {
- // Widget::GetWidgetFromNativeView expects the contents of this property
- // to be of type Widget, so the cast is necessary.
- SetNativeWindowProperty(kWidgetKey, static_cast<Widget*>(this));
+ SetNativeWindowProperty(kNativeWidgetKey, this);
use_layered_buffer_ = !!(window_ex_style() & WS_EX_LAYERED);
LayoutRootView();
return 0;
@@ -1293,50 +1241,68 @@ Widget* Widget::CreatePopupWidget(TransparencyParam transparent,
}
// static
-RootView* Widget::FindRootView(HWND hwnd) {
- RootView* root_view = GetRootViewForHWND(hwnd);
- if (root_view)
- return root_view;
-
- // Enumerate all children and check if they have a RootView.
- EnumChildWindows(hwnd, EnumChildProc, reinterpret_cast<LPARAM>(&root_view));
-
- return root_view;
+void Widget::NotifyLocaleChanged() {
+ NOTIMPLEMENTED();
}
+////////////////////////////////////////////////////////////////////////////////
+// NativeWidget, public:
+
// static
-void Widget::FindAllRootViews(HWND window,
- std::vector<RootView*>* root_views) {
- RootView* root_view = GetRootViewForHWND(window);
- std::set<RootView*> root_views_set;
- if (root_view)
- root_views_set.insert(root_view);
- // Enumerate all children and check if they have a RootView.
- EnumChildWindows(window, EnumAllRootViewsChildProc,
- reinterpret_cast<LPARAM>(&root_views_set));
- root_views->clear();
- root_views->reserve(root_views_set.size());
- for (std::set<RootView*>::iterator it = root_views_set.begin();
- it != root_views_set.end();
- ++it)
- root_views->push_back(*it);
+NativeWidget* NativeWidget::GetNativeWidgetForNativeView(
+ gfx::NativeView native_view) {
+ if (!ui::WindowImpl::IsWindowImpl(native_view))
+ return NULL;
+ return reinterpret_cast<WidgetWin*>(
+ ViewProp::GetValue(native_view, kNativeWidgetKey));
}
// static
-Widget* Widget::GetWidgetFromNativeView(gfx::NativeView native_view) {
- return IsWindow(native_view) ?
- reinterpret_cast<Widget*>(ViewProp::GetValue(native_view, kWidgetKey)) :
- NULL;
+NativeWidget* NativeWidget::GetNativeWidgetForNativeWindow(
+ gfx::NativeWindow native_window) {
+ return GetNativeWidgetForNativeView(native_window);
}
// static
-Widget* Widget::GetWidgetFromNativeWindow(gfx::NativeWindow native_window) {
- return Widget::GetWidgetFromNativeView(native_window);
+NativeWidget* NativeWidget::GetTopLevelNativeWidget(
+ gfx::NativeView native_view) {
+ if (!native_view)
+ return NULL;
+
+ // First, check if the top-level window is a Widget.
+ HWND root = ::GetAncestor(native_view, GA_ROOT);
+ if (!root)
+ return NULL;
+
+ NativeWidget* widget = GetNativeWidgetForNativeView(root);
+ if (widget)
+ return widget;
+
+ // Second, try to locate the last Widget window in the parent hierarchy.
+ HWND parent_hwnd = native_view;
+ NativeWidget* parent_widget;
+ do {
+ parent_widget = GetNativeWidgetForNativeView(parent_hwnd);
+ if (parent_widget) {
+ widget = parent_widget;
+ parent_hwnd = ::GetAncestor(parent_hwnd, GA_PARENT);
+ }
+ } while (parent_hwnd != NULL && parent_widget != NULL);
+
+ return widget;
}
// static
-void Widget::NotifyLocaleChanged() {
- NOTIMPLEMENTED();
+void NativeWidget::GetAllNativeWidgets(gfx::NativeView native_view,
+ NativeWidgets* children) {
+ if (!native_view)
+ return;
+
+ NativeWidget* native_widget = GetNativeWidgetForNativeView(native_view);
+ if (native_widget)
+ children->insert(native_widget);
+ EnumChildWindows(native_view, EnumerateChildWindowsForNativeWidgets,
+ reinterpret_cast<LPARAM>(children));
}
} // namespace views
diff --git a/views/widget/widget_win.h b/views/widget/widget_win.h
index 6130ad1..1916055 100644
--- a/views/widget/widget_win.h
+++ b/views/widget/widget_win.h
@@ -44,8 +44,6 @@ 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
@@ -80,18 +78,12 @@ const int WM_NCUAHDRAWFRAME = 0xAF;
///////////////////////////////////////////////////////////////////////////////
class WidgetWin : public ui::WindowImpl,
public Widget,
- public internal::NativeWidget,
+ public NativeWidget,
public MessageLoopForUI::Observer {
public:
WidgetWin();
virtual ~WidgetWin();
- // Returns the Widget associated with the specified HWND (if any).
- static WidgetWin* GetWidget(HWND hwnd);
-
- // Returns the root Widget associated with the specified HWND (if any).
- static WidgetWin* GetRootWidget(HWND hwnd);
-
// Returns true if we are on Windows Vista or greater and composition is
// enabled.
static bool IsAeroGlassEnabled();
@@ -134,7 +126,6 @@ class WidgetWin : public ui::WindowImpl,
virtual gfx::NativeView GetNativeView() const;
virtual void SetOpacity(unsigned char opacity);
virtual void SetAlwaysOnTop(bool on_top);
- virtual Widget* GetRootWidget() const;
virtual bool IsVisible() const;
virtual bool IsActive() const;
virtual bool IsAccessibleWidget() const;
@@ -228,6 +219,9 @@ class WidgetWin : public ui::WindowImpl,
}
protected:
+ // Overridden from NativeWidget:
+ virtual Widget* GetWidget();
+
// Overridden from MessageLoop::Observer:
void WillProcessMessage(const MSG& msg);
virtual void DidProcessMessage(const MSG& msg);
diff --git a/views/window/window_gtk.cc b/views/window/window_gtk.cc
index 09e1984..a47bc32 100644
--- a/views/window/window_gtk.cc
+++ b/views/window/window_gtk.cc
@@ -97,7 +97,8 @@ void Window::CloseAllSecondaryWindows() {
for (GList* window = windows; window;
window = g_list_next(window)) {
Window::CloseSecondaryWidget(
- WidgetGtk::GetViewForNative(GTK_WIDGET(window->data)));
+ NativeWidget::GetNativeWidgetForNativeView(
+ GTK_WIDGET(window->data))->GetWidget());
}
g_list_free(windows);
}
diff --git a/views/window/window_win.cc b/views/window/window_win.cc
index 239226d..0bff7c0 100644
--- a/views/window/window_win.cc
+++ b/views/window/window_win.cc
@@ -1531,15 +1531,11 @@ void WindowWin::InitClass() {
}
namespace {
-// static
-static BOOL CALLBACK WindowCallbackProc(HWND hwnd, LPARAM lParam) {
- // This is safer than calling GetWindowUserData, since it looks specifically
- // for the RootView window property which should be unique.
- RootView* root_view = GetRootViewForHWND(hwnd);
- if (!root_view)
- return TRUE;
-
- Window::CloseSecondaryWidget(root_view->GetWidget());
+BOOL CALLBACK WindowCallbackProc(HWND hwnd, LPARAM lParam) {
+ NativeWidget* native_widget =
+ NativeWidget::GetNativeWidgetForNativeView(hwnd);
+ if (native_widget)
+ Window::CloseSecondaryWidget(native_widget->GetWidget());
return TRUE;
}
} // namespace