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