summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsschmitz@chromium.org <sschmitz@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-01-25 01:22:54 +0000
committersschmitz@chromium.org <sschmitz@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-01-25 01:22:54 +0000
commit238a8ecfe67823c07675c5347fdfedd858cd23e3 (patch)
tree119b59409b1331d5c2e0e46d11d1ca4f04291fa3
parent58d57eb7e554dd78a2c88b7de93d3e29d7d21edc (diff)
downloadchromium_src-238a8ecfe67823c07675c5347fdfedd858cd23e3.zip
chromium_src-238a8ecfe67823c07675c5347fdfedd858cd23e3.tar.gz
chromium_src-238a8ecfe67823c07675c5347fdfedd858cd23e3.tar.bz2
context menu does not work if one already open
This improves how ChromeOS handles mouse button presses outside of a context menu. On mouse button presses not only is the context menu and is message loop exited, but the event is processed with the same result as if the context menu had not been present. For example, a window may be activated, another context menu may be brought up, a new tab button may be executed, etc. This CL does not yet handle touch events (separate issue). The behavior is now more similar to how it works on Windows. BUG=151074, 162172 TEST=manual Bring up various context menus, then click various mouse buttons outside of it. Review URL: https://chromiumcodereview.appspot.com/11761027 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@178717 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--ui/base/events/event.cc12
-rw-r--r--ui/views/controls/menu/menu_controller.cc29
-rw-r--r--ui/views/controls/menu/menu_controller.h3
3 files changed, 39 insertions, 5 deletions
diff --git a/ui/base/events/event.cc b/ui/base/events/event.cc
index eda682b..cffc21f 100644
--- a/ui/base/events/event.cc
+++ b/ui/base/events/event.cc
@@ -104,6 +104,14 @@ std::string EventTypeName(ui::EventType type) {
return std::string();
}
+bool IsX11SendEventTrue(const base::NativeEvent& event) {
+#if defined(USE_X11)
+ if (event && event->xany.send_event)
+ return true;
+#endif
+ return false;
+}
+
} // namespace
namespace ui {
@@ -317,7 +325,9 @@ bool MouseEvent::IsRepeatedClickEvent(
int MouseEvent::GetRepeatCount(const MouseEvent& event) {
int click_count = 1;
if (last_click_event_) {
- if (IsRepeatedClickEvent(*last_click_event_, event))
+ if (IsX11SendEventTrue(event.native_event()))
+ click_count = last_click_event_->GetClickCount();
+ else if (IsRepeatedClickEvent(*last_click_event_, event))
click_count = last_click_event_->GetClickCount() + 1;
delete last_click_event_;
}
diff --git a/ui/views/controls/menu/menu_controller.cc b/ui/views/controls/menu/menu_controller.cc
index ea8e446..cdeb37b 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;
@@ -803,9 +807,8 @@ void MenuController::SetSelectionOnPointerDown(SubmenuView* source,
// 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)
+#if (defined(OS_WIN) && !defined(USE_AURA)) || defined(USE_X11)
RepostEvent(source, event);
- // NOTE: not reposting on linux seems fine.
#endif
// And close.
@@ -1974,7 +1977,27 @@ void MenuController::RepostEvent(SubmenuView* source,
}
}
}
-#endif // defined(OS_WIN)
+#elif defined(USE_X11)
+void MenuController::RepostEvent(SubmenuView* source,
+ const ui::LocatedEvent& 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());
+ return;
+ }
+ if (!event.native_event())
+ return;
+ // We putback the X11 event. We set the "send_event" field in the
+ // XEvent. Otherwise a mouse click would generate a double click
+ // event. The field "send_event" is in the same place for all event
+ // types so we can use "xany" regardless of type.
+ XEvent xevent = *event.native_event();
+ xevent.xany.send_event = True;
+ XPutBackEvent(xevent.xany.display, &xevent);
+}
+#endif
void MenuController::SetDropMenuItem(
MenuItemView* new_target,
diff --git a/ui/views/controls/menu/menu_controller.h b/ui/views/controls/menu/menu_controller.h
index 891026f..1e5985c3 100644
--- a/ui/views/controls/menu/menu_controller.h
+++ b/ui/views/controls/menu/menu_controller.h
@@ -412,9 +412,10 @@ class VIEWS_EXPORT MenuController
// the title. Returns true if a match was selected and the menu should exit.
bool SelectByChar(char16 key);
-#if defined(OS_WIN) && !defined(USE_AURA)
+#if (defined(OS_WIN) && !defined(USE_AURA)) || defined(USE_X11)
// If there is a window at the location of the event, a new mouse event is
// generated and posted to it at the given location.
+ // For Chromeos this applies also to the desktop background window.
void RepostEvent(SubmenuView* source, const ui::LocatedEvent& event);
#endif