| 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;
|
| }
|
|
|
|
|