+2007-11-15 Øyvind Kolås <pippin@o-hand.com>
+
+ * clutter/clutter-main.[ch]: added clutter_grab_keyboard,
+ clutter_ungrab_keyboard and clutter_get_keyboard_grab, in
+ clutter_do_event deliver keyboard related events only to the
+ actor with the keyboard grab if a grab exists.
+ * clutter/clutter-private.h: added keyboard_grab_actor to context.
+ * tests/test-grab.c: added testing for testing the keyboard grab.
+
2007-11-15 Emmanuele Bassi <ebassi@openedhand.com>
* clutter/clutter-texture.c:
clutter_actor_event (context->pointer_grab_actor, event, FALSE);
return;
}
-
deliver_event (event);
break;
case CLUTTER_DESTROY_NOTIFY:
g_return_if_fail (actor != NULL);
+ if (context->keyboard_grab_actor != NULL)
+ {
+ clutter_actor_event (context->keyboard_grab_actor, event, FALSE);
+ return;
+ }
deliver_event (event);
}
break;
event, FALSE);
return;
}
-
deliver_event (event);
}
break;
return context->pointer_grab_actor;
}
+
+
+static void
+on_keyboard_grab_weak_notify (gpointer data,
+ GObject *where_the_object_was)
+{
+ ClutterMainContext *context;
+
+ context = clutter_context_get_default ();
+ context->keyboard_grab_actor = NULL;
+
+ clutter_ungrab_keyboard ();
+}
+
+/**
+ * clutter_grab_keyboard:
+ * @actor: a #ClutterActor
+ *
+ * Grabs keyboard events, after the grab is done keyboard events ("key-press-event"
+ * and "key-release-event") are delivered to this actor directly. The source
+ * set in the event will be the actor that would have received the event if the
+ * keyboard grab was not in effect.
+ *
+ * Since: 0.6
+ */
+void
+clutter_grab_keyboard (ClutterActor *actor)
+{
+ ClutterMainContext *context;
+
+ g_return_if_fail (actor == NULL || CLUTTER_IS_ACTOR (actor));
+
+ context = clutter_context_get_default ();
+
+ if (context->keyboard_grab_actor == actor)
+ return;
+
+ if (context->keyboard_grab_actor)
+ {
+ g_object_weak_unref (G_OBJECT (context->keyboard_grab_actor),
+ on_keyboard_grab_weak_notify,
+ NULL);
+ context->keyboard_grab_actor = NULL;
+ }
+
+ if (actor)
+ {
+ context->keyboard_grab_actor = actor;
+
+ g_object_weak_ref (G_OBJECT (actor),
+ on_keyboard_grab_weak_notify,
+ NULL);
+ }
+}
+
+/**
+ * clutter_ungrab_keyboard:
+ *
+ * Removes an existing grab of the keyboard.
+ *
+ * Since: 0.6
+ */
+void
+clutter_ungrab_keyboard (void)
+{
+ clutter_grab_keyboard (NULL);
+}
+
+/**
+ * clutter_get_keyboard_grab:
+ *
+ * Queries the current keyboard grab of clutter.
+ *
+ * Return value: the actor currently holding the keyboard grab, or NULL if there is no grab.
+ *
+ * Since: 0.6
+ */
+ClutterActor *
+clutter_get_keyboard_grab (void)
+{
+ ClutterMainContext *context;
+ context = clutter_context_get_default ();
+
+ return context->keyboard_grab_actor;
+}
void clutter_ungrab_pointer (void);
ClutterActor * clutter_get_pointer_grab (void);
+void clutter_grab_keyboard (ClutterActor *actor);
+void clutter_ungrab_keyboard (void);
+ClutterActor * clutter_get_keyboard_grab (void);
+
G_END_DECLS
#endif /* _HAVE_CLUTTER_MAIN_H */
ClutterActor *pointer_grab_actor; /* The actor having the pointer grab
(or NULL if there is no pointer grab)
*/
+ ClutterActor *keyboard_grab_actor; /* The actor having the pointer grab
+ (or NULL if there is no pointer grab)
+ */
};
#define CLUTTER_CONTEXT() (clutter_context_get_default ())
break;
case CLUTTER_BUTTON_RELEASE:
printf("[%s] BUTTON RELEASE", source);
- if (clutter_event_get_source (event) == CLUTTER_ACTOR (stage))
- clutter_stage_set_key_focus (stage, NULL);
- else if (clutter_event_get_source (event) == actor)
- clutter_stage_set_key_focus (stage, actor);
break;
case CLUTTER_SCROLL:
printf("[%s] BUTTON SCROLL", source);
return FALSE;
}
+static gboolean
+cyan_press_cb (ClutterActor *actor,
+ ClutterEvent *event,
+ gpointer data)
+{
+ if (clutter_get_keyboard_grab () != NULL)
+ clutter_ungrab_keyboard ();
+ else
+ clutter_grab_keyboard (actor);
+ return FALSE;
+}
+
+
int
main (int argc, char *argv[])
ClutterColor rcol = { 0xff, 0, 0, 0xff},
bcol = { 0, 0, 0xff, 0xff },
gcol = { 0, 0xff, 0, 0xff },
+ ccol = { 0, 0xff, 0xff, 0xff },
ycol = { 0xff, 0xff, 0, 0xff },
ncol = { 0, 0, 0, 0xff };
g_print ("Blue box: aquire grab on press, destroys the blue box actor on release\n");
g_print ("Yellow box: aquire grab on press, releases grab on next press on yellow box\n");
g_print ("Green box: toggle per actor motion events.\n\n");
+ g_print ("Cyan box: toggle grab (from cyan box) for keyboard events.\n\n");
stage = clutter_stage_get_default ();
g_signal_connect (stage, "event", G_CALLBACK (debug_event_cb), "stage");
g_signal_connect (actor, "button-press-event",
G_CALLBACK (green_press_cb), NULL);
+
+ actor = clutter_rectangle_new_with_color (&ccol);
+ clutter_actor_set_size (actor, 100, 100);
+ clutter_actor_set_position (actor, 500, 100);
+ clutter_actor_set_reactive (actor);
+ clutter_container_add (CLUTTER_CONTAINER (stage), actor, NULL);
+ g_signal_connect (actor, "event",
+ G_CALLBACK (debug_event_cb), "cyan box");
+ g_signal_connect (actor, "button-press-event",
+ G_CALLBACK (cyan_press_cb), NULL);
+
clutter_actor_show_all (CLUTTER_ACTOR (stage));
clutter_main();