Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/automation/automation_provider.h" | 5 #include "chrome/browser/automation/automation_provider.h" |
| 6 | 6 |
| 7 #include <gtk/gtk.h> | 7 #include <gtk/gtk.h> |
| 8 | 8 |
| 9 #include "base/callback.h" | |
| 9 #include "base/utf_string_conversions.h" | 10 #include "base/utf_string_conversions.h" |
| 10 #include "chrome/browser/automation/automation_browser_tracker.h" | 11 #include "chrome/browser/automation/automation_browser_tracker.h" |
| 11 #include "chrome/browser/automation/automation_window_tracker.h" | 12 #include "chrome/browser/automation/automation_window_tracker.h" |
| 12 #include "chrome/browser/automation/ui_controls.h" | 13 #include "chrome/browser/automation/ui_controls.h" |
| 13 #include "chrome/browser/ui/browser.h" | 14 #include "chrome/browser/ui/browser.h" |
| 14 #include "chrome/browser/ui/gtk/browser_window_gtk.h" | 15 #include "chrome/browser/ui/gtk/browser_window_gtk.h" |
| 15 #include "chrome/browser/ui/gtk/gtk_util.h" | 16 #include "chrome/browser/ui/gtk/gtk_util.h" |
| 16 #include "chrome/browser/ui/gtk/view_id_util.h" | 17 #include "chrome/browser/ui/gtk/view_id_util.h" |
| 17 #include "chrome/common/automation_messages.h" | 18 #include "chrome/common/automation_messages.h" |
| 18 #include "ui/gfx/point.h" | 19 #include "ui/gfx/point.h" |
| 19 #include "ui/gfx/rect.h" | 20 #include "ui/gfx/rect.h" |
| 20 | 21 |
| 21 void AutomationProvider::PrintAsync(int tab_handle) { | 22 void AutomationProvider::PrintAsync(int tab_handle) { |
| 22 NOTIMPLEMENTED(); | 23 NOTIMPLEMENTED(); |
| 23 } | 24 } |
| 24 | 25 |
| 25 // This task sends a WindowDragResponse message with the appropriate | 26 // This closure sends a WindowDragResponse message with the appropriate routing |
| 26 // routing ID to the automation proxy. This is implemented as a task so that | 27 // ID to the automation proxy. This is implemented as a task so that we know |
| 27 // we know that the mouse events (and any tasks that they spawn on the message | 28 // that the mouse events (and any tasks that they spawn on the message loop) |
| 28 // loop) have been processed by the time this is sent. | 29 // have been processed by the time this is sent. |
| 29 class WindowDragResponseTask : public Task { | 30 class WindowDragResponseTask : public base::Closure { |
| 30 public: | 31 public: |
| 31 WindowDragResponseTask(AutomationProvider* provider, | 32 WindowDragResponseTask(AutomationProvider* provider, |
| 32 IPC::Message* reply_message) | 33 IPC::Message* reply_message) |
| 33 : provider_(provider), | 34 : provider_(provider), |
| 34 reply_message_(reply_message) { | 35 reply_message_(reply_message) { |
| 35 DCHECK(provider_); | 36 DCHECK(provider_); |
| 36 DCHECK(reply_message_); | 37 DCHECK(reply_message_); |
| 37 } | 38 } |
| 38 | 39 |
| 39 virtual ~WindowDragResponseTask() { | 40 virtual ~WindowDragResponseTask() { |
| 40 } | 41 } |
| 41 | 42 |
| 42 virtual void Run() { | 43 virtual void Run() { |
| 43 AutomationMsg_WindowDrag::WriteReplyParams(reply_message_, true); | 44 AutomationMsg_WindowDrag::WriteReplyParams(reply_message_, true); |
| 44 provider_->Send(reply_message_); | 45 provider_->Send(reply_message_); |
| 45 } | 46 } |
| 46 | 47 |
| 47 private: | 48 private: |
| 48 AutomationProvider* provider_; | 49 AutomationProvider* provider_; |
| 49 IPC::Message* reply_message_; | 50 IPC::Message* reply_message_; |
| 50 | 51 |
| 51 DISALLOW_COPY_AND_ASSIGN(WindowDragResponseTask); | 52 DISALLOW_COPY_AND_ASSIGN(WindowDragResponseTask); |
| 52 }; | 53 }; |
| 53 | 54 |
| 54 // A task that just runs a SendMouseEvent and performs another task when done. | 55 // A closure that just runs a SendMouseEvent and performs another task when |
| 55 class MouseEventTask : public Task { | 56 // done. |
| 57 class MouseEventTask : public base::Closure { | |
| 56 public: | 58 public: |
| 57 MouseEventTask(Task* next_task, ui_controls::MouseButtonState state) | 59 MouseEventTask(const base::Closure& next_task, |
| 60 ui_controls::MouseButtonState state) | |
| 58 : next_task_(next_task), | 61 : next_task_(next_task), |
| 59 state_(state) {} | 62 state_(state) {} |
| 60 | 63 |
| 61 virtual ~MouseEventTask() { | 64 virtual ~MouseEventTask() { |
| 62 } | 65 } |
| 63 | 66 |
| 64 virtual void Run() { | 67 virtual void Run() { |
| 65 ui_controls::SendMouseEventsNotifyWhenDone(ui_controls::LEFT, state_, | 68 ui_controls::SendMouseEventsNotifyWhenDone(ui_controls::LEFT, state_, |
| 66 next_task_); | 69 next_task_); |
| 67 } | 70 } |
| 68 | 71 |
| 69 private: | 72 private: |
| 70 // The task to execute when we are done. | 73 // The task to execute when we are done. |
| 71 Task* next_task_; | 74 base::Closure next_task_; |
| 72 | 75 |
| 73 // Mouse press or mouse release. | 76 // Mouse press or mouse release. |
| 74 ui_controls::MouseButtonState state_; | 77 ui_controls::MouseButtonState state_; |
| 75 | 78 |
| 76 DISALLOW_COPY_AND_ASSIGN(MouseEventTask); | 79 DISALLOW_COPY_AND_ASSIGN(MouseEventTask); |
| 77 }; | 80 }; |
| 78 | 81 |
| 79 // A task that just runs a SendMouseMove and performs another task when done. | 82 // A closure that just runs a SendMouseMove and performs another task when done. |
| 80 class MouseMoveTask : public Task { | 83 class MouseMoveTask : public base::Closure { |
| 81 public: | 84 public: |
| 82 MouseMoveTask(Task* next_task, int absolute_x, int absolute_y) | 85 MouseMoveTask(const base::Closure& next_task, int absolute_x, int absolute_y) |
| 83 : next_task_(next_task), | 86 : next_task_(next_task), |
| 84 x_(absolute_x), | 87 x_(absolute_x), |
| 85 y_(absolute_y) { | 88 y_(absolute_y) { |
| 86 } | 89 } |
| 87 | 90 |
| 88 virtual ~MouseMoveTask() { | 91 virtual ~MouseMoveTask() { |
| 89 } | 92 } |
| 90 | 93 |
| 91 virtual void Run() { | 94 virtual void Run() { |
| 92 ui_controls::SendMouseMoveNotifyWhenDone(x_, y_, next_task_); | 95 ui_controls::SendMouseMoveNotifyWhenDone(x_, y_, next_task_); |
| 93 } | 96 } |
| 94 | 97 |
| 95 private: | 98 private: |
| 96 // The task to execute when we are done. | 99 // The task to execute when we are done. |
| 97 Task* next_task_; | 100 base::Closure next_task_; |
| 98 | 101 |
| 99 // Coordinates of the press. | 102 // Coordinates of the press. |
| 100 int x_; | 103 int x_; |
| 101 int y_; | 104 int y_; |
| 102 | 105 |
| 103 DISALLOW_COPY_AND_ASSIGN(MouseMoveTask); | 106 DISALLOW_COPY_AND_ASSIGN(MouseMoveTask); |
| 104 }; | 107 }; |
| 105 | 108 |
| 106 void AutomationProvider::WindowSimulateDrag( | 109 void AutomationProvider::WindowSimulateDrag( |
| 107 int handle, | 110 int handle, |
| 108 const std::vector<gfx::Point>& drag_path, | 111 const std::vector<gfx::Point>& drag_path, |
| 109 int flags, | 112 int flags, |
| 110 bool press_escape_en_route, | 113 bool press_escape_en_route, |
| 111 IPC::Message* reply_message) { | 114 IPC::Message* reply_message) { |
| 112 // TODO(estade): don't ignore |flags| or |escape_en_route|. | 115 // TODO(estade): don't ignore |flags| or |escape_en_route|. |
| 113 gfx::NativeWindow window = | 116 gfx::NativeWindow window = |
| 114 browser_tracker_->GetResource(handle)->window()->GetNativeHandle(); | 117 browser_tracker_->GetResource(handle)->window()->GetNativeHandle(); |
| 115 if (window && (drag_path.size() > 1)) { | 118 if (window && (drag_path.size() > 1)) { |
| 116 int x, y; | 119 int x, y; |
| 117 gdk_window_get_position(GTK_WIDGET(window)->window, &x, &y); | 120 gdk_window_get_position(GTK_WIDGET(window)->window, &x, &y); |
| 118 | 121 |
| 119 // Create a nested stack of tasks to run. | 122 // Create a nested stack of tasks to run. |
| 120 Task* next_task = new WindowDragResponseTask(this, reply_message); | 123 WindowDragResponseTask task1(this, reply_message); |
| 121 next_task = new MouseEventTask(next_task, ui_controls::UP); | 124 MouseEventTask task2(task1, ui_controls::UP); |
| 122 next_task = new MouseEventTask(next_task, ui_controls::UP); | 125 MouseEventTask task3(task2, ui_controls::UP); |
| 126 base::Closure* task = &task3; | |
| 123 for (size_t i = drag_path.size() - 1; i > 0; --i) { | 127 for (size_t i = drag_path.size() - 1; i > 0; --i) { |
| 124 // Smooth out the mouse movements by adding intermediate points. This | 128 // Smooth out the mouse movements by adding intermediate points. This |
| 125 // better simulates a real user drag. | 129 // better simulates a real user drag. |
| 126 int dest_x = drag_path[i].x() + x; | 130 int dest_x = drag_path[i].x() + x; |
| 127 int dest_y = drag_path[i].y() + y; | 131 int dest_y = drag_path[i].y() + y; |
| 128 int half_step_x = (dest_x + drag_path[i - 1].x() + x) / 2; | 132 int half_step_x = (dest_x + drag_path[i - 1].x() + x) / 2; |
| 129 int half_step_y = (dest_y + drag_path[i - 1].y() + y) / 2; | 133 int half_step_y = (dest_y + drag_path[i - 1].y() + y) / 2; |
| 130 | 134 |
| 131 next_task = new MouseMoveTask(next_task, dest_x, dest_y); | 135 MouseMoveTask task4(*task, dest_x, dest_y); |
| 132 next_task = new MouseMoveTask(next_task, half_step_x, half_step_y); | 136 MouseMoveTask task5(task4, half_step_x, half_step_y); |
| 137 task = &task5; | |
|
csilv
2011/10/10 18:36:47
This looks problematic. 'task' will point to task
| |
| 133 } | 138 } |
| 134 next_task = new MouseEventTask(next_task, ui_controls::DOWN); | 139 MouseEventTask task6(*task, ui_controls::DOWN); |
| 135 | 140 |
| 136 ui_controls::SendMouseMoveNotifyWhenDone(x + drag_path[0].x(), | 141 ui_controls::SendMouseMoveNotifyWhenDone(x + drag_path[0].x(), |
| 137 y + drag_path[0].y(), | 142 y + drag_path[0].y(), |
| 138 next_task); | 143 task6); |
| 139 } else { | 144 } else { |
| 140 AutomationMsg_WindowDrag::WriteReplyParams(reply_message, false); | 145 AutomationMsg_WindowDrag::WriteReplyParams(reply_message, false); |
| 141 Send(reply_message); | 146 Send(reply_message); |
| 142 } | 147 } |
| 143 } | 148 } |
| OLD | NEW |