summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorananta@chromium.org <ananta@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-03-02 06:11:22 +0000
committerananta@chromium.org <ananta@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-03-02 06:11:22 +0000
commit3ef5d1b8cd0d307dda2b03b7d8bf9c8d7d97e870 (patch)
tree7725c4b1c02db26a7e09c30d325c2777109228d6
parent99f5dfdbdf3b9d948750a4bbed07b0a2eef2337e (diff)
downloadchromium_src-3ef5d1b8cd0d307dda2b03b7d8bf9c8d7d97e870.zip
chromium_src-3ef5d1b8cd0d307dda2b03b7d8bf9c8d7d97e870.tar.gz
chromium_src-3ef5d1b8cd0d307dda2b03b7d8bf9c8d7d97e870.tar.bz2
Reverting to fix builder redness. Please fix and reland.
Revert 76483 - Remove/replace RootView/Widget getters with new NativeWidget getters. BUG=72040 TEST=existing unittests. Review URL: http://codereview.chromium.org/6598069 TBR=ben@chromium.org Review URL: http://codereview.chromium.org/6597099 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@76508 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, 360 insertions, 475 deletions
diff --git a/chrome/browser/automation/testing_automation_provider_views.cc b/chrome/browser/automation/testing_automation_provider_views.cc
index 01fedb8..99b4065 100644
--- a/chrome/browser/automation/testing_automation_provider_views.cc
+++ b/chrome/browser/automation/testing_automation_provider_views.cc
@@ -13,7 +13,6 @@
#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"
@@ -122,10 +121,8 @@ void TestingAutomationProvider::WindowGetViewBounds(int handle,
if (window_tracker_->ContainsHandle(handle)) {
gfx::NativeWindow window = window_tracker_->GetResource(handle);
- views::NativeWidget* native_widget =
- views::NativeWidget::GetNativeWidgetForNativeWindow(window);
- if (native_widget) {
- views::View* root_view = native_widget->GetWidget()->GetRootView();
+ views::RootView* root_view = views::Widget::FindRootView(window);
+ if (root_view) {
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 eb75b1b..80d2bf0 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/native_widget.h"
+#include "views/widget/root_view.h"
#include "views/widget/widget.h"
#elif defined(TOOLKIT_GTK)
#include "chrome/browser/ui/gtk/custom_drag.h"
@@ -335,13 +335,10 @@ void DragBookmarks(Profile* profile,
bool was_nested = MessageLoop::current()->IsNested();
MessageLoop::current()->SetNestableTasksAllowed(true);
- 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);
- }
+ views::Widget* widget = views::Widget::GetWidgetFromNativeView(view);
+ widget->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 6633ab8..55aec2e 100644
--- a/chrome/browser/chromeos/setting_level_bubble.cc
+++ b/chrome/browser/chromeos/setting_level_bubble.cc
@@ -45,10 +45,14 @@ static views::Widget* GetToplevelWidget() {
if (!browser)
return NULL;
- views::NativeWidget* native_widget =
- views::NativeWidget::GetNativeWidgetForNativeWindow(
+ views::RootView* root =
+ views::Widget::FindRootView(
GTK_WINDOW(browser->window()->GetNativeHandle()));
- return native_widget->GetWidget();
+ DCHECK(root);
+ if (!root)
+ return NULL;
+
+ return root->GetWidget();
}
SettingLevelBubble::SettingLevelBubble(SkBitmap* increase_icon,
diff --git a/chrome/browser/download/download_util.cc b/chrome/browser/download/download_util.cc
index ae0f398..215997f 100644
--- a/chrome/browser/download/download_util.cc
+++ b/chrome/browser/download/download_util.cc
@@ -540,8 +540,7 @@ void DragDownload(const DownloadItem* download,
GtkWidget* root = gtk_widget_get_toplevel(view);
if (!root)
return;
- views::WidgetGtk* widget = static_cast<views::WidgetGtk*>(
- views::NativeWidget::GetNativeWidgetForNativeView(root));
+ views::WidgetGtk* widget = views::WidgetGtk::GetViewForNative(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 37f53bc..6abe5d5 100644
--- a/chrome/browser/speech/speech_input_bubble_views.cc
+++ b/chrome/browser/speech/speech_input_bubble_views.cc
@@ -281,11 +281,12 @@ void SpeechInputBubbleImpl::Show() {
bubble_content_ = new ContentView(delegate_);
UpdateLayout();
- views::NativeWidget* toplevel_widget =
- views::NativeWidget::GetTopLevelNativeWidget(
- tab_contents()->view()->GetNativeView());
- if (toplevel_widget) {
- info_bubble_ = InfoBubble::Show(toplevel_widget->GetWidget(),
+ views::Widget* tab = views::Widget::GetWidgetFromNativeView(
+ tab_contents()->view()->GetNativeView());
+ views::Widget* parent = tab ? tab->GetRootWidget() : NULL;
+
+ if (parent) {
+ info_bubble_ = InfoBubble::Show(parent,
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 c0819df..bacb9d8 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()->GetTopLevelWidget()->GetBounds(&frame_rect, true);
+ host()->GetRootWidget()->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 162b1f6..9b6dff2 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/native_widget.h"
+#include "views/widget/root_view.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::NativeWidget* native_widget =
- views::NativeWidget::GetNativeWidgetForNativeView(native_view_);
- if (native_widget &&
- native_widget->GetWidget()->ContainsNativeView(native_view)) {
+ 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))
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 dbb8461..88feac7 100644
--- a/views/controls/native/native_view_host_win.cc
+++ b/views/controls/native/native_view_host_win.cc
@@ -8,7 +8,6 @@
#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"
@@ -38,13 +37,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 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,
+ // 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,
host_->GetWidget()->GetNativeView());
}
}
@@ -53,13 +52,13 @@ void NativeViewHostWin::NativeViewDetaching(bool destroyed) {
if (!destroyed && installed_clip_)
UninstallClip();
installed_clip_ = 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,
+ // 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,
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 50b62c6..02d5fe6 100644
--- a/views/controls/tabbed_pane/native_tabbed_pane_gtk.cc
+++ b/views/controls/tabbed_pane/native_tabbed_pane_gtk.cc
@@ -64,8 +64,7 @@ View* NativeTabbedPaneGtk::RemoveTabAtIndex(int index) {
GtkWidget* page =
gtk_notebook_get_nth_page(GTK_NOTEBOOK(native_view()), index);
- WidgetGtk* widget =
- static_cast<WidgetGtk*>(NativeWidget::GetNativeWidgetForNativeView(page));
+ WidgetGtk* widget = WidgetGtk::GetViewForNative(page);
// detach the content view from widget so that we can delete widget
// without destroying the content view.
@@ -195,8 +194,7 @@ WidgetGtk* NativeTabbedPaneGtk::GetWidgetAt(int index) {
DCHECK(index <= GetTabCount());
GtkWidget* page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(native_view()),
index);
- WidgetGtk* widget =
- static_cast<WidgetGtk*>(NativeWidget::GetNativeWidgetForNativeView(page));
+ WidgetGtk* widget = WidgetGtk::GetViewForNative(page);
DCHECK(widget);
return widget;
}
diff --git a/views/focus/accelerator_handler_touch.cc b/views/focus/accelerator_handler_touch.cc
index 389fe7d..d4b072a 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);
- NativeWidget* widget = NativeWidget::GetNativeWidgetForNativeView(gtk_widget);
- if (!widget) {
+ if (!widget_gtk) {
DLOG(WARNING) << "no WidgetGtk found for that GtkWidget";
return NULL;
}
- return widget->GetWidget()->GetRootView();
+ return widget_gtk->GetRootView();
}
#if defined(HAVE_XINPUT2)
diff --git a/views/focus/focus_manager_gtk.cc b/views/focus/focus_manager_gtk.cc
index 327c785..6e9dbcf 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;
- NativeWidget* widget = NativeWidget::GetNativeWidgetForNativeView(root);
+ WidgetGtk* widget = WidgetGtk::GetViewForNative(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->GetWidget()->GetFocusManager();
+ FocusManager* focus_manager = widget->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 d6f1e02..faf3815 100644
--- a/views/focus/focus_manager_win.cc
+++ b/views/focus/focus_manager_win.cc
@@ -23,10 +23,8 @@ void FocusManager::FocusNativeView(gfx::NativeView native_view) {
// static
FocusManager* FocusManager::GetFocusManagerForNativeView(
gfx::NativeView native_view) {
- // 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;
+ WidgetWin* widget = WidgetWin::GetRootWidget(native_view);
+ return widget ? widget->GetFocusManager() : NULL;
}
// static
diff --git a/views/test/views_test_base.h b/views/test/views_test_base.h
index d66a1d8..080eca5 100644
--- a/views/test/views_test_base.h
+++ b/views/test/views_test_base.h
@@ -10,10 +10,6 @@
#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 16109f7..8207c76b 100644
--- a/views/view_unittest.cc
+++ b/views/view_unittest.cc
@@ -1439,22 +1439,33 @@ class TestChangeNativeViewHierarchy {
view_test_->RunPendingMessages();
}
- void CheckEnumeratingNativeWidgets() {
- if (!host_->GetWindow())
+ 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 {
return;
- NativeWidget::NativeWidgets widgets;
- NativeWidget::GetAllNativeWidgets(host_->GetNativeView(), &widgets);
- EXPECT_EQ(TestNativeViewHierarchy::kTotalViews + 1, widgets.size());
+ }
+#endif
+ EXPECT_EQ(TestNativeViewHierarchy::kTotalViews + 1,
+ enumerated_root_views.size());
// Unfortunately there is no guarantee the sequence of views here so always
// go through all of them.
- for (NativeWidget::NativeWidgets::iterator i = widgets.begin();
- i != widgets.end(); ++i) {
- RootView* root_view = (*i)->GetWidget()->GetRootView();
- if (host_->GetRootView() == root_view)
+ for (std::vector<RootView*>::iterator i = enumerated_root_views.begin();
+ i != enumerated_root_views.end(); ++i) {
+ if (host_->GetRootView() == *i)
continue;
size_t j;
for (j = 0; j < TestNativeViewHierarchy::kTotalViews; ++j)
- if (root_views_[j] == root_view)
+ if (root_views_[j] == *i)
break;
// EXPECT_LT/GT/GE() fails to compile with class-defined constants
// with gcc, with error
@@ -1498,7 +1509,7 @@ TEST_F(ViewTest, ChangeNativeViewHierarchyFindRoots) {
// TODO(georgey): Fix the test for Linux
#if defined(OS_WIN)
TestChangeNativeViewHierarchy test(this);
- test.CheckEnumeratingNativeWidgets();
+ test.CheckEnumeratingRootViews();
#endif
}
diff --git a/views/views.gyp b/views/views.gyp
index a8c1fa3..f81e669 100644
--- a/views/views.gyp
+++ b/views/views.gyp
@@ -489,10 +489,6 @@
'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 dffbf93..2700f8c 100644
--- a/views/widget/native_widget.h
+++ b/views/widget/native_widget.h
@@ -6,11 +6,8 @@
#define VIEWS_WIDGET_NATIVE_WIDGET_H_
#pragma once
-#include <set>
-
namespace views {
-
-class Widget;
+namespace internal {
////////////////////////////////////////////////////////////////////////////////
// NativeWidget interface
@@ -21,30 +18,9 @@ class Widget;
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
deleted file mode 100644
index ac3e5b4..0000000
--- a/views/widget/native_widget_test_utils.h
+++ /dev/null
@@ -1,22 +0,0 @@
-// 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
deleted file mode 100644
index 43c0279..0000000
--- a/views/widget/native_widget_test_utils_gtk.cc
+++ /dev/null
@@ -1,33 +0,0 @@
-// 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
deleted file mode 100644
index 2d016e9..0000000
--- a/views/widget/native_widget_test_utils_win.cc
+++ /dev/null
@@ -1,33 +0,0 @@
-// 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
deleted file mode 100644
index 91c29a3..0000000
--- a/views/widget/native_widget_unittest.cc
+++ /dev/null
@@ -1,81 +0,0 @@
-// 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 c280206..0299c2d 100644
--- a/views/widget/widget.cc
+++ b/views/widget/widget.cc
@@ -7,7 +7,6 @@
#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 {
@@ -29,17 +28,6 @@ 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_;
}
@@ -94,6 +82,10 @@ 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 b1860d1..89e9061 100644
--- a/views/widget/widget.h
+++ b/views/widget/widget.h
@@ -29,13 +29,16 @@ 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
//
@@ -88,6 +91,21 @@ 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();
@@ -110,11 +128,6 @@ 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();
@@ -170,6 +183,9 @@ 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;
@@ -264,7 +280,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(NativeWidget* native_widget) {
+ void set_native_widget(internal::NativeWidget* native_widget) {
native_widget_ = native_widget;
}
@@ -274,7 +290,7 @@ class Widget : public internal::NativeWidgetDelegate,
virtual View* GetFocusTraversableParentView();
private:
- NativeWidget* native_widget_;
+ internal::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 cb9eddf..0eca3d7 100644
--- a/views/widget/widget_gtk.cc
+++ b/views/widget/widget_gtk.cc
@@ -44,12 +44,10 @@ using ui::OSExchangeData;
using ui::OSExchangeDataProviderGtk;
using ui::ActiveWindowWatcherX;
-namespace views {
-
namespace {
-// Links the GtkWidget to its NativeWidget.
-const char* const kNativeWidgetKey = "__VIEWS_NATIVE_WIDGET__";
+// g_object data keys to associate a WidgetGtk object to a GtkWidget.
+const char* kWidgetKey = "__VIEWS_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
@@ -136,26 +134,10 @@ class CompositePainter {
DISALLOW_COPY_AND_ASSIGN(CompositePainter);
};
-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);
- }
-
- NativeWidget* native_widget =
- NativeWidget::GetNativeWidgetForNativeView(child_widget);
- if (native_widget) {
- NativeWidget::NativeWidgets* widgets =
- reinterpret_cast<NativeWidget::NativeWidgets*>(param);
- widgets->insert(native_widget);
- }
-}
-
} // namespace
+namespace views {
+
// 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.
// To work around that we listen for DROP_START, then ignore the subsequent
@@ -185,8 +167,7 @@ class WidgetGtk::DropObserver : public MessageLoopForUI::Observer {
if (!gtk_widget)
return NULL;
- return static_cast<WidgetGtk*>(
- NativeWidget::GetNativeWidgetForNativeView(gtk_widget));
+ return WidgetGtk::GetViewForNative(gtk_widget);
}
DISALLOW_COPY_AND_ASSIGN(DropObserver);
@@ -440,11 +421,22 @@ 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_) &&
@@ -525,6 +517,7 @@ 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);
@@ -637,8 +630,7 @@ 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 = static_cast<WidgetGtk*>(
- NativeWidget::GetNativeWidgetForNativeView(parent));
+ WidgetGtk* parent_widget = GetViewForNative(parent);
parent_widget->PositionChild(widget_, bounds.x(), bounds.y(),
bounds.width(), bounds.height());
} else {
@@ -743,6 +735,16 @@ 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_);
}
@@ -794,11 +796,11 @@ FocusManager* WidgetGtk::GetFocusManager() {
if (focus_manager_)
return focus_manager_;
- NativeWidget* native_widget = GetTopLevelNativeWidget(GetNativeView());
- if (native_widget && native_widget != this) {
- // WidgetGtk subclasses may override GetFocusManager(), for example for
+ Widget* root = GetRootWidget();
+ if (root && root != this) {
+ // Widget subclasses may override GetFocusManager(), for example for
// dealing with cases where the widget has been unparented.
- return native_widget->GetWidget()->GetFocusManager();
+ return root->GetFocusManager();
}
return NULL;
}
@@ -934,13 +936,6 @@ void WidgetGtk::EnableDebugPaint() {
}
////////////////////////////////////////////////////////////////////////////////
-// WidgetGtk, NativeWidget implementation:
-
-Widget* WidgetGtk::GetWidget() {
- return this;
-}
-
-////////////////////////////////////////////////////////////////////////////////
// WidgetGtk, protected:
void WidgetGtk::OnSizeRequest(GtkWidget* widget, GtkRequisition* requisition) {
@@ -1378,11 +1373,15 @@ 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 = static_cast<WidgetGtk*>(
- NativeWidget::GetNativeWidgetForNativeView(parent));
+ WidgetGtk* widget_gtk = GetViewForNative(parent);
if (widget_gtk && widget_gtk->is_window_)
return static_cast<WindowGtk*>(widget_gtk);
parent = gtk_widget_get_parent(parent);
@@ -1479,7 +1478,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_), kNativeWidgetKey,
+ g_object_set_data(G_OBJECT(window_contents_), kWidgetKey,
static_cast<Widget*>(this));
if (transparent_)
@@ -1493,7 +1492,9 @@ void WidgetGtk::CreateGtkWidget(GtkWidget* parent, const gfx::Rect& bounds) {
// function properly.
gtk_widget_realize(widget_);
}
- SetNativeWindowProperty(kNativeWidgetKey, this);
+ // Setting the WidgetKey property to widget_, which is used by
+ // GetWidgetFromNativeWindow.
+ SetNativeWindowProperty(kWidgetKey, this);
}
void WidgetGtk::ConfigureWidgetForTransparentBackground(GtkWidget* parent) {
@@ -1572,71 +1573,95 @@ Widget* Widget::CreatePopupWidget(TransparencyParam transparent,
return popup;
}
-// static
-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();
+// 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);
+ }
}
- g_list_free(window_list);
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// NativeWidget, public:
-
-// 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
-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));
+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);
+ }
}
// static
-NativeWidget* NativeWidget::GetTopLevelNativeWidget(
- gfx::NativeView native_view) {
- if (!native_view)
- return NULL;
+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);
- NativeWidget* widget = NULL;
+ std::set<RootView*> root_views_set;
- 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);
+ // 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);
+}
- return widget;
+// 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;
}
// static
-void NativeWidget::GetAllNativeWidgets(gfx::NativeView native_view,
- NativeWidgets* children) {
- if (!native_view)
- return;
+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* native_widget = GetNativeWidgetForNativeView(native_view);
- if (native_widget)
- children->insert(native_widget);
- gtk_container_foreach(GTK_CONTAINER(native_view),
- EnumerateChildWidgetsForNativeWidgets,
- reinterpret_cast<gpointer>(children));
+// 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);
}
} // namespace views
diff --git a/views/widget/widget_gtk.h b/views/widget/widget_gtk.h
index 91b8024..8c0cacd 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 NativeWidget,
+ public internal::NativeWidget,
public ui::ActiveWindowWatcherX::Observer {
public:
// Type of widget.
@@ -137,10 +137,16 @@ 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.
@@ -163,6 +169,7 @@ 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;
@@ -200,9 +207,6 @@ 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,
@@ -302,6 +306,8 @@ 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 d63a00c..70b946d 100644
--- a/views/widget/widget_utils.cc
+++ b/views/widget/widget_utils.cc
@@ -11,7 +11,7 @@
namespace views {
ThemeProvider* GetWidgetThemeProvider(const Widget* widget) {
- const Widget* root_widget = widget->GetTopLevelWidget();
+ Widget* root_widget = widget->GetRootWidget();
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 817ca77..8cde70f 100644
--- a/views/widget/widget_win.cc
+++ b/views/widget/widget_win.cc
@@ -94,22 +94,32 @@ bool ProcessChildWindowMessage(UINT message,
return false;
}
-// 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);
+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.
}
+ return TRUE; // Keep enumerating.
+}
- return TRUE;
+// 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.
}
-// Links the HWND to its NativeWidget.
-const char* const kNativeWidgetKey = "__VIEWS_NATIVE_WIDGET__";
+// 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__";
// A custom MSAA object id used to determine if a screen reader is actively
// listening for MSAA events.
@@ -120,6 +130,11 @@ 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:
@@ -145,7 +160,41 @@ WidgetWin::WidgetWin()
WidgetWin::~WidgetWin() {
DestroyRootView();
- CloseNow();
+}
+
+// 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;
}
// static
@@ -203,7 +252,8 @@ void WidgetWin::Init(gfx::NativeView parent, const gfx::Rect& bounds) {
drop_target_ = new DropTargetWin(GetRootView());
if ((window_style() & WS_CHILD) == 0 ||
- (!GetTopLevelNativeWidget(parent) && parent != GetDesktopWindow())) {
+ (WidgetWin::GetRootWidget(parent) == NULL &&
+ 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
@@ -211,6 +261,9 @@ 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
@@ -335,6 +388,10 @@ 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());
}
@@ -396,11 +453,11 @@ FocusManager* WidgetWin::GetFocusManager() {
if (focus_manager_.get())
return focus_manager_.get();
- NativeWidget* native_widget = GetTopLevelNativeWidget(hwnd());
- if (native_widget && native_widget != this) {
+ WidgetWin* widget = static_cast<WidgetWin*>(GetRootWidget());
+ if (widget && widget != this) {
// WidgetWin subclasses may override GetFocusManager(), for example for
// dealing with cases where the widget has been unparented.
- return native_widget->GetWidget()->GetFocusManager();
+ return widget->GetFocusManager();
}
return NULL;
}
@@ -491,13 +548,6 @@ void WidgetWin::SetCursor(gfx::NativeCursor cursor) {
}
////////////////////////////////////////////////////////////////////////////////
-// WidgetWin, NativeWidget implementation:
-
-Widget* WidgetWin::GetWidget() {
- return this;
-}
-
-////////////////////////////////////////////////////////////////////////////////
// WidgetWin, MessageLoop::Observer implementation:
void WidgetWin::WillProcessMessage(const MSG& msg) {
@@ -582,7 +632,9 @@ void WidgetWin::OnCommand(UINT notification_code, int command_id, HWND window) {
}
LRESULT WidgetWin::OnCreate(CREATESTRUCT* create_struct) {
- SetNativeWindowProperty(kNativeWidgetKey, this);
+ // Widget::GetWidgetFromNativeView expects the contents of this property
+ // to be of type Widget, so the cast is necessary.
+ SetNativeWindowProperty(kWidgetKey, static_cast<Widget*>(this));
use_layered_buffer_ = !!(window_ex_style() & WS_EX_LAYERED);
LayoutRootView();
return 0;
@@ -1241,68 +1293,50 @@ Widget* Widget::CreatePopupWidget(TransparencyParam transparent,
}
// static
-void Widget::NotifyLocaleChanged() {
- NOTIMPLEMENTED();
-}
+RootView* Widget::FindRootView(HWND hwnd) {
+ RootView* root_view = GetRootViewForHWND(hwnd);
+ if (root_view)
+ return root_view;
-////////////////////////////////////////////////////////////////////////////////
-// NativeWidget, public:
+ // Enumerate all children and check if they have a RootView.
+ EnumChildWindows(hwnd, EnumChildProc, reinterpret_cast<LPARAM>(&root_view));
-// static
-NativeWidget* NativeWidget::GetNativeWidgetForNativeView(
- gfx::NativeView native_view) {
- if (!ui::WindowImpl::IsWindowImpl(native_view))
- return NULL;
- return reinterpret_cast<WidgetWin*>(
- ViewProp::GetValue(native_view, kNativeWidgetKey));
+ return root_view;
}
// static
-NativeWidget* NativeWidget::GetNativeWidgetForNativeWindow(
- gfx::NativeWindow native_window) {
- return GetNativeWidgetForNativeView(native_window);
+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);
}
// static
-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;
+Widget* Widget::GetWidgetFromNativeView(gfx::NativeView native_view) {
+ return IsWindow(native_view) ?
+ reinterpret_cast<Widget*>(ViewProp::GetValue(native_view, kWidgetKey)) :
+ NULL;
}
// static
-void NativeWidget::GetAllNativeWidgets(gfx::NativeView native_view,
- NativeWidgets* children) {
- if (!native_view)
- return;
+Widget* Widget::GetWidgetFromNativeWindow(gfx::NativeWindow native_window) {
+ return Widget::GetWidgetFromNativeView(native_window);
+}
- NativeWidget* native_widget = GetNativeWidgetForNativeView(native_view);
- if (native_widget)
- children->insert(native_widget);
- EnumChildWindows(native_view, EnumerateChildWindowsForNativeWidgets,
- reinterpret_cast<LPARAM>(children));
+// static
+void Widget::NotifyLocaleChanged() {
+ NOTIMPLEMENTED();
}
} // namespace views
diff --git a/views/widget/widget_win.h b/views/widget/widget_win.h
index 1916055..6130ad1 100644
--- a/views/widget/widget_win.h
+++ b/views/widget/widget_win.h
@@ -44,6 +44,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
@@ -78,12 +80,18 @@ const int WM_NCUAHDRAWFRAME = 0xAF;
///////////////////////////////////////////////////////////////////////////////
class WidgetWin : public ui::WindowImpl,
public Widget,
- public NativeWidget,
+ public internal::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();
@@ -126,6 +134,7 @@ 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;
@@ -219,9 +228,6 @@ 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 a47bc32..09e1984 100644
--- a/views/window/window_gtk.cc
+++ b/views/window/window_gtk.cc
@@ -97,8 +97,7 @@ void Window::CloseAllSecondaryWindows() {
for (GList* window = windows; window;
window = g_list_next(window)) {
Window::CloseSecondaryWidget(
- NativeWidget::GetNativeWidgetForNativeView(
- GTK_WIDGET(window->data))->GetWidget());
+ WidgetGtk::GetViewForNative(GTK_WIDGET(window->data)));
}
g_list_free(windows);
}
diff --git a/views/window/window_win.cc b/views/window/window_win.cc
index 0bff7c0..239226d 100644
--- a/views/window/window_win.cc
+++ b/views/window/window_win.cc
@@ -1531,11 +1531,15 @@ void WindowWin::InitClass() {
}
namespace {
-BOOL CALLBACK WindowCallbackProc(HWND hwnd, LPARAM lParam) {
- NativeWidget* native_widget =
- NativeWidget::GetNativeWidgetForNativeView(hwnd);
- if (native_widget)
- Window::CloseSecondaryWidget(native_widget->GetWidget());
+// 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());
return TRUE;
}
} // namespace