Index: chrome/browser/automation/ui_controls_linux.cc |
=================================================================== |
--- chrome/browser/automation/ui_controls_linux.cc (revision 23786) |
+++ chrome/browser/automation/ui_controls_linux.cc (working copy) |
@@ -13,6 +13,12 @@ |
namespace { |
+guint32 EventTimeNow() { |
+ struct timespec ts; |
+ clock_gettime(CLOCK_MONOTONIC, &ts); |
+ return ts.tv_sec * 1000 + ts.tv_nsec / 1000000; |
+} |
+ |
class EventWaiter : public MessageLoopForUI::Observer { |
public: |
EventWaiter(Task* task, GdkEventType type) : task_(task), type_(type) { |
@@ -36,7 +42,7 @@ |
} |
private: |
- Task* task_; |
+ scoped_ptr<Task> task_; |
GdkEventType type_; |
}; |
@@ -53,11 +59,8 @@ |
event->key.window = GTK_WIDGET(window)->window; |
g_object_ref(event->key.window); |
event->key.send_event = false; |
+ event->key.time = EventTimeNow(); |
- struct timespec ts; |
- clock_gettime(CLOCK_MONOTONIC, &ts); |
- event->key.time = ts.tv_sec * 1000 + ts.tv_nsec / 1000000; |
- |
// TODO(estade): handle other state flags besides control, shift, alt? |
// For example caps lock. |
event->key.state = (control ? GDK_CONTROL_MASK : 0) | |
@@ -90,30 +93,55 @@ |
return SendKeyPress(window, key, control, shift, alt); |
} |
-// TODO(estade): this appears to be unused on Windows. Can we remove it? |
-bool SendKeyDown(wchar_t key) { |
- NOTIMPLEMENTED(); |
- return false; |
+bool SendMouseMove(long x, long y) { |
+ gdk_display_warp_pointer(gdk_display_get_default(), gdk_screen_get_default(), |
+ x, y); |
+ return true; |
} |
-// TODO(estade): this appears to be unused on Windows. Can we remove it? |
-bool SendKeyUp(wchar_t key) { |
- NOTIMPLEMENTED(); |
- return false; |
+bool SendMouseMoveNotifyWhenDone(long x, long y, Task* task) { |
+ bool rv = SendMouseMove(x, y); |
+ // We can't rely on any particular event signalling the completion of the |
+ // mouse move. Posting the task to the message loop should gaurantee |
+ // the pointer has moved before task is run (although it may not run it as |
+ // soon as it could). |
+ MessageLoop::current()->PostTask(FROM_HERE, task); |
+ return rv; |
} |
-bool SendMouseMove(long x, long y) { |
- NOTIMPLEMENTED(); |
- return false; |
-} |
+bool SendMouseClick(const gfx::Point& point, MouseButton type) { |
+ GdkEvent* event = gdk_event_new(GDK_BUTTON_PRESS); |
-void SendMouseMoveNotifyWhenDone(long x, long y, Task* task) { |
- NOTIMPLEMENTED(); |
-} |
+ event->button.window = gdk_window_at_pointer(NULL, NULL); |
+ g_object_ref(event->button.window); |
+ event->button.send_event = false; |
+ event->button.time = EventTimeNow(); |
-bool SendMouseClick(gfx::NativeWindow window, const gfx::Point& point, |
- MouseButton type) { |
- NOTIMPLEMENTED(); |
+ event->motion.x_root = point.x(); |
+ event->motion.y_root = point.x(); |
+ gint origin_x, origin_y; |
+ gdk_window_get_origin(event->button.window, &origin_x, &origin_y); |
+ event->button.x = point.x() - origin_x; |
+ event->button.y = point.y() - origin_y; |
+ |
+ event->button.axes = NULL; |
+ // TODO(estade): as above, we may want to pack this with the actual state. |
+ event->button.state = 0; |
+ event->button.button = type == LEFT ? 1 : (type == MIDDLE ? 2 : 3); |
+ event->button.device = gdk_device_get_core_pointer(); |
+ |
+ event->button.type = GDK_BUTTON_PRESS; |
+ gdk_event_put(event); |
+ |
+ // Also send a release event. |
+ GdkEvent* release_event = gdk_event_copy(event); |
+ release_event->button.type = GDK_BUTTON_RELEASE; |
+ release_event->button.time++; |
+ gdk_event_put(release_event); |
+ |
+ gdk_event_free(event); |
+ gdk_event_free(release_event); |
+ |
return false; |
} |