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 |