| Index: chrome/browser/automation/automation_provider_gtk.cc
|
| diff --git a/chrome/browser/automation/automation_provider_gtk.cc b/chrome/browser/automation/automation_provider_gtk.cc
|
| index 11b6d31539439a82c61744ce0acfb84a91ef0692..0dfec43f7a1041f72a38c4bed5eda1c01064a011 100644
|
| --- a/chrome/browser/automation/automation_provider_gtk.cc
|
| +++ b/chrome/browser/automation/automation_provider_gtk.cc
|
| @@ -6,6 +6,9 @@
|
|
|
| #include <gtk/gtk.h>
|
|
|
| +#include "base/bind.h"
|
| +#include "base/bind_helpers.h"
|
| +#include "base/callback.h"
|
| #include "base/utf_string_conversions.h"
|
| #include "chrome/browser/automation/automation_browser_tracker.h"
|
| #include "chrome/browser/automation/automation_window_tracker.h"
|
| @@ -18,90 +21,21 @@
|
| #include "ui/gfx/point.h"
|
| #include "ui/gfx/rect.h"
|
|
|
| -void AutomationProvider::PrintAsync(int tab_handle) {
|
| - NOTIMPLEMENTED();
|
| -}
|
| -
|
| -// This task sends a WindowDragResponse message with the appropriate
|
| -// routing ID to the automation proxy. This is implemented as a task so that
|
| -// we know that the mouse events (and any tasks that they spawn on the message
|
| -// loop) have been processed by the time this is sent.
|
| -class WindowDragResponseTask : public Task {
|
| - public:
|
| - WindowDragResponseTask(AutomationProvider* provider,
|
| - IPC::Message* reply_message)
|
| - : provider_(provider),
|
| - reply_message_(reply_message) {
|
| - DCHECK(provider_);
|
| - DCHECK(reply_message_);
|
| - }
|
| -
|
| - virtual ~WindowDragResponseTask() {
|
| - }
|
| +namespace {
|
|
|
| - virtual void Run() {
|
| - AutomationMsg_WindowDrag::WriteReplyParams(reply_message_, true);
|
| - provider_->Send(reply_message_);
|
| - }
|
| -
|
| - private:
|
| - AutomationProvider* provider_;
|
| - IPC::Message* reply_message_;
|
| -
|
| - DISALLOW_COPY_AND_ASSIGN(WindowDragResponseTask);
|
| -};
|
| -
|
| -// A task that just runs a SendMouseEvent and performs another task when done.
|
| -class MouseEventTask : public Task {
|
| - public:
|
| - MouseEventTask(Task* next_task, ui_controls::MouseButtonState state)
|
| - : next_task_(next_task),
|
| - state_(state) {}
|
| -
|
| - virtual ~MouseEventTask() {
|
| - }
|
| -
|
| - virtual void Run() {
|
| - ui_controls::SendMouseEventsNotifyWhenDone(ui_controls::LEFT, state_,
|
| - next_task_);
|
| - }
|
| -
|
| - private:
|
| - // The task to execute when we are done.
|
| - Task* next_task_;
|
| -
|
| - // Mouse press or mouse release.
|
| - ui_controls::MouseButtonState state_;
|
| -
|
| - DISALLOW_COPY_AND_ASSIGN(MouseEventTask);
|
| -};
|
| -
|
| -// A task that just runs a SendMouseMove and performs another task when done.
|
| -class MouseMoveTask : public Task {
|
| - public:
|
| - MouseMoveTask(Task* next_task, int absolute_x, int absolute_y)
|
| - : next_task_(next_task),
|
| - x_(absolute_x),
|
| - y_(absolute_y) {
|
| - }
|
| -
|
| - virtual ~MouseMoveTask() {
|
| - }
|
| -
|
| - virtual void Run() {
|
| - ui_controls::SendMouseMoveNotifyWhenDone(x_, y_, next_task_);
|
| - }
|
| -
|
| - private:
|
| - // The task to execute when we are done.
|
| - Task* next_task_;
|
| +// This function sends a WindowDragResponse message with the appropriate routing
|
| +// ID to the automation proxy.
|
| +void SendWindowDragResponse(AutomationProvider* provider,
|
| + IPC::Message* reply_message) {
|
| + AutomationMsg_WindowDrag::WriteReplyParams(reply_message, true);
|
| + provider->Send(reply_message);
|
| +}
|
|
|
| - // Coordinates of the press.
|
| - int x_;
|
| - int y_;
|
| +} // namespace
|
|
|
| - DISALLOW_COPY_AND_ASSIGN(MouseMoveTask);
|
| -};
|
| +void AutomationProvider::PrintAsync(int tab_handle) {
|
| + NOTIMPLEMENTED();
|
| +}
|
|
|
| void AutomationProvider::WindowSimulateDrag(
|
| int handle,
|
| @@ -117,9 +51,14 @@ void AutomationProvider::WindowSimulateDrag(
|
| gdk_window_get_position(GTK_WIDGET(window)->window, &x, &y);
|
|
|
| // Create a nested stack of tasks to run.
|
| - Task* next_task = new WindowDragResponseTask(this, reply_message);
|
| - next_task = new MouseEventTask(next_task, ui_controls::UP);
|
| - next_task = new MouseEventTask(next_task, ui_controls::UP);
|
| + base::Closure drag_response_cb = base::Bind(
|
| + &SendWindowDragResponse, make_scoped_refptr(this), reply_message);
|
| + base::Closure move_chain_cb = base::IgnoreReturn<bool>(
|
| + base::Bind(&ui_controls::SendMouseEventsNotifyWhenDone,
|
| + ui_controls::LEFT, ui_controls::UP, drag_response_cb));
|
| + move_chain_cb = base::IgnoreReturn<bool>(
|
| + base::Bind(&ui_controls::SendMouseEventsNotifyWhenDone,
|
| + ui_controls::LEFT, ui_controls::UP, move_chain_cb));
|
| for (size_t i = drag_path.size() - 1; i > 0; --i) {
|
| // Smooth out the mouse movements by adding intermediate points. This
|
| // better simulates a real user drag.
|
| @@ -128,14 +67,20 @@ void AutomationProvider::WindowSimulateDrag(
|
| int half_step_x = (dest_x + drag_path[i - 1].x() + x) / 2;
|
| int half_step_y = (dest_y + drag_path[i - 1].y() + y) / 2;
|
|
|
| - next_task = new MouseMoveTask(next_task, dest_x, dest_y);
|
| - next_task = new MouseMoveTask(next_task, half_step_x, half_step_y);
|
| + move_chain_cb = base::IgnoreReturn<bool>(
|
| + base::Bind(&ui_controls::SendMouseMoveNotifyWhenDone, dest_x, dest_y,
|
| + move_chain_cb));
|
| + move_chain_cb = base::IgnoreReturn<bool>(
|
| + base::Bind(&ui_controls::SendMouseMoveNotifyWhenDone, half_step_x,
|
| + half_step_y, move_chain_cb));
|
| }
|
| - next_task = new MouseEventTask(next_task, ui_controls::DOWN);
|
| + move_chain_cb = base::IgnoreReturn<bool>(
|
| + base::Bind(&ui_controls::SendMouseEventsNotifyWhenDone,
|
| + ui_controls::LEFT, ui_controls::DOWN, move_chain_cb));
|
|
|
| ui_controls::SendMouseMoveNotifyWhenDone(x + drag_path[0].x(),
|
| y + drag_path[0].y(),
|
| - next_task);
|
| + move_chain_cb);
|
| } else {
|
| AutomationMsg_WindowDrag::WriteReplyParams(reply_message, false);
|
| Send(reply_message);
|
|
|