OLD | NEW |
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 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/ui_controls.h" | 5 #include "chrome/browser/automation/ui_controls.h" |
6 | 6 |
7 #include <gtk/gtk.h> | 7 #include <gtk/gtk.h> |
8 #include <gdk/gdkkeysyms.h> | 8 #include <gdk/gdkkeysyms.h> |
9 | 9 |
10 #include "gfx/rect.h" | 10 #include "gfx/rect.h" |
| 11 #include "base/event_synthesis_gtk.h" |
11 #include "base/keyboard_code_conversion_gtk.h" | 12 #include "base/keyboard_code_conversion_gtk.h" |
12 #include "base/logging.h" | 13 #include "base/logging.h" |
13 #include "base/message_loop.h" | 14 #include "base/message_loop.h" |
14 #include "chrome/browser/gtk/gtk_util.h" | 15 #include "chrome/browser/gtk/gtk_util.h" |
15 #include "chrome/test/automation/automation_constants.h" | 16 #include "chrome/test/automation/automation_constants.h" |
16 | 17 |
17 #if defined(TOOLKIT_VIEWS) | 18 #if defined(TOOLKIT_VIEWS) |
18 #include "views/view.h" | 19 #include "views/view.h" |
19 #include "views/widget/widget.h" | 20 #include "views/widget/widget.h" |
20 #endif | 21 #endif |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
75 else | 76 else |
76 ui_controls::SendMouseEvents(button_, state_); | 77 ui_controls::SendMouseEvents(button_, state_); |
77 } | 78 } |
78 | 79 |
79 private: | 80 private: |
80 ui_controls::MouseButton button_; | 81 ui_controls::MouseButton button_; |
81 int state_; | 82 int state_; |
82 Task* followup_; | 83 Task* followup_; |
83 }; | 84 }; |
84 | 85 |
85 bool SendKeyEvent(GdkWindow* window, bool press, guint gdk_key, guint state) { | |
86 GdkEvent* event = gdk_event_new(press ? GDK_KEY_PRESS : GDK_KEY_RELEASE); | |
87 | |
88 event->key.type = press ? GDK_KEY_PRESS : GDK_KEY_RELEASE; | |
89 event->key.window = window; | |
90 g_object_ref(event->key.window); | |
91 event->key.send_event = false; | |
92 event->key.time = gtk_util::XTimeNow(); | |
93 | |
94 event->key.state = state; | |
95 event->key.keyval = gdk_key; | |
96 | |
97 GdkKeymapKey* keys; | |
98 gint n_keys; | |
99 if (!gdk_keymap_get_entries_for_keyval(gdk_keymap_get_default(), | |
100 event->key.keyval, &keys, &n_keys)) { | |
101 return false; | |
102 } | |
103 event->key.hardware_keycode = keys[0].keycode; | |
104 event->key.group = keys[0].group; | |
105 g_free(keys); | |
106 | |
107 gdk_event_put(event); | |
108 // gdk_event_put appends a copy of the event. | |
109 gdk_event_free(event); | |
110 return true; | |
111 } | |
112 | |
113 void FakeAMouseMotionEvent(gint x, gint y) { | 86 void FakeAMouseMotionEvent(gint x, gint y) { |
114 GdkEvent* event = gdk_event_new(GDK_MOTION_NOTIFY); | 87 GdkEvent* event = gdk_event_new(GDK_MOTION_NOTIFY); |
115 | 88 |
116 event->motion.send_event = false; | 89 event->motion.send_event = false; |
117 event->motion.time = gtk_util::XTimeNow(); | 90 event->motion.time = gtk_util::XTimeNow(); |
118 | 91 |
119 GtkWidget* grab_widget = gtk_grab_get_current(); | 92 GtkWidget* grab_widget = gtk_grab_get_current(); |
120 if (grab_widget) { | 93 if (grab_widget) { |
121 // If there is a grab, we need to target all events at it regardless of | 94 // If there is a grab, we need to target all events at it regardless of |
122 // what widget the mouse is over. | 95 // what widget the mouse is over. |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
164 break; | 137 break; |
165 } | 138 } |
166 } | 139 } |
167 g_list_free(windows); | 140 g_list_free(windows); |
168 } | 141 } |
169 if (!event_window) { | 142 if (!event_window) { |
170 NOTREACHED() << "Window not specified and none is active"; | 143 NOTREACHED() << "Window not specified and none is active"; |
171 return false; | 144 return false; |
172 } | 145 } |
173 | 146 |
174 bool rv = true; | 147 std::vector<GdkEvent*> events; |
175 | 148 base::SynthesizeKeyPressEvents(event_window, key, control, shift, alt, |
176 if (control) | 149 &events); |
177 rv = rv && SendKeyEvent(event_window, true, GDK_Control_L, 0); | 150 for (std::vector<GdkEvent*>::iterator iter = events.begin(); |
178 | 151 iter != events.end(); ++iter) { |
179 if (shift) { | 152 gdk_event_put(*iter); |
180 rv = rv && SendKeyEvent(event_window, true, GDK_Shift_L, | 153 // gdk_event_put appends a copy of the event. |
181 control ? GDK_CONTROL_MASK : 0); | 154 gdk_event_free(*iter); |
182 } | 155 } |
183 | 156 |
184 if (alt) { | 157 return true; |
185 guint state = (control ? GDK_CONTROL_MASK : 0) | | |
186 (shift ? GDK_SHIFT_MASK : 0); | |
187 rv = rv && SendKeyEvent(event_window, true, GDK_Alt_L, state); | |
188 } | |
189 | |
190 // TODO(estade): handle other state flags besides control, shift, alt? | |
191 // For example caps lock. | |
192 guint state = (control ? GDK_CONTROL_MASK : 0) | | |
193 (shift ? GDK_SHIFT_MASK : 0) | | |
194 (alt ? GDK_MOD1_MASK : 0); | |
195 | |
196 guint gdk_key = base::GdkKeyCodeForWindowsKeyCode(key, shift); | |
197 rv = rv && SendKeyEvent(event_window, true, gdk_key, state); | |
198 rv = rv && SendKeyEvent(event_window, false, gdk_key, state); | |
199 | |
200 if (alt) { | |
201 guint state = (control ? GDK_CONTROL_MASK : 0) | | |
202 (shift ? GDK_SHIFT_MASK : 0) | GDK_MOD1_MASK; | |
203 rv = rv && SendKeyEvent(event_window, false, GDK_Alt_L, state); | |
204 } | |
205 | |
206 if (shift) { | |
207 rv = rv && SendKeyEvent(event_window, false, GDK_Shift_L, | |
208 (control ? GDK_CONTROL_MASK : 0) | GDK_SHIFT_MASK); | |
209 } | |
210 | |
211 if (control) | |
212 rv = rv && SendKeyEvent(event_window, false, GDK_Control_L, | |
213 GDK_CONTROL_MASK); | |
214 | |
215 return rv; | |
216 } | 158 } |
217 | 159 |
218 bool SendKeyPressNotifyWhenDone(gfx::NativeWindow window, | 160 bool SendKeyPressNotifyWhenDone(gfx::NativeWindow window, |
219 base::KeyboardCode key, | 161 base::KeyboardCode key, |
220 bool control, bool shift, | 162 bool control, bool shift, |
221 bool alt, bool command, | 163 bool alt, bool command, |
222 Task* task) { | 164 Task* task) { |
223 DCHECK(command == false); // No command key on Linux | 165 DCHECK(command == false); // No command key on Linux |
224 int release_count = 1; | 166 int release_count = 1; |
225 if (control) | 167 if (control) |
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
338 int state, | 280 int state, |
339 Task* task) { | 281 Task* task) { |
340 gfx::Rect bounds = gtk_util::GetWidgetScreenBounds(widget); | 282 gfx::Rect bounds = gtk_util::GetWidgetScreenBounds(widget); |
341 SendMouseMoveNotifyWhenDone(bounds.x() + bounds.width() / 2, | 283 SendMouseMoveNotifyWhenDone(bounds.x() + bounds.width() / 2, |
342 bounds.y() + bounds.height() / 2, | 284 bounds.y() + bounds.height() / 2, |
343 new ClickTask(button, state, task)); | 285 new ClickTask(button, state, task)); |
344 } | 286 } |
345 #endif | 287 #endif |
346 | 288 |
347 } // namespace ui_controls | 289 } // namespace ui_controls |
OLD | NEW |