| Index: chrome/browser/automation/ui_controls_linux.cc
|
| ===================================================================
|
| --- chrome/browser/automation/ui_controls_linux.cc (revision 24301)
|
| +++ chrome/browser/automation/ui_controls_linux.cc (working copy)
|
| @@ -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 @@
|
|
|
| // 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 @@
|
| 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 @@
|
| 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 @@
|
| 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 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 @@
|
| 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 @@
|
| bounds.y() + bounds.height() / 2,
|
| new ClickTask(button, state, task));
|
| }
|
| +#endif
|
|
|
| } // namespace ui_controls
|
|
|