Merge lp:~bratsche/libgrip/event-routing into lp:libgrip

Proposed by Cody Russell
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
Reviewer Review Type Date Requested Status
Henrik Rydberg (community) Needs Information
Stephen M. Webb (community) Approve
Review via email: mp+43378@code.launchpad.net

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.

To post a comment you must log in.
Revision history for this message
Stephen M. Webb (bregma) wrote :

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.

review: Approve
Revision history for this message
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.

review: Needs Information

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
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 return FALSE;
6 }
7
8-GtkWidget *
9-create_window (void)
10+static void
11+button_tap (GtkWidget *widget,
12+ GripTimeType time_type,
13+ GripGestureEvent *event,
14+ gpointer user_data)
15 {
16- GtkWidget *window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
17- GtkWidget *da;
18- const GdkColor white = { 0, 0xffff, 0xffff, 0xffff };
19-
20- gtk_window_set_title (GTK_WINDOW (window), "Touch Demo");
21- gtk_window_set_default_size (GTK_WINDOW (window), 600, 600);
22- g_signal_connect (window, "destroy", G_CALLBACK (gtk_widget_destroyed), &window);
23-
24- da = gtk_drawing_area_new ();
25- gtk_container_add (GTK_CONTAINER (window), da);
26-
27- gtk_widget_modify_bg (da, GTK_STATE_NORMAL, &white);
28-
29- g_signal_connect (da, "expose-event",
30- G_CALLBACK (expose_event), NULL);
31-
32- return window;
33+ g_signal_emit_by_name (widget, "clicked");
34 }
35
36 static void
37-gesture_callback (GtkWindow *window,
38+gesture_callback (GtkWidget *widget,
39 GripTimeType time_type,
40- GripGestureEvent *event,
41+ GripGestureEvent *event,
42 gpointer user_data)
43 {
44 if (time_type == GRIP_TIME_START)
45@@ -103,12 +90,106 @@
46 }
47 break;
48
49- case GRIP_GESTURE_TAP:
50- break;
51+ case GRIP_GESTURE_TAP:
52+ break;
53 }
54 }
55
56- gtk_widget_queue_draw (GTK_WIDGET (window));
57+ gtk_widget_queue_draw (GTK_WIDGET (widget));
58+}
59+
60+
61+static GtkTreeModel *
62+create_model ()
63+{
64+ return (GtkTreeModel *)gtk_list_store_new (1, G_TYPE_STRING);
65+}
66+
67+static GtkWidget *
68+create_window (GripGestureManager *manager)
69+{
70+ GtkWidget *window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
71+ GtkWidget *da;
72+ GtkWidget *hbox;
73+ GtkWidget *vbox;
74+ GtkWidget *button;
75+ GtkWidget *tv;
76+ GtkTreeModel *model;
77+ GtkWidget *sw;
78+ const GdkColor white = { 0, 0xffff, 0xffff, 0xffff };
79+
80+ da = gtk_drawing_area_new ();
81+
82+ gtk_window_set_title (GTK_WINDOW (window), "Touch Demo");
83+ gtk_window_set_default_size (GTK_WINDOW (window), 600, 600);
84+ g_signal_connect (window, "destroy", G_CALLBACK (gtk_widget_destroyed), &window);
85+ g_signal_connect (window, "destroy", G_CALLBACK (gtk_main_quit), NULL);
86+
87+ hbox = gtk_hbox_new (FALSE, 0);
88+ vbox = gtk_vbox_new (FALSE, 0);
89+
90+ gtk_box_pack_start (GTK_BOX (hbox), vbox, FALSE, FALSE, 0);
91+ gtk_box_pack_start (GTK_BOX (hbox), da, TRUE, TRUE, 0);
92+
93+ model = create_model ();
94+ sw = gtk_scrolled_window_new (NULL, NULL);
95+ tv = gtk_tree_view_new_with_model (model);
96+ g_object_unref (model);
97+
98+ gtk_container_add (GTK_CONTAINER (sw), tv);
99+
100+ gtk_box_pack_start (GTK_BOX (vbox), sw, TRUE, TRUE, 0);
101+
102+ button = gtk_button_new_with_label ("Quit");
103+ g_signal_connect (button,
104+ "clicked",
105+ G_CALLBACK (gtk_main_quit),
106+ NULL);
107+ grip_gesture_manager_register_window (manager,
108+ button,
109+ GRIP_GESTURE_TAP,
110+ 1,
111+ button_tap,
112+ NULL, NULL);
113+
114+ gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
115+
116+ gtk_container_add (GTK_CONTAINER (window), hbox);
117+
118+ gtk_widget_modify_bg (da, GTK_STATE_NORMAL, &white);
119+
120+ g_signal_connect (da, "expose-event",
121+ G_CALLBACK (expose_event), NULL);
122+
123+ grip_gesture_manager_register_window (manager,
124+ da,
125+ GRIP_GESTURE_PINCH,
126+ 2,
127+ gesture_callback,
128+ NULL, NULL);
129+
130+ grip_gesture_manager_register_window (manager,
131+ da,
132+ GRIP_GESTURE_ROTATE,
133+ 2,
134+ gesture_callback,
135+ NULL, NULL);
136+
137+ grip_gesture_manager_register_window (manager,
138+ da,
139+ GRIP_GESTURE_DRAG,
140+ 2,
141+ gesture_callback,
142+ NULL, NULL);
143+
144+ grip_gesture_manager_register_window (manager,
145+ da,
146+ GRIP_GESTURE_TAP,
147+ 2,
148+ gesture_callback,
149+ NULL, NULL);
150+
151+ return window;
152 }
153
154 static void
155@@ -122,7 +203,7 @@
156 int
157 main (int argc, char **argv)
158 {
159- GtkWindow *window;
160+ GtkWidget *window;
161 GripGestureManager *manager;
162
163 gtk_init (&argc, &argv);
164@@ -131,40 +212,11 @@
165 * my Dell XT2 has in it. */
166 signal (SIGABRT, abort_handler);
167
168- window = (GtkWindow *)create_window ();
169 manager = grip_gesture_manager_get ();
170+ window = create_window (manager);
171
172 g_signal_connect (window, "destroy", G_CALLBACK (gtk_main_quit), NULL);
173
174- grip_gesture_manager_register_window (manager,
175- window,
176- GRIP_GESTURE_PINCH,
177- 2,
178- gesture_callback,
179- NULL, NULL);
180-
181- grip_gesture_manager_register_window (manager,
182- window,
183- GRIP_GESTURE_ROTATE,
184- 2,
185- gesture_callback,
186- NULL, NULL);
187-
188- grip_gesture_manager_register_window (manager,
189- window,
190- GRIP_GESTURE_DRAG,
191- 2,
192- gesture_callback,
193- NULL, NULL);
194-
195- grip_gesture_manager_register_window (manager,
196- window,
197- GRIP_GESTURE_TAP,
198- 2,
199- gesture_callback,
200- NULL, NULL);
201-
202-
203 gtk_widget_show_all (GTK_WIDGET (window));
204
205 gtk_main ();
206
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 struct _GripGestureBinding
212 {
213 GripGestureType type;
214+ GtkWidget *widget;
215 gint touches;
216 GripGestureCallback callback;
217 gpointer data;
218@@ -58,7 +59,7 @@
219 struct _GripRegistrationRequest
220 {
221 GripGestureManager *manager;
222- GtkWindow *window;
223+ GtkWidget *widget;
224 GripGestureType gesture_type;
225 gint touch_points;
226 GripGestureCallback callback;
227@@ -96,6 +97,10 @@
228 GeisSize attr_count,
229 GeisGestureAttr *attrs);
230
231+static void window_mapped_cb (GtkWidget *widget,
232+ GdkEvent *event,
233+ gpointer user_data);
234+
235 static GripGestureManager *manager_singleton = NULL;
236 static GeisGestureFuncs gesture_funcs = {
237 gesture_added,
238@@ -351,6 +356,16 @@
239 {
240 event->timestamp = attrs[i].integer_val;
241 }
242+ else if (g_strcmp0 (attrs[i].name, GEIS_GESTURE_ATTRIBUTE_FOCUS_X) == 0 &&
243+ attrs[i].type == GEIS_ATTR_TYPE_FLOAT)
244+ {
245+ event->focus_x = attrs[i].float_val;
246+ }
247+ else if (g_strcmp0 (attrs[i].name, GEIS_GESTURE_ATTRIBUTE_FOCUS_Y) == 0 &&
248+ attrs[i].type == GEIS_ATTR_TYPE_FLOAT)
249+ {
250+ event->focus_y = attrs[i].float_val;
251+ }
252 else if (g_strcmp0 (attrs[i].name, GEIS_GESTURE_ATTRIBUTE_POSITION_X) == 0 &&
253 attrs[i].type == GEIS_ATTR_TYPE_FLOAT)
254 {
255@@ -389,6 +404,21 @@
256 {
257 }
258
259+static gboolean
260+matches_widget (GtkWidget *widget,
261+ GdkWindow *window,
262+ gint x,
263+ gint y)
264+{
265+ GtkAllocation alloc;
266+ gint ax, ay;
267+
268+ gtk_widget_get_allocation (widget, &alloc);
269+ gdk_window_get_root_coords (window, alloc.x, alloc.y, &ax, &ay);
270+
271+ return (x >= ax && x < ax + alloc.width && y >= ay && y < ay + alloc.height);
272+}
273+
274 static void
275 gesture_start (void *cookie,
276 GeisGestureType type,
277@@ -417,10 +447,16 @@
278
279 if (drag.fingers == binding->touches)
280 {
281- binding->callback (reg->window,
282- GRIP_TIME_START,
283- ((GripGestureEvent*)&drag),
284- binding->data);
285+ if (matches_widget (binding->widget,
286+ GTK_WIDGET (reg->window)->window,
287+ (gint)drag.focus_x,
288+ (gint)drag.focus_y))
289+ {
290+ binding->callback (binding->widget,
291+ GRIP_TIME_START,
292+ ((GripGestureEvent*)&drag),
293+ binding->data);
294+ }
295 }
296 }
297 else if (type == GRIP_GESTURE_PINCH)
298@@ -435,10 +471,16 @@
299
300 if (pinch.fingers == binding->touches)
301 {
302- binding->callback (reg->window,
303- GRIP_TIME_START,
304- ((GripGestureEvent*)&pinch),
305- binding->data);
306+ if (matches_widget (binding->widget,
307+ GTK_WIDGET (reg->window)->window,
308+ (gint)pinch.focus_x,
309+ (gint)pinch.focus_y))
310+ {
311+ binding->callback (binding->widget,
312+ GRIP_TIME_START,
313+ ((GripGestureEvent*)&pinch),
314+ binding->data);
315+ }
316 }
317 }
318 else if (type == GRIP_GESTURE_ROTATE)
319@@ -453,10 +495,16 @@
320
321 if (rotate.fingers == binding->touches)
322 {
323- binding->callback (reg->window,
324- GRIP_TIME_START,
325- ((GripGestureEvent*)&rotate),
326- binding->data);
327+ if (matches_widget (binding->widget,
328+ GTK_WIDGET (reg->window)->window,
329+ (gint)rotate.focus_x,
330+ (gint)rotate.focus_y))
331+ {
332+ binding->callback (binding->widget,
333+ GRIP_TIME_START,
334+ ((GripGestureEvent*)&rotate),
335+ binding->data);
336+ }
337 }
338 }
339 else if (type == GRIP_GESTURE_TAP)
340@@ -471,11 +519,17 @@
341
342 if (tap.fingers == binding->touches)
343 {
344- binding->callback (reg->window,
345- GRIP_TIME_START,
346- ((GripGestureEvent*)&tap),
347- binding->data);
348- }
349+ if (matches_widget (binding->widget,
350+ GTK_WIDGET (reg->window)->window,
351+ (gint)tap.focus_x,
352+ (gint)tap.focus_y))
353+ {
354+ binding->callback (binding->widget,
355+ GRIP_TIME_START,
356+ ((GripGestureEvent*)&tap),
357+ binding->data);
358+ }
359+ }
360 }
361 }
362 }
363@@ -509,10 +563,16 @@
364
365 if (drag.fingers == binding->touches)
366 {
367- binding->callback (reg->window,
368- GRIP_TIME_UPDATE,
369- ((GripGestureEvent*)&drag),
370- binding->data);
371+ if (matches_widget (binding->widget,
372+ GTK_WIDGET (reg->window)->window,
373+ (gint)drag.focus_x,
374+ (gint)drag.focus_y))
375+ {
376+ binding->callback (binding->widget,
377+ GRIP_TIME_UPDATE,
378+ ((GripGestureEvent*)&drag),
379+ binding->data);
380+ }
381 }
382 }
383 else if (type == GRIP_GESTURE_PINCH)
384@@ -527,10 +587,16 @@
385
386 if (pinch.fingers == binding->touches)
387 {
388- binding->callback (reg->window,
389- GRIP_TIME_UPDATE,
390- ((GripGestureEvent*)&pinch),
391- binding->data);
392+ if (matches_widget (binding->widget,
393+ GTK_WIDGET (reg->window)->window,
394+ (gint)pinch.focus_x,
395+ (gint)pinch.focus_y))
396+ {
397+ binding->callback (binding->widget,
398+ GRIP_TIME_UPDATE,
399+ ((GripGestureEvent*)&pinch),
400+ binding->data);
401+ }
402 }
403 }
404 else if (type == GRIP_GESTURE_ROTATE)
405@@ -545,10 +611,16 @@
406
407 if (rotate.fingers == binding->touches)
408 {
409- binding->callback (reg->window,
410- GRIP_TIME_UPDATE,
411- ((GripGestureEvent*)&rotate),
412- binding->data);
413+ if (matches_widget (binding->widget,
414+ GTK_WIDGET (reg->window)->window,
415+ (gint)rotate.focus_x,
416+ (gint)rotate.focus_y))
417+ {
418+ binding->callback (binding->widget,
419+ GRIP_TIME_UPDATE,
420+ ((GripGestureEvent*)&rotate),
421+ binding->data);
422+ }
423 }
424 }
425 else if (type == GRIP_GESTURE_TAP)
426@@ -563,11 +635,17 @@
427
428 if (tap.fingers == binding->touches)
429 {
430- binding->callback (reg->window,
431- GRIP_TIME_UPDATE,
432- ((GripGestureEvent*)&tap),
433- binding->data);
434- }
435+ if (matches_widget (binding->widget,
436+ GTK_WIDGET (reg->window)->window,
437+ (gint)tap.focus_x,
438+ (gint)tap.focus_y))
439+ {
440+ binding->callback (binding->widget,
441+ GRIP_TIME_UPDATE,
442+ ((GripGestureEvent*)&tap),
443+ binding->data);
444+ }
445+ }
446 }
447 }
448 }
449@@ -601,10 +679,16 @@
450
451 if (drag.fingers == binding->touches)
452 {
453- binding->callback (reg->window,
454- GRIP_TIME_END,
455- ((GripGestureEvent*)&drag),
456- binding->data);
457+ if (matches_widget (binding->widget,
458+ GTK_WIDGET (reg->window)->window,
459+ (gint)drag.focus_x,
460+ (gint)drag.focus_y))
461+ {
462+ binding->callback (binding->widget,
463+ GRIP_TIME_END,
464+ ((GripGestureEvent*)&drag),
465+ binding->data);
466+ }
467 }
468 }
469 else if (type == GRIP_GESTURE_PINCH)
470@@ -619,10 +703,16 @@
471
472 if (pinch.fingers == binding->touches)
473 {
474- binding->callback (reg->window,
475- GRIP_TIME_END,
476- ((GripGestureEvent*)&pinch),
477- binding->data);
478+ if (matches_widget (binding->widget,
479+ GTK_WIDGET (reg->window)->window,
480+ (gint)pinch.focus_x,
481+ (gint)pinch.focus_y))
482+ {
483+ binding->callback (binding->widget,
484+ GRIP_TIME_END,
485+ ((GripGestureEvent*)&pinch),
486+ binding->data);
487+ }
488 }
489 }
490 else if (type == GRIP_GESTURE_ROTATE)
491@@ -637,10 +727,16 @@
492
493 if (rotate.fingers == binding->touches)
494 {
495- binding->callback (reg->window,
496- GRIP_TIME_END,
497- ((GripGestureEvent*)&rotate),
498- binding->data);
499+ if (matches_widget (binding->widget,
500+ GTK_WIDGET (reg->window)->window,
501+ (gint)rotate.focus_x,
502+ (gint)rotate.focus_y))
503+ {
504+ binding->callback (binding->widget,
505+ GRIP_TIME_END,
506+ ((GripGestureEvent*)&rotate),
507+ binding->data);
508+ }
509 }
510 }
511 else if (type == GRIP_GESTURE_TAP)
512@@ -655,11 +751,17 @@
513
514 if (tap.fingers == binding->touches)
515 {
516- binding->callback (reg->window,
517- GRIP_TIME_END,
518- ((GripGestureEvent*)&tap),
519- binding->data);
520- }
521+ if (matches_widget (binding->widget,
522+ GTK_WIDGET (reg->window)->window,
523+ (gint)tap.focus_x,
524+ (gint)tap.focus_y))
525+ {
526+ binding->callback (binding->widget,
527+ GRIP_TIME_END,
528+ ((GripGestureEvent*)&tap),
529+ binding->data);
530+ }
531+ }
532 }
533 }
534 }
535@@ -730,7 +832,7 @@
536
537 static void
538 register_internal (GripGestureManager *manager,
539- GtkWindow *window,
540+ GtkWidget *widget,
541 GripGestureType gesture_type,
542 gint touch_points,
543 GripGestureCallback callback,
544@@ -740,12 +842,18 @@
545 GripGestureManagerPrivate *priv;
546 GripGestureRegistration *reg;
547 GripGestureBinding *binding;
548+ GtkWidget *toplevel;
549
550 g_return_if_fail (GRIP_IS_GESTURE_MANAGER (manager));
551+ g_return_if_fail (GTK_IS_WIDGET (widget));
552+
553+ toplevel = gtk_widget_get_toplevel (widget);
554+
555+ g_return_if_fail (GTK_IS_WINDOW (toplevel));
556
557 priv = manager->priv;
558
559- if (!(reg = g_hash_table_lookup (priv->hash, window)))
560+ if (!(reg = g_hash_table_lookup (priv->hash, toplevel)))
561 {
562 GeisInstance instance;
563 GIOChannel *iochannel;
564@@ -753,7 +861,7 @@
565 GeisXcbWinInfo xcb_win_info = {
566 .display_name = NULL,
567 .screenp = NULL,
568- .window_id = GDK_DRAWABLE_XID (GTK_WIDGET (window)->window)
569+ .window_id = GDK_DRAWABLE_XID (toplevel->window)
570 };
571 GeisWinInfo win_info = {
572 GEIS_XCB_FULL_WINDOW,
573@@ -783,10 +891,10 @@
574
575 reg = g_new0 (GripGestureRegistration, 1);
576
577- reg->window = window;
578+ reg->window = GTK_WINDOW (toplevel);
579 reg->instance = instance;
580
581- g_signal_connect (window,
582+ g_signal_connect (toplevel,
583 "destroy",
584 G_CALLBACK (window_destroyed_cb),
585 manager);
586@@ -810,6 +918,7 @@
587 binding = g_new0 (GripGestureBinding, 1);
588
589 binding->type = gesture_type;
590+ binding->widget = widget;
591 binding->touches = touch_points;
592 binding->callback = callback;
593 binding->data = user_data;
594@@ -818,11 +927,101 @@
595 reg->bindings = g_list_append (reg->bindings, binding);
596
597 g_hash_table_insert (priv->hash,
598- window,
599+ toplevel,
600 reg);
601 }
602
603 static void
604+toplevel_notify_cb (GtkWidget *widget,
605+ GParamSpec *pspec,
606+ gpointer user_data)
607+{
608+ if (pspec->name == g_intern_static_string ("parent"))
609+ {
610+ GtkWidget *toplevel = gtk_widget_get_toplevel (widget);
611+ GripRegistrationRequest *req = (GripRegistrationRequest *)user_data;
612+
613+ if (GTK_IS_WINDOW (toplevel))
614+ {
615+ g_signal_handlers_disconnect_by_func (widget,
616+ G_CALLBACK (toplevel_notify_cb),
617+ user_data);
618+
619+ if (gtk_widget_get_mapped (GTK_WIDGET (toplevel)))
620+ {
621+ register_internal (req->manager,
622+ req->widget,
623+ req->gesture_type,
624+ req->touch_points,
625+ req->callback,
626+ req->user_data,
627+ req->destroy);
628+
629+ g_free (req);
630+ }
631+ else
632+ {
633+ GripGestureManagerPrivate *priv = req->manager->priv;
634+
635+ priv->requests = g_list_append (priv->requests, req);
636+
637+ g_signal_connect (toplevel,
638+ "map-event",
639+ G_CALLBACK (window_mapped_cb),
640+ req->manager);
641+ }
642+ }
643+ else
644+ {
645+ g_signal_connect (G_OBJECT (toplevel),
646+ "notify",
647+ G_CALLBACK (toplevel_notify_cb),
648+ user_data);
649+ }
650+ }
651+}
652+
653+static void
654+register_widget (GripGestureManager *manager,
655+ GtkWidget *widget,
656+ GripGestureType gesture_type,
657+ gint touch_points,
658+ GripGestureCallback callback,
659+ gpointer user_data,
660+ GDestroyNotify destroy)
661+{
662+ GtkWidget *toplevel = gtk_widget_get_toplevel (widget);
663+
664+ if (GTK_IS_WINDOW (toplevel))
665+ {
666+ register_internal (manager,
667+ widget,
668+ gesture_type,
669+ touch_points,
670+ callback,
671+ user_data,
672+ destroy);
673+ }
674+ else
675+ {
676+ GripRegistrationRequest *req = g_new0 (GripRegistrationRequest, 1);
677+
678+ req->manager = manager;
679+ req->widget = widget;
680+ req->gesture_type = gesture_type;
681+ req->touch_points = touch_points;
682+ req->callback = callback;
683+ req->user_data = user_data;
684+ req->destroy = destroy;
685+
686+ g_signal_connect (toplevel,
687+ "notify",
688+ G_CALLBACK (toplevel_notify_cb),
689+ req);
690+ }
691+}
692+
693+static void
694 window_mapped_cb (GtkWidget *widget,
695 GdkEvent *event,
696 gpointer user_data)
697@@ -835,13 +1034,13 @@
698 {
699 GripRegistrationRequest *req = tmp->data;
700
701- register_internal (req->manager,
702- req->window,
703- req->gesture_type,
704- req->touch_points,
705- req->callback,
706- req->user_data,
707- req->destroy);
708+ register_widget (req->manager,
709+ req->widget,
710+ req->gesture_type,
711+ req->touch_points,
712+ req->callback,
713+ req->user_data,
714+ req->destroy);
715
716 g_free (req);
717 }
718@@ -871,44 +1070,68 @@
719 */
720 void
721 grip_gesture_manager_register_window (GripGestureManager *manager,
722- GtkWindow *window,
723+ GtkWidget *widget,
724 GripGestureType gesture_type,
725 gint touch_points,
726 GripGestureCallback callback,
727 gpointer user_data,
728 GDestroyNotify destroy)
729 {
730+ GtkWidget *toplevel;
731+
732 g_return_if_fail (GRIP_IS_GESTURE_MANAGER (manager));
733- g_return_if_fail (GTK_IS_WINDOW (window));
734-
735- if (gtk_widget_get_mapped (GTK_WIDGET (window)))
736+ g_return_if_fail (GTK_IS_WIDGET (widget));
737+
738+ toplevel = gtk_widget_get_toplevel (widget);
739+
740+ if (GTK_IS_WINDOW (toplevel))
741 {
742- register_internal (manager,
743- window,
744- gesture_type,
745- touch_points,
746- callback,
747- user_data,
748- destroy);
749+ if (gtk_widget_get_mapped (GTK_WIDGET (toplevel)))
750+ {
751+ register_internal (manager,
752+ widget,
753+ gesture_type,
754+ touch_points,
755+ callback,
756+ user_data,
757+ destroy);
758+ }
759+ else
760+ {
761+ GripRegistrationRequest *req = g_new0 (GripRegistrationRequest, 1);
762+ GripGestureManagerPrivate *priv = manager->priv;
763+
764+ req->manager = manager;
765+ req->widget = widget;
766+ req->gesture_type = gesture_type;
767+ req->touch_points = touch_points;
768+ req->callback = callback;
769+ req->user_data = user_data;
770+ req->destroy = destroy;
771+
772+ priv->requests = g_list_append (priv->requests, req);
773+
774+ g_signal_connect (toplevel,
775+ "map-event",
776+ G_CALLBACK (window_mapped_cb),
777+ manager);
778+ }
779 }
780 else
781 {
782 GripRegistrationRequest *req = g_new0 (GripRegistrationRequest, 1);
783- GripGestureManagerPrivate *priv = manager->priv;
784
785 req->manager = manager;
786- req->window = window;
787+ req->widget = widget;
788 req->gesture_type = gesture_type;
789 req->touch_points = touch_points;
790 req->callback = callback;
791 req->user_data = user_data;
792 req->destroy = destroy;
793
794- priv->requests = g_list_append (priv->requests, req);
795-
796- g_signal_connect (window,
797- "map-event",
798- G_CALLBACK (window_mapped_cb),
799- manager);
800+ g_signal_connect (toplevel,
801+ "notify",
802+ G_CALLBACK (toplevel_notify_cb),
803+ req);
804 }
805 }
806
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 guint fingers;
812
813 guint32 tap_time;
814+ gfloat focus_x;
815+ gfloat focus_y;
816 gfloat position_x;
817 gfloat position_y;
818 };
819@@ -159,7 +161,7 @@
820 GObjectClass parent_class;
821 };
822
823-typedef void (* GripGestureCallback) (GtkWindow *window,
824+typedef void (* GripGestureCallback) (GtkWidget *widget,
825 GripTimeType time,
826 GripGestureEvent *gesture,
827 gpointer user_data);
828@@ -167,12 +169,12 @@
829 GType grip_gesture_manager_get_type (void) G_GNUC_CONST;
830 GripGestureManager *grip_gesture_manager_get (void);
831 void grip_gesture_manager_register_window (GripGestureManager *manager,
832- GtkWindow *window,
833+ GtkWidget *widget,
834 GripGestureType gesture_type,
835- gint touch_points,
836+ gint touch_points,
837 GripGestureCallback callback,
838- gpointer user_data,
839- GDestroyNotify destroy);
840+ gpointer user_data,
841+ GDestroyNotify destroy);
842
843 G_END_DECLS
844

Subscribers

People subscribed via source and target branches