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 0fe8fbb63b51164b3cf9fc373cc6960cf76ef4fc..bd7ad055f224801012882f9b7853b7fddcf2a3fa 100644 |
--- a/ui/views/controls/menu/menu_controller.cc |
+++ b/ui/views/controls/menu/menu_controller.cc |
@@ -34,6 +34,10 @@ |
#include "ui/aura/window.h" |
#endif |
+#if defined(USE_X11) |
+#include <X11/Xlib.h> |
+#endif |
+ |
using base::Time; |
using base::TimeDelta; |
using ui::OSExchangeData; |
@@ -800,15 +804,6 @@ void MenuController::SetSelectionOnPointerDown(SubmenuView* source, |
part.menu->GetRootMenuItem() != state_.item->GetRootMenuItem())) { |
// Mouse wasn't pressed over any menu, or the active menu, cancel. |
- // 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 defined(OS_WIN) && !defined(USE_AURA) |
- RepostEvent(source, event); |
- // NOTE: not reposting on linux seems fine. |
-#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 |
@@ -820,7 +815,33 @@ void MenuController::SetSelectionOnPointerDown(SubmenuView* source, |
if (last_part.type != MenuPart::NONE) |
exit_type = EXIT_OUTERMOST; |
} |
+ |
+#if defined(OS_WIN) && !defined(USE_AURA) |
+ // 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); |
+#elif defined(USE_X11) |
+ if (exit_type == EXIT_ALL && state_.item && event.native_event()) { |
+ // We will putback the X11 event here, so that the usual |
+ // action (e.g. window activation, new context menu) happens |
+ // after this context menu and its message loop have exited. We |
+ // do not want mouse button events treated as double clicks. |
+ // Without the following special precaution a "put back" mouse |
+ // button event will result in a double click. We use the |
+ // "send_event" flag. When this event is processed later on, the |
+ // flag is used to avoid treating it as a double click. The |
+ // field "send_event" is in the same place for all event types |
+ // so we can use "xany" regardless of event type. |
+ XEvent xevent = *event.native_event(); |
+ xevent.xany.send_event = True; |
+ XPutBackEvent(xevent.xany.display, &xevent); |
+ } |
+#endif |
+ |
+ // And close. |
Cancel(exit_type); |
+ |
return; |
} |