summaryrefslogtreecommitdiffstats
path: root/ui
diff options
context:
space:
mode:
authorben@chromium.org <ben@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-02-02 18:31:52 +0000
committerben@chromium.org <ben@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-02-02 18:31:52 +0000
commitcc2c4eb51c6fc7c688151df5fc28e28d031cf3e3 (patch)
treecf110bb3cfe4fb2f19dfca7fd3c5d808cee2c8d9 /ui
parent832c698f26e0d26a05a699720b5ed214b7463c74 (diff)
downloadchromium_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')
-rw-r--r--ui/views/focus/accelerator_handler.h71
-rw-r--r--ui/views/focus/accelerator_handler_win.cc60
-rw-r--r--ui/views/views.gyp3
-rw-r--r--ui/views/widget/native_widget.h12
-rw-r--r--ui/views/widget/native_widget_win.cc43
-rw-r--r--ui/views/widget/native_widget_win_unittest.cc92
-rw-r--r--ui/views/widget/widget.cc3
-rw-r--r--ui/views/widget/widget.h2
8 files changed, 284 insertions, 2 deletions
diff --git a/ui/views/focus/accelerator_handler.h b/ui/views/focus/accelerator_handler.h
new file mode 100644
index 0000000..3f129ba
--- /dev/null
+++ b/ui/views/focus/accelerator_handler.h
@@ -0,0 +1,71 @@
+// 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 UI_VIEWS_FOCUS_ACCELERATOR_HANDLER_H_
+#define UI_VIEWS_FOCUS_ACCELERATOR_HANDLER_H_
+#pragma once
+
+#include "build/build_config.h"
+
+#if defined(OS_LINUX)
+#include <gdk/gdk.h>
+#endif
+
+#include <set>
+#include <vector>
+
+#include "base/message_loop.h"
+
+namespace ui {
+
+#if defined(TOUCH_UI)
+// Dispatch an XEvent to the RootView. Return true if the event was dispatched
+// and handled, false otherwise.
+bool DispatchXEvent(XEvent* xevent);
+
+#if defined(HAVE_XINPUT2)
+// Keep a list of touch devices so that it is possible to determine if a pointer
+// event is a touch-event or a mouse-event.
+void SetTouchDeviceList(std::vector<unsigned int>& devices);
+#endif // HAVE_XINPUT2
+#endif // TOUCH_UI
+
+////////////////////////////////////////////////////////////////////////////////
+// AcceleratorHandler class
+//
+// An object that pre-screens all UI messages for potential accelerators.
+// Registered accelerators are processed regardless of focus within a given
+// Widget or Window.
+//
+// This processing is done at the Dispatcher level rather than on the Widget
+// because of the global nature of this processing, and the fact that not all
+// controls within a window need to be Widgets - some are native controls from
+// the underlying toolkit wrapped by NativeViewHost.
+//
+class AcceleratorHandler : public MessageLoopForUI::Dispatcher {
+ public:
+ AcceleratorHandler();
+ // Dispatcher method. This returns true if an accelerator was processed by the
+ // focus manager
+#if defined(OS_WIN)
+ virtual bool Dispatch(const MSG& msg);
+#else
+ virtual bool Dispatch(GdkEvent* event);
+#if defined(TOUCH_UI)
+ virtual MessagePumpGlibXDispatcher::DispatchStatus Dispatch(XEvent* xev);
+#endif
+#endif
+
+ private:
+#if defined(OS_WIN)
+ // The keys currently pressed and consumed by the FocusManager.
+ std::set<WPARAM> pressed_keys_;
+#endif
+
+ DISALLOW_COPY_AND_ASSIGN(AcceleratorHandler);
+};
+
+} // namespace ui
+
+#endif // UI_VIEWS_FOCUS_ACCELERATOR_HANDLER_H_
diff --git a/ui/views/focus/accelerator_handler_win.cc b/ui/views/focus/accelerator_handler_win.cc
new file mode 100644
index 0000000..02bd097
--- /dev/null
+++ b/ui/views/focus/accelerator_handler_win.cc
@@ -0,0 +1,60 @@
+// 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 "ui/views/focus/accelerator_handler.h"
+
+#include "ui/base/keycodes/keyboard_codes.h"
+#include "ui/base/keycodes/keyboard_code_conversion_win.h"
+#include "ui/views/events/event.h"
+//#include "ui/views/focus/focus_manager.h"
+
+namespace ui {
+
+AcceleratorHandler::AcceleratorHandler() {
+}
+
+bool AcceleratorHandler::Dispatch(const MSG& msg) {
+ bool process_message = true;
+
+ if (msg.message >= WM_KEYFIRST && msg.message <= WM_KEYLAST) {
+ /*
+ FocusManager* focus_manager =
+ FocusManager::GetFocusManagerForNativeView(msg.hwnd);
+ if (focus_manager) {
+ switch (msg.message) {
+ case WM_KEYDOWN:
+ case WM_SYSKEYDOWN: {
+ process_message = focus_manager->OnKeyEvent(KeyEvent(msg));
+ if (!process_message) {
+ // Record that this key is pressed so we can remember not to
+ // translate and dispatch the associated WM_KEYUP.
+ pressed_keys_.insert(msg.wParam);
+ }
+ break;
+ }
+ case WM_KEYUP:
+ case WM_SYSKEYUP: {
+ std::set<WPARAM>::iterator iter = pressed_keys_.find(msg.wParam);
+ if (iter != pressed_keys_.end()) {
+ // Don't translate/dispatch the KEYUP since we have eaten the
+ // associated KEYDOWN.
+ pressed_keys_.erase(iter);
+ return true;
+ }
+ break;
+ }
+ }
+ }
+ */
+ }
+
+ if (process_message) {
+ TranslateMessage(&msg);
+ DispatchMessage(&msg);
+ }
+
+ return true;
+}
+
+} // namespace ui
diff --git a/ui/views/views.gyp b/ui/views/views.gyp
index fa9ad5a..63e00ae 100644
--- a/ui/views/views.gyp
+++ b/ui/views/views.gyp
@@ -56,6 +56,8 @@
'events/event.cc',
'events/event.h',
'events/event_win.cc',
+ 'focus/accelerator_handler.h',
+ 'focus/accelerator_handler_win.cc',
'layout/fill_layout.cc',
'layout/fill_layout.h',
'layout/layout_manager.cc',
@@ -120,6 +122,7 @@
'rendering/border_unittest.cc',
'run_all_unittests.cc',
'view_unittest.cc',
+ 'widget/native_widget_win_unittest.cc',
'widget/widget_unittest.cc',
],
'include_dirs': [
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;
}