diff options
author | ben@chromium.org <ben@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-02-02 18:31:52 +0000 |
---|---|---|
committer | ben@chromium.org <ben@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-02-02 18:31:52 +0000 |
commit | cc2c4eb51c6fc7c688151df5fc28e28d031cf3e3 (patch) | |
tree | cf110bb3cfe4fb2f19dfca7fd3c5d808cee2c8d9 /ui/views/widget | |
parent | 832c698f26e0d26a05a699720b5ed214b7463c74 (diff) | |
download | chromium_src-cc2c4eb51c6fc7c688151df5fc28e28d031cf3e3.zip chromium_src-cc2c4eb51c6fc7c688151df5fc28e28d031cf3e3.tar.gz chromium_src-cc2c4eb51c6fc7c688151df5fc28e28d031cf3e3.tar.bz2 |
Begin to integrate Focus Manager. Add Windows accelerator handler implementation (commented out now due to lack of focus manager). Add some utilities to NativeWidget for obtaining NativeWidget from a NativeView.
BUG=none
TEST=none
Review URL: http://codereview.chromium.org/6286035
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@73479 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ui/views/widget')
-rw-r--r-- | ui/views/widget/native_widget.h | 12 | ||||
-rw-r--r-- | ui/views/widget/native_widget_win.cc | 43 | ||||
-rw-r--r-- | ui/views/widget/native_widget_win_unittest.cc | 92 | ||||
-rw-r--r-- | ui/views/widget/widget.cc | 3 | ||||
-rw-r--r-- | ui/views/widget/widget.h | 2 |
5 files changed, 150 insertions, 2 deletions
diff --git a/ui/views/widget/native_widget.h b/ui/views/widget/native_widget.h index f8508a2..6b9add7 100644 --- a/ui/views/widget/native_widget.h +++ b/ui/views/widget/native_widget.h @@ -32,6 +32,18 @@ class NativeWidget { static NativeWidget* CreateNativeWidget( internal::NativeWidgetListener* listener); + // 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); + // See Widget for documentation and notes. virtual void InitWithNativeViewParent(gfx::NativeView parent, const gfx::Rect& bounds) = 0; diff --git a/ui/views/widget/native_widget_win.cc b/ui/views/widget/native_widget_win.cc index c5bd930..e435592 100644 --- a/ui/views/widget/native_widget_win.cc +++ b/ui/views/widget/native_widget_win.cc @@ -10,6 +10,7 @@ #include "gfx/native_theme_win.h" #include "ui/base/system_monitor/system_monitor.h" #include "ui/base/view_prop.h" +#include "ui/base/win/hwnd_util.h" #include "ui/views/view.h" #include "ui/views/widget/native_widget_listener.h" #include "ui/views/widget/widget.h" @@ -265,6 +266,7 @@ void NativeWidgetWin::OnCommand(UINT notification_code, int command_id, } LRESULT NativeWidgetWin::OnCreate(CREATESTRUCT* create_struct) { + SetNativeWindowProperty(kNativeWidgetKey, this); MessageLoopForUI::current()->AddObserver(this); return 0; } @@ -623,4 +625,45 @@ NativeWidget* NativeWidget::CreateNativeWidget( return new internal::NativeWidgetWin(listener); } +// static +NativeWidget* NativeWidget::GetNativeWidgetForNativeView( + gfx::NativeView native_view) { + if (!WindowImpl::IsWindowImpl(native_view)) + return NULL; + return reinterpret_cast<internal::NativeWidgetWin*>( + ViewProp::GetValue(native_view, internal::kNativeWidgetKey)); +} + +// static +NativeWidget* NativeWidget::GetNativeWidgetForNativeWindow( + gfx::NativeWindow native_window) { + return GetNativeWidgetForNativeView(native_window); +} + +// static +NativeWidget* NativeWidget::GetTopLevelNativeWidget( + gfx::NativeView native_view) { + // 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; +} + } // namespace ui diff --git a/ui/views/widget/native_widget_win_unittest.cc b/ui/views/widget/native_widget_win_unittest.cc new file mode 100644 index 0000000..b5cdf04 --- /dev/null +++ b/ui/views/widget/native_widget_win_unittest.cc @@ -0,0 +1,92 @@ +// 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 "ui/base/win/window_impl.h" +#include "ui/views/view.h" +#include "ui/views/widget/native_widget.h" +#include "ui/views/widget/widget.h" + +namespace ui { + +class NativeWidgetTest : public testing::Test { + public: + NativeWidgetTest() {} + virtual ~NativeWidgetTest() {} + + Widget* CreateWidget() const { + Widget* widget = new Widget(new View); + widget->set_delete_on_destroy(false); + widget->InitWithNativeViewParent(NULL, gfx::Rect(10, 10, 200, 200)); + return widget; + } + + private: + DISALLOW_COPY_AND_ASSIGN(NativeWidgetTest); +}; + +class TestWindowImpl : public WindowImpl { + public: + TestWindowImpl() {} + virtual ~TestWindowImpl() {} + + virtual BOOL ProcessWindowMessage(HWND window, + UINT message, + WPARAM w_param, + LPARAM l_param, + LRESULT& result, + DWORD msg_mad_id = 0) { + return FALSE; + } + + private: + DISALLOW_COPY_AND_ASSIGN(TestWindowImpl); +}; + +TEST_F(NativeWidgetTest, CreateNativeWidget) { + scoped_ptr<Widget> widget(CreateWidget()); + EXPECT_TRUE(widget->native_widget()->GetNativeView() != NULL); +} + +TEST_F(NativeWidgetTest, GetNativeWidgetForNativeView) { + scoped_ptr<Widget> widget(CreateWidget()); + NativeWidget* a = widget->native_widget(); + HWND nv = widget->native_widget()->GetNativeView(); + NativeWidget* b = NativeWidget::GetNativeWidgetForNativeView(nv); + EXPECT_EQ(a, b); +} + +// |widget| has the toplevel NativeWidget. +TEST_F(NativeWidgetTest, GetTopLevelNativeWidget1) { + scoped_ptr<Widget> widget(CreateWidget()); + EXPECT_EQ(widget->native_widget(), + NativeWidget::GetTopLevelNativeWidget( + widget->native_widget()->GetNativeView())); +} + +// |toplevel_widget| has the toplevel NativeWidget. +TEST_F(NativeWidgetTest, GetTopLevelNativeWidget2) { + scoped_ptr<Widget> child_widget(CreateWidget()); + scoped_ptr<Widget> toplevel_widget(CreateWidget()); + SetParent(child_widget->native_widget()->GetNativeView(), + toplevel_widget->native_widget()->GetNativeView()); + EXPECT_EQ(toplevel_widget->native_widget(), + NativeWidget::GetTopLevelNativeWidget( + child_widget->native_widget()->GetNativeView())); +} + +// |child_widget| has the toplevel NativeWidget. +TEST_F(NativeWidgetTest, GetTopLevelNativeWidget3) { + scoped_ptr<Widget> child_widget(CreateWidget()); + + TestWindowImpl toplevel; + toplevel.Init(NULL, gfx::Rect(10, 10, 100, 100)); + + SetParent(child_widget->native_widget()->GetNativeView(), toplevel.hwnd()); + EXPECT_EQ(child_widget->native_widget(), + NativeWidget::GetTopLevelNativeWidget( + child_widget->native_widget()->GetNativeView())); +} + +} // namespace ui diff --git a/ui/views/widget/widget.cc b/ui/views/widget/widget.cc index 36af0b1..ba2daa6 100644 --- a/ui/views/widget/widget.cc +++ b/ui/views/widget/widget.cc @@ -47,7 +47,8 @@ Widget::Widget(View* contents_view) root_view_(new internal::RootView(this, contents_view))), is_mouse_button_pressed_(false), last_mouse_event_was_move_(false), - ALLOW_THIS_IN_INITIALIZER_LIST(close_widget_factory_(this)) { + ALLOW_THIS_IN_INITIALIZER_LIST(close_widget_factory_(this)), + delete_on_destroy_(true) { } Widget::~Widget() { diff --git a/ui/views/widget/widget.h b/ui/views/widget/widget.h index 9a68eab..b97e7933 100644 --- a/ui/views/widget/widget.h +++ b/ui/views/widget/widget.h @@ -41,7 +41,7 @@ class Widget : public internal::NativeWidgetListener { explicit Widget(View* contents_view); virtual ~Widget(); - bool set_delete_on_destroy(bool delete_on_destroy) { + void set_delete_on_destroy(bool delete_on_destroy) { delete_on_destroy_ = delete_on_destroy; } |