summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordbeam@chromium.org <dbeam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-04-23 23:12:28 +0000
committerdbeam@chromium.org <dbeam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-04-23 23:12:28 +0000
commit0dd77f9c9ee45dd576907ab978ae7288e75ad4d0 (patch)
tree3b6aa165679b1424d0cf0a4ff120b4f19cbc6bb7
parent8a92485b119e1af072f3f015fcac43edf1274c19 (diff)
downloadchromium_src-0dd77f9c9ee45dd576907ab978ae7288e75ad4d0.zip
chromium_src-0dd77f9c9ee45dd576907ab978ae7288e75ad4d0.tar.gz
chromium_src-0dd77f9c9ee45dd576907ab978ae7288e75ad4d0.tar.bz2
views: move native event reposting back to MenuController as it's the only
caller now. R=sky@chromium.org BUG=259529 Review URL: https://codereview.chromium.org/245993005 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@265765 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--ui/views/controls/menu/menu_controller.cc127
-rw-r--r--ui/views/event_utils.h33
-rw-r--r--ui/views/event_utils_aura.cc70
-rw-r--r--ui/views/event_utils_win.cc59
-rw-r--r--ui/views/views.gyp3
5 files changed, 89 insertions, 203 deletions
diff --git a/ui/views/controls/menu/menu_controller.cc b/ui/views/controls/menu/menu_controller.cc
index 1861724..a63448d 100644
--- a/ui/views/controls/menu/menu_controller.cc
+++ b/ui/views/controls/menu/menu_controller.cc
@@ -13,18 +13,21 @@
#include "base/run_loop.h"
#include "base/strings/utf_string_conversions.h"
#include "base/time/time.h"
+#include "ui/aura/client/screen_position_client.h"
#include "ui/aura/env.h"
#include "ui/aura/window.h"
#include "ui/aura/window_event_dispatcher.h"
+#include "ui/aura/window_tree_host.h"
#include "ui/base/dragdrop/drag_utils.h"
#include "ui/base/dragdrop/os_exchange_data.h"
#include "ui/base/l10n/l10n_util.h"
-#include "ui/events/event_constants.h"
+#include "ui/events/event.h"
#include "ui/events/event_utils.h"
#include "ui/events/platform/platform_event_source.h"
#include "ui/events/platform/scoped_event_dispatcher.h"
#include "ui/gfx/canvas.h"
#include "ui/gfx/native_widget_types.h"
+#include "ui/gfx/point.h"
#include "ui/gfx/screen.h"
#include "ui/gfx/vector2d.h"
#include "ui/native_theme/native_theme.h"
@@ -35,9 +38,9 @@
#include "ui/views/controls/menu/menu_scroll_view_container.h"
#include "ui/views/controls/menu/submenu_view.h"
#include "ui/views/drag_utils.h"
-#include "ui/views/event_utils.h"
#include "ui/views/focus/view_storage.h"
#include "ui/views/mouse_constants.h"
+#include "ui/views/view.h"
#include "ui/views/view_constants.h"
#include "ui/views/views_delegate.h"
#include "ui/views/widget/root_view.h"
@@ -56,6 +59,7 @@
#include "ui/views/controls/menu/menu_event_dispatcher_linux.h"
#endif
+using aura::client::ScreenPositionClient;
using base::Time;
using base::TimeDelta;
using ui::OSExchangeData;
@@ -973,14 +977,7 @@ void MenuController::SetSelectionOnPointerDown(SubmenuView* source,
#if defined(OS_WIN)
// We're going to close and we own the mouse capture. We need to repost the
// mouse down, otherwise the window the user clicked on won't get the event.
- if (!state_.item) {
- // We some times get an event after closing all the menus. Ignore it. Make
- // sure the menu is in fact not visible. If the menu is visible, then
- // we're in a bad state where we think the menu isn't visibile but it is.
- DCHECK(!source->GetWidget()->IsVisible());
- } else {
- RepostEvent(source, event);
- }
+ RepostEvent(source, event);
#endif
// And close.
@@ -2145,52 +2142,106 @@ bool MenuController::SelectByChar(base::char16 character) {
void MenuController::RepostEvent(SubmenuView* source,
const ui::LocatedEvent& event) {
+ if (!event.IsMouseEvent()) {
+ // TODO(rbyers): Gesture event repost is tricky to get right
+ // crbug.com/170987.
+ DCHECK(event.IsGestureEvent());
+ return;
+ }
+
+#if defined(OS_WIN)
+ if (!state_.item) {
+ // We some times get an event after closing all the menus. Ignore it. Make
+ // sure the menu is in fact not visible. If the menu is visible, then
+ // we're in a bad state where we think the menu isn't visibile but it is.
+ DCHECK(!source->GetWidget()->IsVisible());
+ return;
+ }
+
+ state_.item->GetRootMenuItem()->GetSubmenu()->ReleaseCapture();
+#endif
+
gfx::Point screen_loc(event.location());
View::ConvertPointToScreen(source->GetScrollViewContainer(), &screen_loc);
-
gfx::NativeView native_view = source->GetWidget()->GetNativeView();
+ if (!native_view)
+ return;
+
gfx::Screen* screen = gfx::Screen::GetScreenFor(native_view);
gfx::NativeWindow window = screen->GetWindowAtScreenPoint(screen_loc);
- // On Windows, it is ok for window to be NULL. Please refer to the
- // RepostLocatedEvent function for more information.
#if defined(OS_WIN)
- // Release the capture.
- SubmenuView* submenu = state_.item->GetRootMenuItem()->GetSubmenu();
- submenu->ReleaseCapture();
-
- gfx::NativeView view = submenu->GetWidget()->GetNativeView();
- if (view && window) {
- DWORD view_tid = GetWindowThreadProcessId(HWNDForNativeView(view), NULL);
- if (view_tid != GetWindowThreadProcessId(HWNDForNativeView(window), NULL)) {
+ // PostMessage() to metro windows isn't allowed (access will be denied). Don't
+ // try to repost with Win32 if the window under the mouse press is in metro.
+ if (!ViewsDelegate::views_delegate ||
+ !ViewsDelegate::views_delegate->IsWindowInMetro(window)) {
+ HWND target_window = window ? HWNDForNativeWindow(window) :
+ WindowFromPoint(screen_loc.ToPOINT());
+ HWND source_window = HWNDForNativeView(native_view);
+ if (!target_window || !source_window ||
+ GetWindowThreadProcessId(source_window, NULL) !=
+ GetWindowThreadProcessId(target_window, NULL)) {
// Even though we have mouse capture, windows generates a mouse event if
// the other window is in a separate thread. Only repost an event if
- // |view| was created on the same thread, else the target window can get
- // double events leading to bad behavior.
+ // |target_window| and |source_window| were created on the same thread,
+ // else double events can occur and lead to bad behavior.
return;
}
+
+ // Determine whether the click was in the client area or not.
+ // NOTE: WM_NCHITTEST coordinates are relative to the screen.
+ LPARAM coords = MAKELPARAM(screen_loc.x(), screen_loc.y());
+ LRESULT nc_hit_result = SendMessage(target_window, WM_NCHITTEST, 0, coords);
+ const bool client_area = nc_hit_result == HTCLIENT;
+
+ // TODO(sky): this isn't right. The event to generate should correspond with
+ // the event we just got. MouseEvent only tells us what is down, which may
+ // differ. Need to add ability to get changed button from MouseEvent.
+ int event_type;
+ int flags = event.flags();
+ if (flags & ui::EF_LEFT_MOUSE_BUTTON) {
+ event_type = client_area ? WM_LBUTTONDOWN : WM_NCLBUTTONDOWN;
+ } else if (flags & ui::EF_MIDDLE_MOUSE_BUTTON) {
+ event_type = client_area ? WM_MBUTTONDOWN : WM_NCMBUTTONDOWN;
+ } else if (flags & ui::EF_RIGHT_MOUSE_BUTTON) {
+ event_type = client_area ? WM_RBUTTONDOWN : WM_NCRBUTTONDOWN;
+ } else {
+ NOTREACHED();
+ return;
+ }
+
+ int window_x = screen_loc.x();
+ int window_y = screen_loc.y();
+ if (client_area) {
+ POINT pt = { window_x, window_y };
+ ScreenToClient(target_window, &pt);
+ window_x = pt.x;
+ window_y = pt.y;
+ }
+
+ WPARAM target = client_area ? event.native_event().wParam : nc_hit_result;
+ LPARAM window_coords = MAKELPARAM(window_x, window_y);
+ PostMessage(target_window, event_type, target, window_coords);
+ return;
}
-#else
+#endif
+ // Non-Windows Aura or |window| is in metro mode.
if (!window)
return;
-#endif
- scoped_ptr<ui::LocatedEvent> clone;
- if (event.IsMouseEvent()) {
- clone.reset(new ui::MouseEvent(static_cast<const ui::MouseEvent&>(event)));
- } else if (event.IsGestureEvent()) {
- // TODO(rbyers): Gesture event repost is tricky to get right
- // crbug.com/170987.
+ aura::Window* root = window->GetRootWindow();
+ ScreenPositionClient* spc = aura::client::GetScreenPositionClient(root);
+ if (!spc)
return;
- } else {
- NOTREACHED();
- return;
- }
- clone->set_location(screen_loc);
- RepostLocatedEvent(window, *clone);
-}
+ gfx::Point root_loc(screen_loc);
+ spc->ConvertPointFromScreen(root, &root_loc);
+ ui::MouseEvent clone(static_cast<const ui::MouseEvent&>(event));
+ clone.set_location(root_loc);
+ clone.set_root_location(root_loc);
+ root->GetHost()->dispatcher()->RepostEvent(clone);
+}
void MenuController::SetDropMenuItem(
MenuItemView* new_target,
diff --git a/ui/views/event_utils.h b/ui/views/event_utils.h
deleted file mode 100644
index 03bf65b..0000000
--- a/ui/views/event_utils.h
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright 2013 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_EVENT_UTILS_H_
-#define UI_VIEWS_EVENT_UTILS_H_
-
-#include "ui/gfx/native_widget_types.h"
-#include "ui/views/views_export.h"
-
-namespace ui {
-class LocatedEvent;
-}
-
-namespace views {
-
-// Reposts a located event natively. Returns false when |event| could not be
-// reposted. |event| should be in screen coordinates. |window| is the target
-// window that the event will be forwarded to. Only some events are supported.
-// On Windows |window| can be NULL, in which case the event is forwarded to
-// the HWND at the current location if it is on the same thread.
-VIEWS_EXPORT bool RepostLocatedEvent(gfx::NativeWindow window,
- const ui::LocatedEvent& event);
-
-#if defined(OS_WIN)
-// Reposts a located event to the HWND passed in.
-VIEWS_EXPORT bool RepostLocatedEventWin(HWND window,
- const ui::LocatedEvent& event);
-#endif
-
-} // namespace views
-
-#endif // UI_VIEWS_EVENT_UTILS_H_
diff --git a/ui/views/event_utils_aura.cc b/ui/views/event_utils_aura.cc
deleted file mode 100644
index 5e93e8e..0000000
--- a/ui/views/event_utils_aura.cc
+++ /dev/null
@@ -1,70 +0,0 @@
-// Copyright 2013 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/event_utils.h"
-
-#include "base/logging.h"
-#include "base/memory/scoped_ptr.h"
-#include "ui/aura/client/screen_position_client.h"
-#include "ui/aura/window_event_dispatcher.h"
-#include "ui/aura/window_tree_host.h"
-#include "ui/events/event.h"
-#include "ui/gfx/point.h"
-#include "ui/views/views_delegate.h"
-
-using aura::client::ScreenPositionClient;
-
-namespace views {
-
-bool RepostLocatedEvent(gfx::NativeWindow window,
- const ui::LocatedEvent& event) {
-#if defined(OS_WIN)
- // On Windows, if the |window| parameter is NULL, then we attempt to repost
- // the event to the window at the current location, if it is on the current
- // thread.
- HWND target_window = NULL;
- if (!window) {
- target_window = ::WindowFromPoint(event.location().ToPOINT());
- if (::GetWindowThreadProcessId(target_window, NULL) !=
- ::GetCurrentThreadId())
- return false;
- } else {
- if (ViewsDelegate::views_delegate &&
- !ViewsDelegate::views_delegate->IsWindowInMetro(window))
- target_window = window->GetHost()->GetAcceleratedWidget();
- }
- return RepostLocatedEventWin(target_window, event);
-#else
- if (!window)
- return false;
-
- aura::Window* root_window = window->GetRootWindow();
-
- gfx::Point root_loc(event.location());
- ScreenPositionClient* spc =
- aura::client::GetScreenPositionClient(root_window);
- if (!spc)
- return false;
-
- spc->ConvertPointFromScreen(root_window, &root_loc);
-
- scoped_ptr<ui::LocatedEvent> relocated;
- if (!event.IsMouseEvent()) {
- // TODO(rbyers): Gesture event repost is tricky to get right
- // crbug.com/170987.
- DCHECK(event.IsGestureEvent());
- return false;
- }
-
- const ui::MouseEvent& orig = static_cast<const ui::MouseEvent&>(event);
- relocated.reset(new ui::MouseEvent(orig));
- relocated->set_location(root_loc);
- relocated->set_root_location(root_loc);
-
- root_window->GetHost()->dispatcher()->RepostEvent(*relocated);
- return true;
-#endif
-}
-
-} // namespace views
diff --git a/ui/views/event_utils_win.cc b/ui/views/event_utils_win.cc
deleted file mode 100644
index 78cb9df..0000000
--- a/ui/views/event_utils_win.cc
+++ /dev/null
@@ -1,59 +0,0 @@
-// Copyright 2013 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/event_utils.h"
-
-#include <windowsx.h>
-
-#include "base/logging.h"
-#include "ui/events/event.h"
-#include "ui/events/event_constants.h"
-#include "ui/gfx/point.h"
-
-namespace views {
-
-bool RepostLocatedEventWin(HWND window,
- const ui::LocatedEvent& event) {
- if (!window)
- return false;
-
- // Determine whether the click was in the client area or not.
- // NOTE: WM_NCHITTEST coordinates are relative to the screen.
- const gfx::Point screen_loc = event.location();
- LRESULT nc_hit_result = SendMessage(window, WM_NCHITTEST, 0,
- MAKELPARAM(screen_loc.x(),
- screen_loc.y()));
- const bool in_client_area = nc_hit_result == HTCLIENT;
-
- // TODO(sky): this isn't right. The event to generate should correspond with
- // the event we just got. MouseEvent only tells us what is down, which may
- // differ. Need to add ability to get changed button from MouseEvent.
- int event_type;
- int flags = event.flags();
- if (flags & ui::EF_LEFT_MOUSE_BUTTON) {
- event_type = in_client_area ? WM_LBUTTONDOWN : WM_NCLBUTTONDOWN;
- } else if (flags & ui::EF_MIDDLE_MOUSE_BUTTON) {
- event_type = in_client_area ? WM_MBUTTONDOWN : WM_NCMBUTTONDOWN;
- } else if (flags & ui::EF_RIGHT_MOUSE_BUTTON) {
- event_type = in_client_area ? WM_RBUTTONDOWN : WM_NCRBUTTONDOWN;
- } else {
- NOTREACHED();
- return false;
- }
-
- int window_x = screen_loc.x();
- int window_y = screen_loc.y();
- if (in_client_area) {
- POINT pt = {window_x, window_y};
- ScreenToClient(window, &pt);
- window_x = pt.x;
- window_y = pt.y;
- }
-
- WPARAM target = in_client_area ? event.native_event().wParam : nc_hit_result;
- PostMessage(window, event_type, target, MAKELPARAM(window_x, window_y));
- return true;
-}
-
-} // namespace views
diff --git a/ui/views/views.gyp b/ui/views/views.gyp
index e3a2e93..f553d25 100644
--- a/ui/views/views.gyp
+++ b/ui/views/views.gyp
@@ -232,9 +232,6 @@
'drag_controller.h',
'drag_utils.cc',
'drag_utils.h',
- 'event_utils.h',
- 'event_utils_aura.cc',
- 'event_utils_win.cc',
'focus/external_focus_tracker.cc',
'focus/external_focus_tracker.h',
'focus/focus_manager.cc',