Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(104)

Unified Diff: ui/views/controls/menu/menu_controller.cc

Issue 1586353004: Update reposting of events from menus (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « ui/views/controls/menu/menu_controller.h ('k') | ui/views/controls/menu/menu_controller_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: ui/views/controls/menu/menu_controller.cc
diff --git a/ui/views/controls/menu/menu_controller.cc b/ui/views/controls/menu/menu_controller.cc
index d16553b880d9fa4d0f36645ab2febab82ef4366f..10b2cd914e768af579dec903fc6996c741838c10 100644
--- a/ui/views/controls/menu/menu_controller.cc
+++ b/ui/views/controls/menu/menu_controller.cc
@@ -679,7 +679,7 @@ void MenuController::OnTouchEvent(SubmenuView* source, ui::TouchEvent* event) {
if (event->type() == ui::ET_TOUCH_PRESSED) {
MenuPart part = GetMenuPart(source, event->location());
if (part.type == MenuPart::NONE) {
- RepostEvent(source, event);
+ RepostEventAndCancel(source, event);
event->SetHandled();
}
}
@@ -1001,36 +1001,8 @@ void MenuController::SetSelectionOnPointerDown(SubmenuView* source,
// then use this to figure out if this menu was finished with the same click
// which is sent to it thereafter.
closing_event_time_ = event->time_stamp();
-
- // Mouse wasn't pressed over any menu, or the active menu, cancel.
-
-#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.
- RepostEvent(source, event);
-#endif
-
- // And close.
- ExitType exit_type = EXIT_ALL;
- if (!menu_stack_.empty()) {
- // We're running nested menus. Only exit all if the mouse wasn't over one
- // of the menus from the last run.
- gfx::Point screen_loc(event->location());
- View::ConvertPointToScreen(source->GetScrollViewContainer(), &screen_loc);
- MenuPart last_part = GetMenuPartByScreenCoordinateUsingMenu(
- menu_stack_.back().first.item, screen_loc);
- if (last_part.type != MenuPart::NONE)
- exit_type = EXIT_OUTERMOST;
- }
- Cancel(exit_type);
-
-#if defined(OS_CHROMEOS)
- // We're going to exit the menu and want to repost the event so that is
- // is handled normally after the context menu has exited. We call
- // RepostEvent after Cancel so that mouse capture has been released so
- // that finding the event target is unaffected by the current capture.
- RepostEvent(source, event);
-#endif
+ // Event wasn't pressed over any menu, or the active menu, cancel.
+ RepostEventAndCancel(source, event);
// Do not repost events for Linux Aura because this behavior is more
// consistent with the behavior of other Linux apps.
return;
@@ -2188,7 +2160,10 @@ void MenuController::SelectByChar(base::char16 character) {
}
void MenuController::RepostEvent(SubmenuView* source,
- const ui::LocatedEvent* event) {
+ const ui::LocatedEvent* event,
+ const gfx::Point& screen_loc,
+ gfx::NativeView native_view,
+ gfx::NativeWindow window) {
if (!event->IsMouseEvent() && !event->IsTouchEvent()) {
// TODO(rbyers): Gesture event repost is tricky to get right
// crbug.com/170987.
@@ -2208,15 +2183,9 @@ void MenuController::RepostEvent(SubmenuView* source,
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);
-
#if defined(OS_WIN)
gfx::Point screen_loc_pixels = gfx::win::DIPToScreenPoint(screen_loc);
HWND target_window = ::WindowFromPoint(screen_loc_pixels.ToPOINT());
@@ -2294,6 +2263,47 @@ void MenuController::RepostEvent(SubmenuView* source,
MenuMessageLoop::RepostEventToWindow(event, window, screen_loc);
}
+void MenuController::RepostEventAndCancel(SubmenuView* source,
+ const ui::LocatedEvent* event) {
+ // Cancel can lead to the deletion |source| so we save the view and window to
+ // be used when reposting the event.
+ gfx::Point screen_loc(event->location());
+ View::ConvertPointToScreen(source->GetScrollViewContainer(), &screen_loc);
+ gfx::NativeView native_view = source->GetWidget()->GetNativeView();
+ gfx::NativeWindow window = nullptr;
+ if (native_view) {
+ gfx::Screen* screen = gfx::Screen::GetScreenFor(native_view);
+ window = screen->GetWindowAtScreenPoint(screen_loc);
+ }
+
+#if defined(OS_WIN)
+ // We're going to close and we own the event capture. We need to repost the
+ // event, otherwise the window the user clicked on won't get the event.
+ RepostEvent(source, event, screen_loc, native_view, window);
+#endif
+
+ // Determine target to see if a complete or partial close of the menu should
+ // occur.
+ ExitType exit_type = EXIT_ALL;
+ if (!menu_stack_.empty()) {
+ // We're running nested menus. Only exit all if the mouse wasn't over one
+ // of the menus from the last run.
+ MenuPart last_part = GetMenuPartByScreenCoordinateUsingMenu(
+ menu_stack_.back().first.item, screen_loc);
+ if (last_part.type != MenuPart::NONE)
+ exit_type = EXIT_OUTERMOST;
+ }
+ Cancel(exit_type);
+
+#if defined(OS_CHROMEOS)
+ // We're going to exit the menu and want to repost the event so that is
+ // is handled normally after the context menu has exited. We call
+ // RepostEvent after Cancel so that event capture has been released so
+ // that finding the event target is unaffected by the current capture.
+ RepostEvent(source, event, screen_loc, native_view, window);
+#endif
+}
+
void MenuController::SetDropMenuItem(
MenuItemView* new_target,
MenuDelegate::DropPosition new_position) {
« no previous file with comments | « ui/views/controls/menu/menu_controller.h ('k') | ui/views/controls/menu/menu_controller_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698