Merge lp:~bratsche/libgrip/event-routing into lp:libgrip
- event-routing
- Merge into trunk
Status: | Merged |
---|---|
Merged at revision: | 16 |
Proposed branch: | lp:~bratsche/libgrip/event-routing |
Merge into: | lp:libgrip |
Diff against target: |
843 lines (+421/-144) 3 files modified
examples/rectangle-mover/gesture.c (+107/-55) src/gripgesturemanager.c (+307/-84) src/gripgesturemanager.h (+7/-5) |
To merge this branch: | bzr merge lp:~bratsche/libgrip/event-routing |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Henrik Rydberg (community) | Needs Information | ||
Stephen M. Webb (community) | Approve | ||
Review via email: mp+43378@code.launchpad.net |
Commit message
Description of the change
This changes the API of libgrip. Gesture callbacks are now registered by widget rather than by window.
See the rectangle mover test program to test it out, and note that you should be able to do the normal gestures only in the drawing area. The area on the left is a treeview (although I'm not populating it with anything yet); doing gesture events on the treeview will result in nothing happening. Below the treeview is a "Quit" button, and tapping this will cause the test program to exit.
Henrik Rydberg (rydberg) wrote : | # |
I love test programs :-) I noticed some problems:
1. Dragging seems to lose some events along the way
2. Rotating around a finger looks odd (rather grail's fault)
3. For me, tapping the quit button did not work
I have attaching an evemu test case, where I first maximize the ./gesture program, then start recording some movements, and lastly tap the quit button. Will only work on natty, please holler if it would help you.
Preview Diff
1 | === modified file 'examples/rectangle-mover/gesture.c' | |||
2 | --- examples/rectangle-mover/gesture.c 2010-12-09 01:25:48 +0000 | |||
3 | +++ examples/rectangle-mover/gesture.c 2010-12-10 18:01:55 +0000 | |||
4 | @@ -38,32 +38,19 @@ | |||
5 | 38 | return FALSE; | 38 | return FALSE; |
6 | 39 | } | 39 | } |
7 | 40 | 40 | ||
10 | 41 | GtkWidget * | 41 | static void |
11 | 42 | create_window (void) | 42 | button_tap (GtkWidget *widget, |
12 | 43 | GripTimeType time_type, | ||
13 | 44 | GripGestureEvent *event, | ||
14 | 45 | gpointer user_data) | ||
15 | 43 | { | 46 | { |
33 | 44 | GtkWidget *window = gtk_window_new (GTK_WINDOW_TOPLEVEL); | 47 | g_signal_emit_by_name (widget, "clicked"); |
17 | 45 | GtkWidget *da; | ||
18 | 46 | const GdkColor white = { 0, 0xffff, 0xffff, 0xffff }; | ||
19 | 47 | |||
20 | 48 | gtk_window_set_title (GTK_WINDOW (window), "Touch Demo"); | ||
21 | 49 | gtk_window_set_default_size (GTK_WINDOW (window), 600, 600); | ||
22 | 50 | g_signal_connect (window, "destroy", G_CALLBACK (gtk_widget_destroyed), &window); | ||
23 | 51 | |||
24 | 52 | da = gtk_drawing_area_new (); | ||
25 | 53 | gtk_container_add (GTK_CONTAINER (window), da); | ||
26 | 54 | |||
27 | 55 | gtk_widget_modify_bg (da, GTK_STATE_NORMAL, &white); | ||
28 | 56 | |||
29 | 57 | g_signal_connect (da, "expose-event", | ||
30 | 58 | G_CALLBACK (expose_event), NULL); | ||
31 | 59 | |||
32 | 60 | return window; | ||
34 | 61 | } | 48 | } |
35 | 62 | 49 | ||
36 | 63 | static void | 50 | static void |
38 | 64 | gesture_callback (GtkWindow *window, | 51 | gesture_callback (GtkWidget *widget, |
39 | 65 | GripTimeType time_type, | 52 | GripTimeType time_type, |
41 | 66 | GripGestureEvent *event, | 53 | GripGestureEvent *event, |
42 | 67 | gpointer user_data) | 54 | gpointer user_data) |
43 | 68 | { | 55 | { |
44 | 69 | if (time_type == GRIP_TIME_START) | 56 | if (time_type == GRIP_TIME_START) |
45 | @@ -103,12 +90,106 @@ | |||
46 | 103 | } | 90 | } |
47 | 104 | break; | 91 | break; |
48 | 105 | 92 | ||
51 | 106 | case GRIP_GESTURE_TAP: | 93 | case GRIP_GESTURE_TAP: |
52 | 107 | break; | 94 | break; |
53 | 108 | } | 95 | } |
54 | 109 | } | 96 | } |
55 | 110 | 97 | ||
57 | 111 | gtk_widget_queue_draw (GTK_WIDGET (window)); | 98 | gtk_widget_queue_draw (GTK_WIDGET (widget)); |
58 | 99 | } | ||
59 | 100 | |||
60 | 101 | |||
61 | 102 | static GtkTreeModel * | ||
62 | 103 | create_model () | ||
63 | 104 | { | ||
64 | 105 | return (GtkTreeModel *)gtk_list_store_new (1, G_TYPE_STRING); | ||
65 | 106 | } | ||
66 | 107 | |||
67 | 108 | static GtkWidget * | ||
68 | 109 | create_window (GripGestureManager *manager) | ||
69 | 110 | { | ||
70 | 111 | GtkWidget *window = gtk_window_new (GTK_WINDOW_TOPLEVEL); | ||
71 | 112 | GtkWidget *da; | ||
72 | 113 | GtkWidget *hbox; | ||
73 | 114 | GtkWidget *vbox; | ||
74 | 115 | GtkWidget *button; | ||
75 | 116 | GtkWidget *tv; | ||
76 | 117 | GtkTreeModel *model; | ||
77 | 118 | GtkWidget *sw; | ||
78 | 119 | const GdkColor white = { 0, 0xffff, 0xffff, 0xffff }; | ||
79 | 120 | |||
80 | 121 | da = gtk_drawing_area_new (); | ||
81 | 122 | |||
82 | 123 | gtk_window_set_title (GTK_WINDOW (window), "Touch Demo"); | ||
83 | 124 | gtk_window_set_default_size (GTK_WINDOW (window), 600, 600); | ||
84 | 125 | g_signal_connect (window, "destroy", G_CALLBACK (gtk_widget_destroyed), &window); | ||
85 | 126 | g_signal_connect (window, "destroy", G_CALLBACK (gtk_main_quit), NULL); | ||
86 | 127 | |||
87 | 128 | hbox = gtk_hbox_new (FALSE, 0); | ||
88 | 129 | vbox = gtk_vbox_new (FALSE, 0); | ||
89 | 130 | |||
90 | 131 | gtk_box_pack_start (GTK_BOX (hbox), vbox, FALSE, FALSE, 0); | ||
91 | 132 | gtk_box_pack_start (GTK_BOX (hbox), da, TRUE, TRUE, 0); | ||
92 | 133 | |||
93 | 134 | model = create_model (); | ||
94 | 135 | sw = gtk_scrolled_window_new (NULL, NULL); | ||
95 | 136 | tv = gtk_tree_view_new_with_model (model); | ||
96 | 137 | g_object_unref (model); | ||
97 | 138 | |||
98 | 139 | gtk_container_add (GTK_CONTAINER (sw), tv); | ||
99 | 140 | |||
100 | 141 | gtk_box_pack_start (GTK_BOX (vbox), sw, TRUE, TRUE, 0); | ||
101 | 142 | |||
102 | 143 | button = gtk_button_new_with_label ("Quit"); | ||
103 | 144 | g_signal_connect (button, | ||
104 | 145 | "clicked", | ||
105 | 146 | G_CALLBACK (gtk_main_quit), | ||
106 | 147 | NULL); | ||
107 | 148 | grip_gesture_manager_register_window (manager, | ||
108 | 149 | button, | ||
109 | 150 | GRIP_GESTURE_TAP, | ||
110 | 151 | 1, | ||
111 | 152 | button_tap, | ||
112 | 153 | NULL, NULL); | ||
113 | 154 | |||
114 | 155 | gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0); | ||
115 | 156 | |||
116 | 157 | gtk_container_add (GTK_CONTAINER (window), hbox); | ||
117 | 158 | |||
118 | 159 | gtk_widget_modify_bg (da, GTK_STATE_NORMAL, &white); | ||
119 | 160 | |||
120 | 161 | g_signal_connect (da, "expose-event", | ||
121 | 162 | G_CALLBACK (expose_event), NULL); | ||
122 | 163 | |||
123 | 164 | grip_gesture_manager_register_window (manager, | ||
124 | 165 | da, | ||
125 | 166 | GRIP_GESTURE_PINCH, | ||
126 | 167 | 2, | ||
127 | 168 | gesture_callback, | ||
128 | 169 | NULL, NULL); | ||
129 | 170 | |||
130 | 171 | grip_gesture_manager_register_window (manager, | ||
131 | 172 | da, | ||
132 | 173 | GRIP_GESTURE_ROTATE, | ||
133 | 174 | 2, | ||
134 | 175 | gesture_callback, | ||
135 | 176 | NULL, NULL); | ||
136 | 177 | |||
137 | 178 | grip_gesture_manager_register_window (manager, | ||
138 | 179 | da, | ||
139 | 180 | GRIP_GESTURE_DRAG, | ||
140 | 181 | 2, | ||
141 | 182 | gesture_callback, | ||
142 | 183 | NULL, NULL); | ||
143 | 184 | |||
144 | 185 | grip_gesture_manager_register_window (manager, | ||
145 | 186 | da, | ||
146 | 187 | GRIP_GESTURE_TAP, | ||
147 | 188 | 2, | ||
148 | 189 | gesture_callback, | ||
149 | 190 | NULL, NULL); | ||
150 | 191 | |||
151 | 192 | return window; | ||
152 | 112 | } | 193 | } |
153 | 113 | 194 | ||
154 | 114 | static void | 195 | static void |
155 | @@ -122,7 +203,7 @@ | |||
156 | 122 | int | 203 | int |
157 | 123 | main (int argc, char **argv) | 204 | main (int argc, char **argv) |
158 | 124 | { | 205 | { |
160 | 125 | GtkWindow *window; | 206 | GtkWidget *window; |
161 | 126 | GripGestureManager *manager; | 207 | GripGestureManager *manager; |
162 | 127 | 208 | ||
163 | 128 | gtk_init (&argc, &argv); | 209 | gtk_init (&argc, &argv); |
164 | @@ -131,40 +212,11 @@ | |||
165 | 131 | * my Dell XT2 has in it. */ | 212 | * my Dell XT2 has in it. */ |
166 | 132 | signal (SIGABRT, abort_handler); | 213 | signal (SIGABRT, abort_handler); |
167 | 133 | 214 | ||
168 | 134 | window = (GtkWindow *)create_window (); | ||
169 | 135 | manager = grip_gesture_manager_get (); | 215 | manager = grip_gesture_manager_get (); |
170 | 216 | window = create_window (manager); | ||
171 | 136 | 217 | ||
172 | 137 | g_signal_connect (window, "destroy", G_CALLBACK (gtk_main_quit), NULL); | 218 | g_signal_connect (window, "destroy", G_CALLBACK (gtk_main_quit), NULL); |
173 | 138 | 219 | ||
174 | 139 | grip_gesture_manager_register_window (manager, | ||
175 | 140 | window, | ||
176 | 141 | GRIP_GESTURE_PINCH, | ||
177 | 142 | 2, | ||
178 | 143 | gesture_callback, | ||
179 | 144 | NULL, NULL); | ||
180 | 145 | |||
181 | 146 | grip_gesture_manager_register_window (manager, | ||
182 | 147 | window, | ||
183 | 148 | GRIP_GESTURE_ROTATE, | ||
184 | 149 | 2, | ||
185 | 150 | gesture_callback, | ||
186 | 151 | NULL, NULL); | ||
187 | 152 | |||
188 | 153 | grip_gesture_manager_register_window (manager, | ||
189 | 154 | window, | ||
190 | 155 | GRIP_GESTURE_DRAG, | ||
191 | 156 | 2, | ||
192 | 157 | gesture_callback, | ||
193 | 158 | NULL, NULL); | ||
194 | 159 | |||
195 | 160 | grip_gesture_manager_register_window (manager, | ||
196 | 161 | window, | ||
197 | 162 | GRIP_GESTURE_TAP, | ||
198 | 163 | 2, | ||
199 | 164 | gesture_callback, | ||
200 | 165 | NULL, NULL); | ||
201 | 166 | |||
202 | 167 | |||
203 | 168 | gtk_widget_show_all (GTK_WIDGET (window)); | 220 | gtk_widget_show_all (GTK_WIDGET (window)); |
204 | 169 | 221 | ||
205 | 170 | gtk_main (); | 222 | gtk_main (); |
206 | 171 | 223 | ||
207 | === modified file 'src/gripgesturemanager.c' | |||
208 | --- src/gripgesturemanager.c 2010-12-09 01:25:48 +0000 | |||
209 | +++ src/gripgesturemanager.c 2010-12-10 18:01:55 +0000 | |||
210 | @@ -41,6 +41,7 @@ | |||
211 | 41 | struct _GripGestureBinding | 41 | struct _GripGestureBinding |
212 | 42 | { | 42 | { |
213 | 43 | GripGestureType type; | 43 | GripGestureType type; |
214 | 44 | GtkWidget *widget; | ||
215 | 44 | gint touches; | 45 | gint touches; |
216 | 45 | GripGestureCallback callback; | 46 | GripGestureCallback callback; |
217 | 46 | gpointer data; | 47 | gpointer data; |
218 | @@ -58,7 +59,7 @@ | |||
219 | 58 | struct _GripRegistrationRequest | 59 | struct _GripRegistrationRequest |
220 | 59 | { | 60 | { |
221 | 60 | GripGestureManager *manager; | 61 | GripGestureManager *manager; |
223 | 61 | GtkWindow *window; | 62 | GtkWidget *widget; |
224 | 62 | GripGestureType gesture_type; | 63 | GripGestureType gesture_type; |
225 | 63 | gint touch_points; | 64 | gint touch_points; |
226 | 64 | GripGestureCallback callback; | 65 | GripGestureCallback callback; |
227 | @@ -96,6 +97,10 @@ | |||
228 | 96 | GeisSize attr_count, | 97 | GeisSize attr_count, |
229 | 97 | GeisGestureAttr *attrs); | 98 | GeisGestureAttr *attrs); |
230 | 98 | 99 | ||
231 | 100 | static void window_mapped_cb (GtkWidget *widget, | ||
232 | 101 | GdkEvent *event, | ||
233 | 102 | gpointer user_data); | ||
234 | 103 | |||
235 | 99 | static GripGestureManager *manager_singleton = NULL; | 104 | static GripGestureManager *manager_singleton = NULL; |
236 | 100 | static GeisGestureFuncs gesture_funcs = { | 105 | static GeisGestureFuncs gesture_funcs = { |
237 | 101 | gesture_added, | 106 | gesture_added, |
238 | @@ -351,6 +356,16 @@ | |||
239 | 351 | { | 356 | { |
240 | 352 | event->timestamp = attrs[i].integer_val; | 357 | event->timestamp = attrs[i].integer_val; |
241 | 353 | } | 358 | } |
242 | 359 | else if (g_strcmp0 (attrs[i].name, GEIS_GESTURE_ATTRIBUTE_FOCUS_X) == 0 && | ||
243 | 360 | attrs[i].type == GEIS_ATTR_TYPE_FLOAT) | ||
244 | 361 | { | ||
245 | 362 | event->focus_x = attrs[i].float_val; | ||
246 | 363 | } | ||
247 | 364 | else if (g_strcmp0 (attrs[i].name, GEIS_GESTURE_ATTRIBUTE_FOCUS_Y) == 0 && | ||
248 | 365 | attrs[i].type == GEIS_ATTR_TYPE_FLOAT) | ||
249 | 366 | { | ||
250 | 367 | event->focus_y = attrs[i].float_val; | ||
251 | 368 | } | ||
252 | 354 | else if (g_strcmp0 (attrs[i].name, GEIS_GESTURE_ATTRIBUTE_POSITION_X) == 0 && | 369 | else if (g_strcmp0 (attrs[i].name, GEIS_GESTURE_ATTRIBUTE_POSITION_X) == 0 && |
253 | 355 | attrs[i].type == GEIS_ATTR_TYPE_FLOAT) | 370 | attrs[i].type == GEIS_ATTR_TYPE_FLOAT) |
254 | 356 | { | 371 | { |
255 | @@ -389,6 +404,21 @@ | |||
256 | 389 | { | 404 | { |
257 | 390 | } | 405 | } |
258 | 391 | 406 | ||
259 | 407 | static gboolean | ||
260 | 408 | matches_widget (GtkWidget *widget, | ||
261 | 409 | GdkWindow *window, | ||
262 | 410 | gint x, | ||
263 | 411 | gint y) | ||
264 | 412 | { | ||
265 | 413 | GtkAllocation alloc; | ||
266 | 414 | gint ax, ay; | ||
267 | 415 | |||
268 | 416 | gtk_widget_get_allocation (widget, &alloc); | ||
269 | 417 | gdk_window_get_root_coords (window, alloc.x, alloc.y, &ax, &ay); | ||
270 | 418 | |||
271 | 419 | return (x >= ax && x < ax + alloc.width && y >= ay && y < ay + alloc.height); | ||
272 | 420 | } | ||
273 | 421 | |||
274 | 392 | static void | 422 | static void |
275 | 393 | gesture_start (void *cookie, | 423 | gesture_start (void *cookie, |
276 | 394 | GeisGestureType type, | 424 | GeisGestureType type, |
277 | @@ -417,10 +447,16 @@ | |||
278 | 417 | 447 | ||
279 | 418 | if (drag.fingers == binding->touches) | 448 | if (drag.fingers == binding->touches) |
280 | 419 | { | 449 | { |
285 | 420 | binding->callback (reg->window, | 450 | if (matches_widget (binding->widget, |
286 | 421 | GRIP_TIME_START, | 451 | GTK_WIDGET (reg->window)->window, |
287 | 422 | ((GripGestureEvent*)&drag), | 452 | (gint)drag.focus_x, |
288 | 423 | binding->data); | 453 | (gint)drag.focus_y)) |
289 | 454 | { | ||
290 | 455 | binding->callback (binding->widget, | ||
291 | 456 | GRIP_TIME_START, | ||
292 | 457 | ((GripGestureEvent*)&drag), | ||
293 | 458 | binding->data); | ||
294 | 459 | } | ||
295 | 424 | } | 460 | } |
296 | 425 | } | 461 | } |
297 | 426 | else if (type == GRIP_GESTURE_PINCH) | 462 | else if (type == GRIP_GESTURE_PINCH) |
298 | @@ -435,10 +471,16 @@ | |||
299 | 435 | 471 | ||
300 | 436 | if (pinch.fingers == binding->touches) | 472 | if (pinch.fingers == binding->touches) |
301 | 437 | { | 473 | { |
306 | 438 | binding->callback (reg->window, | 474 | if (matches_widget (binding->widget, |
307 | 439 | GRIP_TIME_START, | 475 | GTK_WIDGET (reg->window)->window, |
308 | 440 | ((GripGestureEvent*)&pinch), | 476 | (gint)pinch.focus_x, |
309 | 441 | binding->data); | 477 | (gint)pinch.focus_y)) |
310 | 478 | { | ||
311 | 479 | binding->callback (binding->widget, | ||
312 | 480 | GRIP_TIME_START, | ||
313 | 481 | ((GripGestureEvent*)&pinch), | ||
314 | 482 | binding->data); | ||
315 | 483 | } | ||
316 | 442 | } | 484 | } |
317 | 443 | } | 485 | } |
318 | 444 | else if (type == GRIP_GESTURE_ROTATE) | 486 | else if (type == GRIP_GESTURE_ROTATE) |
319 | @@ -453,10 +495,16 @@ | |||
320 | 453 | 495 | ||
321 | 454 | if (rotate.fingers == binding->touches) | 496 | if (rotate.fingers == binding->touches) |
322 | 455 | { | 497 | { |
327 | 456 | binding->callback (reg->window, | 498 | if (matches_widget (binding->widget, |
328 | 457 | GRIP_TIME_START, | 499 | GTK_WIDGET (reg->window)->window, |
329 | 458 | ((GripGestureEvent*)&rotate), | 500 | (gint)rotate.focus_x, |
330 | 459 | binding->data); | 501 | (gint)rotate.focus_y)) |
331 | 502 | { | ||
332 | 503 | binding->callback (binding->widget, | ||
333 | 504 | GRIP_TIME_START, | ||
334 | 505 | ((GripGestureEvent*)&rotate), | ||
335 | 506 | binding->data); | ||
336 | 507 | } | ||
337 | 460 | } | 508 | } |
338 | 461 | } | 509 | } |
339 | 462 | else if (type == GRIP_GESTURE_TAP) | 510 | else if (type == GRIP_GESTURE_TAP) |
340 | @@ -471,11 +519,17 @@ | |||
341 | 471 | 519 | ||
342 | 472 | if (tap.fingers == binding->touches) | 520 | if (tap.fingers == binding->touches) |
343 | 473 | { | 521 | { |
349 | 474 | binding->callback (reg->window, | 522 | if (matches_widget (binding->widget, |
350 | 475 | GRIP_TIME_START, | 523 | GTK_WIDGET (reg->window)->window, |
351 | 476 | ((GripGestureEvent*)&tap), | 524 | (gint)tap.focus_x, |
352 | 477 | binding->data); | 525 | (gint)tap.focus_y)) |
353 | 478 | } | 526 | { |
354 | 527 | binding->callback (binding->widget, | ||
355 | 528 | GRIP_TIME_START, | ||
356 | 529 | ((GripGestureEvent*)&tap), | ||
357 | 530 | binding->data); | ||
358 | 531 | } | ||
359 | 532 | } | ||
360 | 479 | } | 533 | } |
361 | 480 | } | 534 | } |
362 | 481 | } | 535 | } |
363 | @@ -509,10 +563,16 @@ | |||
364 | 509 | 563 | ||
365 | 510 | if (drag.fingers == binding->touches) | 564 | if (drag.fingers == binding->touches) |
366 | 511 | { | 565 | { |
371 | 512 | binding->callback (reg->window, | 566 | if (matches_widget (binding->widget, |
372 | 513 | GRIP_TIME_UPDATE, | 567 | GTK_WIDGET (reg->window)->window, |
373 | 514 | ((GripGestureEvent*)&drag), | 568 | (gint)drag.focus_x, |
374 | 515 | binding->data); | 569 | (gint)drag.focus_y)) |
375 | 570 | { | ||
376 | 571 | binding->callback (binding->widget, | ||
377 | 572 | GRIP_TIME_UPDATE, | ||
378 | 573 | ((GripGestureEvent*)&drag), | ||
379 | 574 | binding->data); | ||
380 | 575 | } | ||
381 | 516 | } | 576 | } |
382 | 517 | } | 577 | } |
383 | 518 | else if (type == GRIP_GESTURE_PINCH) | 578 | else if (type == GRIP_GESTURE_PINCH) |
384 | @@ -527,10 +587,16 @@ | |||
385 | 527 | 587 | ||
386 | 528 | if (pinch.fingers == binding->touches) | 588 | if (pinch.fingers == binding->touches) |
387 | 529 | { | 589 | { |
392 | 530 | binding->callback (reg->window, | 590 | if (matches_widget (binding->widget, |
393 | 531 | GRIP_TIME_UPDATE, | 591 | GTK_WIDGET (reg->window)->window, |
394 | 532 | ((GripGestureEvent*)&pinch), | 592 | (gint)pinch.focus_x, |
395 | 533 | binding->data); | 593 | (gint)pinch.focus_y)) |
396 | 594 | { | ||
397 | 595 | binding->callback (binding->widget, | ||
398 | 596 | GRIP_TIME_UPDATE, | ||
399 | 597 | ((GripGestureEvent*)&pinch), | ||
400 | 598 | binding->data); | ||
401 | 599 | } | ||
402 | 534 | } | 600 | } |
403 | 535 | } | 601 | } |
404 | 536 | else if (type == GRIP_GESTURE_ROTATE) | 602 | else if (type == GRIP_GESTURE_ROTATE) |
405 | @@ -545,10 +611,16 @@ | |||
406 | 545 | 611 | ||
407 | 546 | if (rotate.fingers == binding->touches) | 612 | if (rotate.fingers == binding->touches) |
408 | 547 | { | 613 | { |
413 | 548 | binding->callback (reg->window, | 614 | if (matches_widget (binding->widget, |
414 | 549 | GRIP_TIME_UPDATE, | 615 | GTK_WIDGET (reg->window)->window, |
415 | 550 | ((GripGestureEvent*)&rotate), | 616 | (gint)rotate.focus_x, |
416 | 551 | binding->data); | 617 | (gint)rotate.focus_y)) |
417 | 618 | { | ||
418 | 619 | binding->callback (binding->widget, | ||
419 | 620 | GRIP_TIME_UPDATE, | ||
420 | 621 | ((GripGestureEvent*)&rotate), | ||
421 | 622 | binding->data); | ||
422 | 623 | } | ||
423 | 552 | } | 624 | } |
424 | 553 | } | 625 | } |
425 | 554 | else if (type == GRIP_GESTURE_TAP) | 626 | else if (type == GRIP_GESTURE_TAP) |
426 | @@ -563,11 +635,17 @@ | |||
427 | 563 | 635 | ||
428 | 564 | if (tap.fingers == binding->touches) | 636 | if (tap.fingers == binding->touches) |
429 | 565 | { | 637 | { |
435 | 566 | binding->callback (reg->window, | 638 | if (matches_widget (binding->widget, |
436 | 567 | GRIP_TIME_UPDATE, | 639 | GTK_WIDGET (reg->window)->window, |
437 | 568 | ((GripGestureEvent*)&tap), | 640 | (gint)tap.focus_x, |
438 | 569 | binding->data); | 641 | (gint)tap.focus_y)) |
439 | 570 | } | 642 | { |
440 | 643 | binding->callback (binding->widget, | ||
441 | 644 | GRIP_TIME_UPDATE, | ||
442 | 645 | ((GripGestureEvent*)&tap), | ||
443 | 646 | binding->data); | ||
444 | 647 | } | ||
445 | 648 | } | ||
446 | 571 | } | 649 | } |
447 | 572 | } | 650 | } |
448 | 573 | } | 651 | } |
449 | @@ -601,10 +679,16 @@ | |||
450 | 601 | 679 | ||
451 | 602 | if (drag.fingers == binding->touches) | 680 | if (drag.fingers == binding->touches) |
452 | 603 | { | 681 | { |
457 | 604 | binding->callback (reg->window, | 682 | if (matches_widget (binding->widget, |
458 | 605 | GRIP_TIME_END, | 683 | GTK_WIDGET (reg->window)->window, |
459 | 606 | ((GripGestureEvent*)&drag), | 684 | (gint)drag.focus_x, |
460 | 607 | binding->data); | 685 | (gint)drag.focus_y)) |
461 | 686 | { | ||
462 | 687 | binding->callback (binding->widget, | ||
463 | 688 | GRIP_TIME_END, | ||
464 | 689 | ((GripGestureEvent*)&drag), | ||
465 | 690 | binding->data); | ||
466 | 691 | } | ||
467 | 608 | } | 692 | } |
468 | 609 | } | 693 | } |
469 | 610 | else if (type == GRIP_GESTURE_PINCH) | 694 | else if (type == GRIP_GESTURE_PINCH) |
470 | @@ -619,10 +703,16 @@ | |||
471 | 619 | 703 | ||
472 | 620 | if (pinch.fingers == binding->touches) | 704 | if (pinch.fingers == binding->touches) |
473 | 621 | { | 705 | { |
478 | 622 | binding->callback (reg->window, | 706 | if (matches_widget (binding->widget, |
479 | 623 | GRIP_TIME_END, | 707 | GTK_WIDGET (reg->window)->window, |
480 | 624 | ((GripGestureEvent*)&pinch), | 708 | (gint)pinch.focus_x, |
481 | 625 | binding->data); | 709 | (gint)pinch.focus_y)) |
482 | 710 | { | ||
483 | 711 | binding->callback (binding->widget, | ||
484 | 712 | GRIP_TIME_END, | ||
485 | 713 | ((GripGestureEvent*)&pinch), | ||
486 | 714 | binding->data); | ||
487 | 715 | } | ||
488 | 626 | } | 716 | } |
489 | 627 | } | 717 | } |
490 | 628 | else if (type == GRIP_GESTURE_ROTATE) | 718 | else if (type == GRIP_GESTURE_ROTATE) |
491 | @@ -637,10 +727,16 @@ | |||
492 | 637 | 727 | ||
493 | 638 | if (rotate.fingers == binding->touches) | 728 | if (rotate.fingers == binding->touches) |
494 | 639 | { | 729 | { |
499 | 640 | binding->callback (reg->window, | 730 | if (matches_widget (binding->widget, |
500 | 641 | GRIP_TIME_END, | 731 | GTK_WIDGET (reg->window)->window, |
501 | 642 | ((GripGestureEvent*)&rotate), | 732 | (gint)rotate.focus_x, |
502 | 643 | binding->data); | 733 | (gint)rotate.focus_y)) |
503 | 734 | { | ||
504 | 735 | binding->callback (binding->widget, | ||
505 | 736 | GRIP_TIME_END, | ||
506 | 737 | ((GripGestureEvent*)&rotate), | ||
507 | 738 | binding->data); | ||
508 | 739 | } | ||
509 | 644 | } | 740 | } |
510 | 645 | } | 741 | } |
511 | 646 | else if (type == GRIP_GESTURE_TAP) | 742 | else if (type == GRIP_GESTURE_TAP) |
512 | @@ -655,11 +751,17 @@ | |||
513 | 655 | 751 | ||
514 | 656 | if (tap.fingers == binding->touches) | 752 | if (tap.fingers == binding->touches) |
515 | 657 | { | 753 | { |
521 | 658 | binding->callback (reg->window, | 754 | if (matches_widget (binding->widget, |
522 | 659 | GRIP_TIME_END, | 755 | GTK_WIDGET (reg->window)->window, |
523 | 660 | ((GripGestureEvent*)&tap), | 756 | (gint)tap.focus_x, |
524 | 661 | binding->data); | 757 | (gint)tap.focus_y)) |
525 | 662 | } | 758 | { |
526 | 759 | binding->callback (binding->widget, | ||
527 | 760 | GRIP_TIME_END, | ||
528 | 761 | ((GripGestureEvent*)&tap), | ||
529 | 762 | binding->data); | ||
530 | 763 | } | ||
531 | 764 | } | ||
532 | 663 | } | 765 | } |
533 | 664 | } | 766 | } |
534 | 665 | } | 767 | } |
535 | @@ -730,7 +832,7 @@ | |||
536 | 730 | 832 | ||
537 | 731 | static void | 833 | static void |
538 | 732 | register_internal (GripGestureManager *manager, | 834 | register_internal (GripGestureManager *manager, |
540 | 733 | GtkWindow *window, | 835 | GtkWidget *widget, |
541 | 734 | GripGestureType gesture_type, | 836 | GripGestureType gesture_type, |
542 | 735 | gint touch_points, | 837 | gint touch_points, |
543 | 736 | GripGestureCallback callback, | 838 | GripGestureCallback callback, |
544 | @@ -740,12 +842,18 @@ | |||
545 | 740 | GripGestureManagerPrivate *priv; | 842 | GripGestureManagerPrivate *priv; |
546 | 741 | GripGestureRegistration *reg; | 843 | GripGestureRegistration *reg; |
547 | 742 | GripGestureBinding *binding; | 844 | GripGestureBinding *binding; |
548 | 845 | GtkWidget *toplevel; | ||
549 | 743 | 846 | ||
550 | 744 | g_return_if_fail (GRIP_IS_GESTURE_MANAGER (manager)); | 847 | g_return_if_fail (GRIP_IS_GESTURE_MANAGER (manager)); |
551 | 848 | g_return_if_fail (GTK_IS_WIDGET (widget)); | ||
552 | 849 | |||
553 | 850 | toplevel = gtk_widget_get_toplevel (widget); | ||
554 | 851 | |||
555 | 852 | g_return_if_fail (GTK_IS_WINDOW (toplevel)); | ||
556 | 745 | 853 | ||
557 | 746 | priv = manager->priv; | 854 | priv = manager->priv; |
558 | 747 | 855 | ||
560 | 748 | if (!(reg = g_hash_table_lookup (priv->hash, window))) | 856 | if (!(reg = g_hash_table_lookup (priv->hash, toplevel))) |
561 | 749 | { | 857 | { |
562 | 750 | GeisInstance instance; | 858 | GeisInstance instance; |
563 | 751 | GIOChannel *iochannel; | 859 | GIOChannel *iochannel; |
564 | @@ -753,7 +861,7 @@ | |||
565 | 753 | GeisXcbWinInfo xcb_win_info = { | 861 | GeisXcbWinInfo xcb_win_info = { |
566 | 754 | .display_name = NULL, | 862 | .display_name = NULL, |
567 | 755 | .screenp = NULL, | 863 | .screenp = NULL, |
569 | 756 | .window_id = GDK_DRAWABLE_XID (GTK_WIDGET (window)->window) | 864 | .window_id = GDK_DRAWABLE_XID (toplevel->window) |
570 | 757 | }; | 865 | }; |
571 | 758 | GeisWinInfo win_info = { | 866 | GeisWinInfo win_info = { |
572 | 759 | GEIS_XCB_FULL_WINDOW, | 867 | GEIS_XCB_FULL_WINDOW, |
573 | @@ -783,10 +891,10 @@ | |||
574 | 783 | 891 | ||
575 | 784 | reg = g_new0 (GripGestureRegistration, 1); | 892 | reg = g_new0 (GripGestureRegistration, 1); |
576 | 785 | 893 | ||
578 | 786 | reg->window = window; | 894 | reg->window = GTK_WINDOW (toplevel); |
579 | 787 | reg->instance = instance; | 895 | reg->instance = instance; |
580 | 788 | 896 | ||
582 | 789 | g_signal_connect (window, | 897 | g_signal_connect (toplevel, |
583 | 790 | "destroy", | 898 | "destroy", |
584 | 791 | G_CALLBACK (window_destroyed_cb), | 899 | G_CALLBACK (window_destroyed_cb), |
585 | 792 | manager); | 900 | manager); |
586 | @@ -810,6 +918,7 @@ | |||
587 | 810 | binding = g_new0 (GripGestureBinding, 1); | 918 | binding = g_new0 (GripGestureBinding, 1); |
588 | 811 | 919 | ||
589 | 812 | binding->type = gesture_type; | 920 | binding->type = gesture_type; |
590 | 921 | binding->widget = widget; | ||
591 | 813 | binding->touches = touch_points; | 922 | binding->touches = touch_points; |
592 | 814 | binding->callback = callback; | 923 | binding->callback = callback; |
593 | 815 | binding->data = user_data; | 924 | binding->data = user_data; |
594 | @@ -818,11 +927,101 @@ | |||
595 | 818 | reg->bindings = g_list_append (reg->bindings, binding); | 927 | reg->bindings = g_list_append (reg->bindings, binding); |
596 | 819 | 928 | ||
597 | 820 | g_hash_table_insert (priv->hash, | 929 | g_hash_table_insert (priv->hash, |
599 | 821 | window, | 930 | toplevel, |
600 | 822 | reg); | 931 | reg); |
601 | 823 | } | 932 | } |
602 | 824 | 933 | ||
603 | 825 | static void | 934 | static void |
604 | 935 | toplevel_notify_cb (GtkWidget *widget, | ||
605 | 936 | GParamSpec *pspec, | ||
606 | 937 | gpointer user_data) | ||
607 | 938 | { | ||
608 | 939 | if (pspec->name == g_intern_static_string ("parent")) | ||
609 | 940 | { | ||
610 | 941 | GtkWidget *toplevel = gtk_widget_get_toplevel (widget); | ||
611 | 942 | GripRegistrationRequest *req = (GripRegistrationRequest *)user_data; | ||
612 | 943 | |||
613 | 944 | if (GTK_IS_WINDOW (toplevel)) | ||
614 | 945 | { | ||
615 | 946 | g_signal_handlers_disconnect_by_func (widget, | ||
616 | 947 | G_CALLBACK (toplevel_notify_cb), | ||
617 | 948 | user_data); | ||
618 | 949 | |||
619 | 950 | if (gtk_widget_get_mapped (GTK_WIDGET (toplevel))) | ||
620 | 951 | { | ||
621 | 952 | register_internal (req->manager, | ||
622 | 953 | req->widget, | ||
623 | 954 | req->gesture_type, | ||
624 | 955 | req->touch_points, | ||
625 | 956 | req->callback, | ||
626 | 957 | req->user_data, | ||
627 | 958 | req->destroy); | ||
628 | 959 | |||
629 | 960 | g_free (req); | ||
630 | 961 | } | ||
631 | 962 | else | ||
632 | 963 | { | ||
633 | 964 | GripGestureManagerPrivate *priv = req->manager->priv; | ||
634 | 965 | |||
635 | 966 | priv->requests = g_list_append (priv->requests, req); | ||
636 | 967 | |||
637 | 968 | g_signal_connect (toplevel, | ||
638 | 969 | "map-event", | ||
639 | 970 | G_CALLBACK (window_mapped_cb), | ||
640 | 971 | req->manager); | ||
641 | 972 | } | ||
642 | 973 | } | ||
643 | 974 | else | ||
644 | 975 | { | ||
645 | 976 | g_signal_connect (G_OBJECT (toplevel), | ||
646 | 977 | "notify", | ||
647 | 978 | G_CALLBACK (toplevel_notify_cb), | ||
648 | 979 | user_data); | ||
649 | 980 | } | ||
650 | 981 | } | ||
651 | 982 | } | ||
652 | 983 | |||
653 | 984 | static void | ||
654 | 985 | register_widget (GripGestureManager *manager, | ||
655 | 986 | GtkWidget *widget, | ||
656 | 987 | GripGestureType gesture_type, | ||
657 | 988 | gint touch_points, | ||
658 | 989 | GripGestureCallback callback, | ||
659 | 990 | gpointer user_data, | ||
660 | 991 | GDestroyNotify destroy) | ||
661 | 992 | { | ||
662 | 993 | GtkWidget *toplevel = gtk_widget_get_toplevel (widget); | ||
663 | 994 | |||
664 | 995 | if (GTK_IS_WINDOW (toplevel)) | ||
665 | 996 | { | ||
666 | 997 | register_internal (manager, | ||
667 | 998 | widget, | ||
668 | 999 | gesture_type, | ||
669 | 1000 | touch_points, | ||
670 | 1001 | callback, | ||
671 | 1002 | user_data, | ||
672 | 1003 | destroy); | ||
673 | 1004 | } | ||
674 | 1005 | else | ||
675 | 1006 | { | ||
676 | 1007 | GripRegistrationRequest *req = g_new0 (GripRegistrationRequest, 1); | ||
677 | 1008 | |||
678 | 1009 | req->manager = manager; | ||
679 | 1010 | req->widget = widget; | ||
680 | 1011 | req->gesture_type = gesture_type; | ||
681 | 1012 | req->touch_points = touch_points; | ||
682 | 1013 | req->callback = callback; | ||
683 | 1014 | req->user_data = user_data; | ||
684 | 1015 | req->destroy = destroy; | ||
685 | 1016 | |||
686 | 1017 | g_signal_connect (toplevel, | ||
687 | 1018 | "notify", | ||
688 | 1019 | G_CALLBACK (toplevel_notify_cb), | ||
689 | 1020 | req); | ||
690 | 1021 | } | ||
691 | 1022 | } | ||
692 | 1023 | |||
693 | 1024 | static void | ||
694 | 826 | window_mapped_cb (GtkWidget *widget, | 1025 | window_mapped_cb (GtkWidget *widget, |
695 | 827 | GdkEvent *event, | 1026 | GdkEvent *event, |
696 | 828 | gpointer user_data) | 1027 | gpointer user_data) |
697 | @@ -835,13 +1034,13 @@ | |||
698 | 835 | { | 1034 | { |
699 | 836 | GripRegistrationRequest *req = tmp->data; | 1035 | GripRegistrationRequest *req = tmp->data; |
700 | 837 | 1036 | ||
708 | 838 | register_internal (req->manager, | 1037 | register_widget (req->manager, |
709 | 839 | req->window, | 1038 | req->widget, |
710 | 840 | req->gesture_type, | 1039 | req->gesture_type, |
711 | 841 | req->touch_points, | 1040 | req->touch_points, |
712 | 842 | req->callback, | 1041 | req->callback, |
713 | 843 | req->user_data, | 1042 | req->user_data, |
714 | 844 | req->destroy); | 1043 | req->destroy); |
715 | 845 | 1044 | ||
716 | 846 | g_free (req); | 1045 | g_free (req); |
717 | 847 | } | 1046 | } |
718 | @@ -871,44 +1070,68 @@ | |||
719 | 871 | */ | 1070 | */ |
720 | 872 | void | 1071 | void |
721 | 873 | grip_gesture_manager_register_window (GripGestureManager *manager, | 1072 | grip_gesture_manager_register_window (GripGestureManager *manager, |
723 | 874 | GtkWindow *window, | 1073 | GtkWidget *widget, |
724 | 875 | GripGestureType gesture_type, | 1074 | GripGestureType gesture_type, |
725 | 876 | gint touch_points, | 1075 | gint touch_points, |
726 | 877 | GripGestureCallback callback, | 1076 | GripGestureCallback callback, |
727 | 878 | gpointer user_data, | 1077 | gpointer user_data, |
728 | 879 | GDestroyNotify destroy) | 1078 | GDestroyNotify destroy) |
729 | 880 | { | 1079 | { |
730 | 1080 | GtkWidget *toplevel; | ||
731 | 1081 | |||
732 | 881 | g_return_if_fail (GRIP_IS_GESTURE_MANAGER (manager)); | 1082 | g_return_if_fail (GRIP_IS_GESTURE_MANAGER (manager)); |
736 | 882 | g_return_if_fail (GTK_IS_WINDOW (window)); | 1083 | g_return_if_fail (GTK_IS_WIDGET (widget)); |
737 | 883 | 1084 | ||
738 | 884 | if (gtk_widget_get_mapped (GTK_WIDGET (window))) | 1085 | toplevel = gtk_widget_get_toplevel (widget); |
739 | 1086 | |||
740 | 1087 | if (GTK_IS_WINDOW (toplevel)) | ||
741 | 885 | { | 1088 | { |
749 | 886 | register_internal (manager, | 1089 | if (gtk_widget_get_mapped (GTK_WIDGET (toplevel))) |
750 | 887 | window, | 1090 | { |
751 | 888 | gesture_type, | 1091 | register_internal (manager, |
752 | 889 | touch_points, | 1092 | widget, |
753 | 890 | callback, | 1093 | gesture_type, |
754 | 891 | user_data, | 1094 | touch_points, |
755 | 892 | destroy); | 1095 | callback, |
756 | 1096 | user_data, | ||
757 | 1097 | destroy); | ||
758 | 1098 | } | ||
759 | 1099 | else | ||
760 | 1100 | { | ||
761 | 1101 | GripRegistrationRequest *req = g_new0 (GripRegistrationRequest, 1); | ||
762 | 1102 | GripGestureManagerPrivate *priv = manager->priv; | ||
763 | 1103 | |||
764 | 1104 | req->manager = manager; | ||
765 | 1105 | req->widget = widget; | ||
766 | 1106 | req->gesture_type = gesture_type; | ||
767 | 1107 | req->touch_points = touch_points; | ||
768 | 1108 | req->callback = callback; | ||
769 | 1109 | req->user_data = user_data; | ||
770 | 1110 | req->destroy = destroy; | ||
771 | 1111 | |||
772 | 1112 | priv->requests = g_list_append (priv->requests, req); | ||
773 | 1113 | |||
774 | 1114 | g_signal_connect (toplevel, | ||
775 | 1115 | "map-event", | ||
776 | 1116 | G_CALLBACK (window_mapped_cb), | ||
777 | 1117 | manager); | ||
778 | 1118 | } | ||
779 | 893 | } | 1119 | } |
780 | 894 | else | 1120 | else |
781 | 895 | { | 1121 | { |
782 | 896 | GripRegistrationRequest *req = g_new0 (GripRegistrationRequest, 1); | 1122 | GripRegistrationRequest *req = g_new0 (GripRegistrationRequest, 1); |
783 | 897 | GripGestureManagerPrivate *priv = manager->priv; | ||
784 | 898 | 1123 | ||
785 | 899 | req->manager = manager; | 1124 | req->manager = manager; |
787 | 900 | req->window = window; | 1125 | req->widget = widget; |
788 | 901 | req->gesture_type = gesture_type; | 1126 | req->gesture_type = gesture_type; |
789 | 902 | req->touch_points = touch_points; | 1127 | req->touch_points = touch_points; |
790 | 903 | req->callback = callback; | 1128 | req->callback = callback; |
791 | 904 | req->user_data = user_data; | 1129 | req->user_data = user_data; |
792 | 905 | req->destroy = destroy; | 1130 | req->destroy = destroy; |
793 | 906 | 1131 | ||
800 | 907 | priv->requests = g_list_append (priv->requests, req); | 1132 | g_signal_connect (toplevel, |
801 | 908 | 1133 | "notify", | |
802 | 909 | g_signal_connect (window, | 1134 | G_CALLBACK (toplevel_notify_cb), |
803 | 910 | "map-event", | 1135 | req); |
798 | 911 | G_CALLBACK (window_mapped_cb), | ||
799 | 912 | manager); | ||
804 | 913 | } | 1136 | } |
805 | 914 | } | 1137 | } |
806 | 915 | 1138 | ||
807 | === modified file 'src/gripgesturemanager.h' | |||
808 | --- src/gripgesturemanager.h 2010-11-22 14:49:44 +0000 | |||
809 | +++ src/gripgesturemanager.h 2010-12-10 18:01:55 +0000 | |||
810 | @@ -122,6 +122,8 @@ | |||
811 | 122 | guint fingers; | 122 | guint fingers; |
812 | 123 | 123 | ||
813 | 124 | guint32 tap_time; | 124 | guint32 tap_time; |
814 | 125 | gfloat focus_x; | ||
815 | 126 | gfloat focus_y; | ||
816 | 125 | gfloat position_x; | 127 | gfloat position_x; |
817 | 126 | gfloat position_y; | 128 | gfloat position_y; |
818 | 127 | }; | 129 | }; |
819 | @@ -159,7 +161,7 @@ | |||
820 | 159 | GObjectClass parent_class; | 161 | GObjectClass parent_class; |
821 | 160 | }; | 162 | }; |
822 | 161 | 163 | ||
824 | 162 | typedef void (* GripGestureCallback) (GtkWindow *window, | 164 | typedef void (* GripGestureCallback) (GtkWidget *widget, |
825 | 163 | GripTimeType time, | 165 | GripTimeType time, |
826 | 164 | GripGestureEvent *gesture, | 166 | GripGestureEvent *gesture, |
827 | 165 | gpointer user_data); | 167 | gpointer user_data); |
828 | @@ -167,12 +169,12 @@ | |||
829 | 167 | GType grip_gesture_manager_get_type (void) G_GNUC_CONST; | 169 | GType grip_gesture_manager_get_type (void) G_GNUC_CONST; |
830 | 168 | GripGestureManager *grip_gesture_manager_get (void); | 170 | GripGestureManager *grip_gesture_manager_get (void); |
831 | 169 | void grip_gesture_manager_register_window (GripGestureManager *manager, | 171 | void grip_gesture_manager_register_window (GripGestureManager *manager, |
833 | 170 | GtkWindow *window, | 172 | GtkWidget *widget, |
834 | 171 | GripGestureType gesture_type, | 173 | GripGestureType gesture_type, |
836 | 172 | gint touch_points, | 174 | gint touch_points, |
837 | 173 | GripGestureCallback callback, | 175 | GripGestureCallback callback, |
840 | 174 | gpointer user_data, | 176 | gpointer user_data, |
841 | 175 | GDestroyNotify destroy); | 177 | GDestroyNotify destroy); |
842 | 176 | 178 | ||
843 | 177 | G_END_DECLS | 179 | G_END_DECLS |
844 | 178 | 180 |
Code compiles OK and the supplied test program draws a barbie pink box that rotates, drags, expands, shrinks, and entertains for minutes on end when gesturing over the drawing area and nowhere else, but only the Quit button responds to a 2-finger tap (as expected).
The code looks clean. This is a good change.