diff options
author | sky@chromium.org <sky@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-08-26 03:27:29 +0000 |
---|---|---|
committer | sky@chromium.org <sky@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-08-26 03:27:29 +0000 |
commit | c0cbacb7525dfb39b346f597d5c7947fa1f9f63b (patch) | |
tree | 95d16f97e42d0f5ffccc08b701e0e1b2fa1572dc /chrome/browser/automation/ui_controls_linux.cc | |
parent | 7bc5f1bb093daa602ac483051bd0071f8064779b (diff) | |
download | chromium_src-c0cbacb7525dfb39b346f597d5c7947fa1f9f63b.zip chromium_src-c0cbacb7525dfb39b346f597d5c7947fa1f9f63b.tar.gz chromium_src-c0cbacb7525dfb39b346f597d5c7947fa1f9f63b.tar.bz2 |
Couple of tweaks to ui_controls_linux:
. Moves listening from DidProcess to WillProcess. This is necessitated
by the bookmark bar (chrome menu) tests that spawn a nested run
loop, which results in DidProcess not getting sent and the test
wedging. This brings the code closer in line with Windows.
. If there is a mouse/keyboard grab, mouse/keyboard events are sent to
the grabbed widget.
. Deals with a NULL widget for sending keyboard events (tries to find
focused widget).
BUG=none
TEST=none
Review URL: http://codereview.chromium.org/173392
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@24420 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/automation/ui_controls_linux.cc')
-rw-r--r-- | chrome/browser/automation/ui_controls_linux.cc | 83 |
1 files changed, 73 insertions, 10 deletions
diff --git a/chrome/browser/automation/ui_controls_linux.cc b/chrome/browser/automation/ui_controls_linux.cc index bcaf6c5..9b5418e 100644 --- a/chrome/browser/automation/ui_controls_linux.cc +++ b/chrome/browser/automation/ui_controls_linux.cc @@ -13,6 +13,11 @@ #include "chrome/common/gtk_util.h" #include "chrome/test/automation/automation_constants.h" +#if defined(TOOLKIT_VIEWS) +#include "views/view.h" +#include "views/widget/widget.h" +#endif + namespace { guint32 EventTimeNow() { @@ -33,18 +38,26 @@ class EventWaiter : public MessageLoopForUI::Observer { // MessageLoop::Observer implementation: virtual void WillProcessEvent(GdkEvent* event) { - // No-op. + if (event->type == type_) { + // At the time we're invoked the event has not actually been processed. + // Use PostTask to make sure the event has been processed before + // notifying. + // NOTE: if processing a message results in running a nested message + // loop, then DidProcessEvent isn't immediately sent. As such, we do + // the processing in WillProcessEvent rather than DidProcessEvent. + MessageLoop::current()->PostTask(FROM_HERE, task_); + delete this; + } } virtual void DidProcessEvent(GdkEvent* event) { - if (event->any.type == type_) { - task_->Run(); - delete this; - } + // No-op. } private: - scoped_ptr<Task> task_; + // We pass ownership of task_ to MessageLoop when the corrent event is + // received. + Task *task_; GdkEventType type_; }; @@ -57,7 +70,10 @@ class ClickTask : public Task { virtual ~ClickTask() {} virtual void Run() { - ui_controls::SendMouseEventsNotifyWhenDone(button_, state_, followup_); + if (followup_) + ui_controls::SendMouseEventsNotifyWhenDone(button_, state_, followup_); + else + ui_controls::SendMouseEvents(button_, state_); } private: @@ -76,7 +92,25 @@ bool SendKeyPress(gfx::NativeWindow window, GdkEvent* event = gdk_event_new(GDK_KEY_PRESS); event->key.type = GDK_KEY_PRESS; - event->key.window = GTK_WIDGET(window)->window; + GtkWidget* grab_widget = gtk_grab_get_current(); + if (grab_widget) { + // If there is a grab, send all events to the grabbed widget. + event->key.window = grab_widget->window; + } else if (window) { + event->key.window = GTK_WIDGET(window)->window; + } else { + // No target was specified. Send the events to the focused window. + GList* windows = gtk_window_list_toplevels(); + for (GList* element = windows; element; element = g_list_next(element)) { + GtkWindow* window = GTK_WINDOW(element->data); + if (gtk_window_is_active(window)) { + event->key.window = GTK_WIDGET(window)->window; + break; + } + } + g_list_free(windows); + } + DCHECK(event->key.window); g_object_ref(event->key.window); event->key.send_event = false; event->key.time = EventTimeNow(); @@ -136,7 +170,15 @@ bool SendMouseEvents(MouseButton type, int state) { event->button.time = EventTimeNow(); gint x, y; - event->button.window = gdk_window_at_pointer(&x, &y); + GtkWidget* grab_widget = gtk_grab_get_current(); + if (grab_widget) { + // If there is a grab, we need to target all events at it regardless of + // what widget the mouse is over. + event->button.window = grab_widget->window; + gdk_window_get_pointer(event->button.window, &x, &y, NULL); + } else { + event->button.window = gdk_window_at_pointer(&x, &y); + } g_object_ref(event->button.window); event->motion.x = x; event->motion.y = y; @@ -170,7 +212,18 @@ bool SendMouseEvents(MouseButton type, int state) { bool SendMouseEventsNotifyWhenDone(MouseButton type, int state, Task* task) { bool rv = SendMouseEvents(type, state); - MessageLoop::current()->PostTask(FROM_HERE, task); + GdkEventType wait_type; + if (state & UP) { + wait_type = GDK_BUTTON_RELEASE; + } else { + if (type == LEFT) + wait_type = GDK_BUTTON_PRESS; + else if (type == MIDDLE) + wait_type = GDK_2BUTTON_PRESS; + else + wait_type = GDK_3BUTTON_PRESS; + } + new EventWaiter(task, wait_type); return rv; } @@ -178,6 +231,15 @@ bool SendMouseClick(MouseButton type) { return SendMouseEvents(type, UP | DOWN); } +#if defined(TOOLKIT_VIEWS) +void MoveMouseToCenterAndPress(views::View* view, MouseButton button, + int state, Task* task) { + gfx::Point view_center(view->width() / 2, view->height() / 2); + views::View::ConvertPointToScreen(view, &view_center); + SendMouseMoveNotifyWhenDone(view_center.x(), view_center.y(), + new ClickTask(button, state, task)); +} +#else void MoveMouseToCenterAndPress(GtkWidget* widget, MouseButton button, int state, @@ -187,5 +249,6 @@ void MoveMouseToCenterAndPress(GtkWidget* widget, bounds.y() + bounds.height() / 2, new ClickTask(button, state, task)); } +#endif } // namespace ui_controls |