Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(76)

Side by Side Diff: ui/ui_controls/ui_controls_gtk.cc

Issue 11419013: Add desktop vs. ash context to ui_controls Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: mac typo Created 8 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 "ui/ui_controls/ui_controls.h" 5 #include "ui/ui_controls/ui_controls.h"
6 6
7 #include <gdk/gdkkeysyms.h> 7 #include <gdk/gdkkeysyms.h>
8 #include <gtk/gtk.h> 8 #include <gtk/gtk.h>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
87 event->type = GDK_MOTION_NOTIFY; 87 event->type = GDK_MOTION_NOTIFY;
88 88
89 gdk_event_put(event); 89 gdk_event_put(event);
90 gdk_event_free(event); 90 gdk_event_free(event);
91 } 91 }
92 92
93 } // namespace 93 } // namespace
94 94
95 namespace ui_controls { 95 namespace ui_controls {
96 96
97 bool SendKeyPress(gfx::NativeWindow window, 97 namespace {
98 ui::KeyboardCode key, 98
99 bool control, 99 class UIControlsGtk : public UIControls {
100 bool shift, 100 public:
101 bool alt, 101 UIControlsGtk() {}
oshima 2012/11/16 20:41:39 virtual ~UIControlsGtk() {}
scottmg 2012/11/16 22:34:06 Done.
102 bool command) { 102
103 DCHECK(!command); // No command key on Linux 103 bool SendKeyPress(gfx::NativeWindow window,
104 GdkWindow* event_window = NULL; 104 ui::KeyboardCode key,
105 GtkWidget* grab_widget = gtk_grab_get_current(); 105 bool control,
106 if (grab_widget) { 106 bool shift,
107 // If there is a grab, send all events to the grabbed widget. 107 bool alt,
108 event_window = gtk_widget_get_window(grab_widget); 108 bool command) OVERRIDE {
109 } else if (window) { 109 DCHECK(!command); // No command key on Linux
110 event_window = gtk_widget_get_window(GTK_WIDGET(window)); 110 GdkWindow* event_window = NULL;
111 } else { 111 GtkWidget* grab_widget = gtk_grab_get_current();
112 // No target was specified. Send the events to the active toplevel. 112 if (grab_widget) {
113 GList* windows = gtk_window_list_toplevels(); 113 // If there is a grab, send all events to the grabbed widget.
114 for (GList* element = windows; element; element = g_list_next(element)) { 114 event_window = gtk_widget_get_window(grab_widget);
115 GtkWindow* this_window = GTK_WINDOW(element->data); 115 } else if (window) {
116 if (gtk_window_is_active(this_window)) { 116 event_window = gtk_widget_get_window(GTK_WIDGET(window));
117 event_window = gtk_widget_get_window(GTK_WIDGET(this_window)); 117 } else {
118 break; 118 // No target was specified. Send the events to the active toplevel.
119 GList* windows = gtk_window_list_toplevels();
120 for (GList* element = windows; element; element = g_list_next(element)) {
121 GtkWindow* this_window = GTK_WINDOW(element->data);
122 if (gtk_window_is_active(this_window)) {
123 event_window = gtk_widget_get_window(GTK_WIDGET(this_window));
124 break;
125 }
119 } 126 }
127 g_list_free(windows);
120 } 128 }
121 g_list_free(windows); 129 if (!event_window) {
130 NOTREACHED() << "Window not specified and none is active";
131 return false;
132 }
133
134 std::vector<GdkEvent*> events;
135 ui::SynthesizeKeyPressEvents(
136 event_window, key, control, shift, alt, &events);
137 for (std::vector<GdkEvent*>::iterator iter = events.begin();
138 iter != events.end(); ++iter) {
139 gdk_event_put(*iter);
140 // gdk_event_put appends a copy of the event.
141 gdk_event_free(*iter);
142 }
143
144 return true;
122 } 145 }
123 if (!event_window) { 146
124 NOTREACHED() << "Window not specified and none is active"; 147 bool SendKeyPressNotifyWhenDone(gfx::NativeWindow window,
148 ui::KeyboardCode key,
149 bool control,
150 bool shift,
151 bool alt,
152 bool command,
153 const base::Closure& task) OVERRIDE {
154 DCHECK(!command); // No command key on Linux
155 int release_count = 1;
156 if (control)
157 release_count++;
158 if (shift)
159 release_count++;
160 if (alt)
161 release_count++;
162 // This object will delete itself after running |task|.
163 new EventWaiter(task, GDK_KEY_RELEASE, release_count);
164 return SendKeyPress(window, key, control, shift, alt, command);
165 }
166
167 bool SendMouseMove(long x, long y) OVERRIDE {
168 gdk_display_warp_pointer(
169 gdk_display_get_default(), gdk_screen_get_default(), x, y);
170 // Sometimes gdk_display_warp_pointer fails to send back any indication of
171 // the move, even though it succesfully moves the server cursor. We fake
172 // it in order to get drags to work.
173 FakeAMouseMotionEvent(x, y);
174 return true;
175 }
176
177 bool SendMouseMoveNotifyWhenDone(
178 long x, long y, const base::Closure& task) OVERRIDE {
179 bool rv = SendMouseMove(x, y);
180 new EventWaiter(task, GDK_MOTION_NOTIFY, 1);
181 return rv;
182 }
183
184 bool SendMouseEvents(MouseButton type, int state) OVERRIDE {
185 GdkEvent* event = gdk_event_new(GDK_BUTTON_PRESS);
186
187 event->button.send_event = false;
188 event->button.time = XTimeNow();
189
190 gint x, y;
191 GtkWidget* grab_widget = gtk_grab_get_current();
192 if (grab_widget) {
193 // If there is a grab, we need to target all events at it regardless of
194 // what widget the mouse is over.
195 event->button.window = gtk_widget_get_window(grab_widget);
196 gdk_window_get_pointer(event->button.window, &x, &y, NULL);
197 } else {
198 event->button.window = gdk_window_at_pointer(&x, &y);
199 CHECK(event->button.window);
200 }
201
202 g_object_ref(event->button.window);
203 event->button.x = x;
204 event->button.y = y;
205 gint origin_x, origin_y;
206 gdk_window_get_origin(event->button.window, &origin_x, &origin_y);
207 event->button.x_root = x + origin_x;
208 event->button.y_root = y + origin_y;
209
210 event->button.axes = NULL;
211 GdkModifierType modifier;
212 gdk_window_get_pointer(event->button.window, NULL, NULL, &modifier);
213 event->button.state = modifier;
214 event->button.button = type == LEFT ? 1 : (type == MIDDLE ? 2 : 3);
215 event->button.device = gdk_device_get_core_pointer();
216
217 event->button.type = GDK_BUTTON_PRESS;
218 if (state & DOWN)
219 gdk_event_put(event);
220
221 // Also send a release event.
222 GdkEvent* release_event = gdk_event_copy(event);
223 release_event->button.type = GDK_BUTTON_RELEASE;
224 release_event->button.time++;
225 if (state & UP)
226 gdk_event_put(release_event);
227
228 gdk_event_free(event);
229 gdk_event_free(release_event);
230
125 return false; 231 return false;
126 } 232 }
127 233
128 std::vector<GdkEvent*> events; 234 bool SendMouseEventsNotifyWhenDone(MouseButton type,
129 ui::SynthesizeKeyPressEvents(event_window, key, control, shift, alt, &events); 235 int state,
130 for (std::vector<GdkEvent*>::iterator iter = events.begin(); 236 const base::Closure& task) OVERRIDE {
131 iter != events.end(); ++iter) { 237 bool rv = SendMouseEvents(type, state);
132 gdk_event_put(*iter); 238 GdkEventType wait_type;
133 // gdk_event_put appends a copy of the event. 239 if (state & UP) {
134 gdk_event_free(*iter); 240 wait_type = GDK_BUTTON_RELEASE;
241 } else {
242 if (type == LEFT)
243 wait_type = GDK_BUTTON_PRESS;
244 else if (type == MIDDLE)
245 wait_type = GDK_2BUTTON_PRESS;
246 else
247 wait_type = GDK_3BUTTON_PRESS;
248 }
249 new EventWaiter(task, wait_type, 1);
250 return rv;
135 } 251 }
136 252
137 return true; 253 bool SendMouseClick(MouseButton type) {
138 } 254 return SendMouseEvents(type, UP | DOWN);
139
140 bool SendKeyPressNotifyWhenDone(gfx::NativeWindow window,
141 ui::KeyboardCode key,
142 bool control,
143 bool shift,
144 bool alt,
145 bool command,
146 const base::Closure& task) {
147 DCHECK(!command); // No command key on Linux
148 int release_count = 1;
149 if (control)
150 release_count++;
151 if (shift)
152 release_count++;
153 if (alt)
154 release_count++;
155 // This object will delete itself after running |task|.
156 new EventWaiter(task, GDK_KEY_RELEASE, release_count);
157 return SendKeyPress(window, key, control, shift, alt, command);
158 }
159
160 bool SendMouseMove(long x, long y) {
161 gdk_display_warp_pointer(gdk_display_get_default(), gdk_screen_get_default(),
162 x, y);
163 // Sometimes gdk_display_warp_pointer fails to send back any indication of
164 // the move, even though it succesfully moves the server cursor. We fake it in
165 // order to get drags to work.
166 FakeAMouseMotionEvent(x, y);
167 return true;
168 }
169
170 bool SendMouseMoveNotifyWhenDone(long x, long y, const base::Closure& task) {
171 bool rv = SendMouseMove(x, y);
172 new EventWaiter(task, GDK_MOTION_NOTIFY, 1);
173 return rv;
174 }
175
176 bool SendMouseEvents(MouseButton type, int state) {
177 GdkEvent* event = gdk_event_new(GDK_BUTTON_PRESS);
178
179 event->button.send_event = false;
180 event->button.time = XTimeNow();
181
182 gint x, y;
183 GtkWidget* grab_widget = gtk_grab_get_current();
184 if (grab_widget) {
185 // If there is a grab, we need to target all events at it regardless of
186 // what widget the mouse is over.
187 event->button.window = gtk_widget_get_window(grab_widget);
188 gdk_window_get_pointer(event->button.window, &x, &y, NULL);
189 } else {
190 event->button.window = gdk_window_at_pointer(&x, &y);
191 CHECK(event->button.window);
192 } 255 }
193 256
194 g_object_ref(event->button.window); 257 private:
195 event->button.x = x; 258 DISALLOW_COPY_AND_ASSIGN(UIControlsGtk);
196 event->button.y = y; 259 };
197 gint origin_x, origin_y;
198 gdk_window_get_origin(event->button.window, &origin_x, &origin_y);
199 event->button.x_root = x + origin_x;
200 event->button.y_root = y + origin_y;
201 260
202 event->button.axes = NULL; 261 } // namespace
203 GdkModifierType modifier;
204 gdk_window_get_pointer(event->button.window, NULL, NULL, &modifier);
205 event->button.state = modifier;
206 event->button.button = type == LEFT ? 1 : (type == MIDDLE ? 2 : 3);
207 event->button.device = gdk_device_get_core_pointer();
208 262
209 event->button.type = GDK_BUTTON_PRESS; 263 UIControls* CreateNativeUIControls() {
210 if (state & DOWN) 264 return new UIControlsGtk;
211 gdk_event_put(event);
212
213 // Also send a release event.
214 GdkEvent* release_event = gdk_event_copy(event);
215 release_event->button.type = GDK_BUTTON_RELEASE;
216 release_event->button.time++;
217 if (state & UP)
218 gdk_event_put(release_event);
219
220 gdk_event_free(event);
221 gdk_event_free(release_event);
222
223 return false;
224 }
225
226 bool SendMouseEventsNotifyWhenDone(MouseButton type,
227 int state,
228 const base::Closure& task) {
229 bool rv = SendMouseEvents(type, state);
230 GdkEventType wait_type;
231 if (state & UP) {
232 wait_type = GDK_BUTTON_RELEASE;
233 } else {
234 if (type == LEFT)
235 wait_type = GDK_BUTTON_PRESS;
236 else if (type == MIDDLE)
237 wait_type = GDK_2BUTTON_PRESS;
238 else
239 wait_type = GDK_3BUTTON_PRESS;
240 }
241 new EventWaiter(task, wait_type, 1);
242 return rv;
243 }
244
245 bool SendMouseClick(MouseButton type) {
246 return SendMouseEvents(type, UP | DOWN);
247 } 265 }
248 266
249 } // namespace ui_controls 267 } // namespace ui_controls
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698