summaryrefslogtreecommitdiff
path: root/clutter-gtk
diff options
context:
space:
mode:
authorEmmanuele Bassi <ebassi@linux.intel.com>2010-02-17 18:39:33 +0000
committerEmmanuele Bassi <ebassi@linux.intel.com>2010-02-17 18:39:33 +0000
commit649e233810ece62c97a01deaaba7caee2acc6499 (patch)
tree1919b0ec41ab89442e64ec8052d49fbdd8e8dd76 /clutter-gtk
parent60135af470f4285fd5e2c7ac21005048dc4f9d82 (diff)
downloadclutter-gtk-649e233810ece62c97a01deaaba7caee2acc6499.tar.gz
embed: Update input devices
The event handling in Clutter has been changed internally to always use input devices to store the state of the pointers and to emit ENTER/LEAVE event pairs consistently. This means that GtkClutterEmbed should be responsible of updating the state of the input devices, since we're completely overriding the event handling.
Diffstat (limited to 'clutter-gtk')
-rw-r--r--clutter-gtk/gtk-clutter-embed.c124
1 files changed, 100 insertions, 24 deletions
diff --git a/clutter-gtk/gtk-clutter-embed.c b/clutter-gtk/gtk-clutter-embed.c
index 6aec960..483ab75 100644
--- a/clutter-gtk/gtk-clutter-embed.c
+++ b/clutter-gtk/gtk-clutter-embed.c
@@ -193,13 +193,8 @@ gtk_clutter_embed_realize (GtkWidget *widget)
GdkVisual *visual;
GdkColormap *colormap;
-# if CLUTTER_CHECK_VERSION (1, 1, 5)
/* We need to use the colormap from the Clutter visual */
xvinfo = clutter_x11_get_visual_info ();
-# else
- xvinfo = clutter_x11_get_stage_visual (CLUTTER_STAGE (priv->stage));
-# endif
-
if (xvinfo == None)
{
g_critical ("Unable to retrieve the XVisualInfo from Clutter");
@@ -211,7 +206,7 @@ gtk_clutter_embed_realize (GtkWidget *widget)
colormap = gdk_colormap_new (visual, FALSE);
gtk_widget_set_colormap (widget, colormap);
}
-#endif
+#endif /* HAVE_CLUTTER_GTK_X11 */
GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);
@@ -328,29 +323,38 @@ gtk_clutter_embed_motion_notify_event (GtkWidget *widget,
GdkEventMotion *event)
{
GtkClutterEmbedPrivate *priv = GTK_CLUTTER_EMBED (widget)->priv;
+ ClutterDeviceManager *manager;
+ ClutterInputDevice *device;
ClutterEvent cevent = { 0, };
- cevent.type = CLUTTER_MOTION;
- cevent.any.stage = CLUTTER_STAGE (priv->stage);
+ manager = clutter_device_manager_get_default ();
+ device = clutter_device_manager_get_core_device (manager, CLUTTER_POINTER_DEVICE);
+
+ cevent.motion.type = CLUTTER_MOTION;
+ cevent.motion.stage = CLUTTER_STAGE (priv->stage);
cevent.motion.x = event->x;
cevent.motion.y = event->y;
cevent.motion.time = event->time;
cevent.motion.modifier_state = event->state;
+ cevent.motion.device = device;
+
+ clutter_input_device_update_from_event (device, &cevent, FALSE);
clutter_do_event (&cevent);
- /* doh - motion events can push ENTER/LEAVE events onto Clutters
- * internal event queue which we do really ever touch (essentially
- * proxying from gtks queue). The below pumps them back out and
- * processes.
- * *could* be side effects with below though doubful as no other
- * events reach the queue (we shut down event collection). Maybe
- * a peek_mask type call could be even safer.
- */
- while (clutter_events_pending())
+ /* XXX - motion events might synthesize ENTER/LEAVE event pairs
+ * and push them on the Clutter event queue for our stage; we need
+ * to pop them out of the queue.
+ *
+ * FIXME - instead of using the global "are there events pending"
+ * function we should have a clutter_stage_events_pending()
+ * accessor so that we can distinguish between stages.
+ */
+ while (clutter_events_pending ())
{
ClutterEvent *ev = clutter_event_get ();
- if (ev)
+
+ if (ev != NULL)
{
clutter_do_event (ev);
clutter_event_free (ev);
@@ -365,18 +369,23 @@ gtk_clutter_embed_button_event (GtkWidget *widget,
GdkEventButton *event)
{
GtkClutterEmbedPrivate *priv = GTK_CLUTTER_EMBED (widget)->priv;
+ ClutterDeviceManager *manager;
+ ClutterInputDevice *device;
ClutterEvent cevent = { 0, };
if (event->type == GDK_BUTTON_PRESS ||
event->type == GDK_2BUTTON_PRESS ||
event->type == GDK_3BUTTON_PRESS)
- cevent.type = cevent.button.type = CLUTTER_BUTTON_PRESS;
+ cevent.button.type = CLUTTER_BUTTON_PRESS;
else if (event->type == GDK_BUTTON_RELEASE)
- cevent.type = cevent.button.type = CLUTTER_BUTTON_RELEASE;
+ cevent.button.type = CLUTTER_BUTTON_RELEASE;
else
return FALSE;
- cevent.any.stage = CLUTTER_STAGE (priv->stage);
+ manager = clutter_device_manager_get_default ();
+ device = clutter_device_manager_get_core_device (manager, CLUTTER_POINTER_DEVICE);
+
+ cevent.button.stage = CLUTTER_STAGE (priv->stage);
cevent.button.x = event->x;
cevent.button.y = event->y;
cevent.button.time = event->time;
@@ -386,6 +395,9 @@ gtk_clutter_embed_button_event (GtkWidget *widget,
: 3));
cevent.button.modifier_state = event->state;
cevent.button.button = event->button;
+ cevent.button.device = device;
+
+ clutter_input_device_update_from_event (device, &cevent, FALSE);
clutter_do_event (&cevent);
@@ -397,21 +409,27 @@ gtk_clutter_embed_key_event (GtkWidget *widget,
GdkEventKey *event)
{
GtkClutterEmbedPrivate *priv = GTK_CLUTTER_EMBED (widget)->priv;
+ ClutterDeviceManager *manager;
+ ClutterInputDevice *device;
ClutterEvent cevent = { 0, };
if (event->type == GDK_KEY_PRESS)
- cevent.type = cevent.key.type = CLUTTER_KEY_PRESS;
+ cevent.key.type = CLUTTER_KEY_PRESS;
else if (event->type == GDK_KEY_RELEASE)
- cevent.type = cevent.key.type = CLUTTER_KEY_RELEASE;
+ cevent.key.type = CLUTTER_KEY_RELEASE;
else
return FALSE;
- cevent.any.stage = CLUTTER_STAGE (priv->stage);
+ manager = clutter_device_manager_get_default ();
+ device = clutter_device_manager_get_core_device (manager, CLUTTER_KEYBOARD_DEVICE);
+
+ cevent.key.stage = CLUTTER_STAGE (priv->stage);
cevent.key.time = event->time;
cevent.key.modifier_state = event->state;
cevent.key.keyval = event->keyval;
cevent.key.hardware_keycode = event->hardware_keycode;
cevent.key.unicode_value = gdk_keyval_to_unicode (event->keyval);
+ cevent.key.device = device;
clutter_do_event (&cevent);
@@ -512,6 +530,62 @@ gtk_clutter_embed_scroll_event (GtkWidget *widget,
return FALSE;
}
+static gboolean
+gtk_clutter_embed_enter_notify_event (GtkWidget *widget,
+ GdkEventCrossing *event)
+{
+ GtkClutterEmbedPrivate *priv = GTK_CLUTTER_EMBED (widget)->priv;
+ ClutterDeviceManager *manager;
+ ClutterInputDevice *device;
+ ClutterEvent cevent = { 0, };
+
+ manager = clutter_device_manager_get_default ();
+ device = clutter_device_manager_get_core_device (manager, CLUTTER_POINTER_DEVICE);
+
+ cevent.crossing.type = CLUTTER_ENTER;
+ cevent.crossing.stage = CLUTTER_STAGE (priv->stage);
+ cevent.crossing.x = (gint) event->x;
+ cevent.crossing.y = (gint) event->y;
+ cevent.crossing.time = event->time;
+ cevent.crossing.source = priv->stage;
+ cevent.crossing.related = NULL;
+ cevent.crossing.device = device;
+
+ clutter_input_device_update_from_event (device, &cevent, TRUE);
+
+ clutter_do_event (&cevent);
+
+ return FALSE;
+}
+
+static gboolean
+gtk_clutter_embed_leave_notify_event (GtkWidget *widget,
+ GdkEventCrossing *event)
+{
+ GtkClutterEmbedPrivate *priv = GTK_CLUTTER_EMBED (widget)->priv;
+ ClutterDeviceManager *manager;
+ ClutterInputDevice *device;
+ ClutterEvent cevent = { 0, };
+
+ manager = clutter_device_manager_get_default ();
+ device = clutter_device_manager_get_core_device (manager, CLUTTER_POINTER_DEVICE);
+
+ cevent.crossing.type = CLUTTER_LEAVE;
+ cevent.crossing.stage = CLUTTER_STAGE (priv->stage);
+ cevent.crossing.x = (gint) event->x;
+ cevent.crossing.y = (gint) event->y;
+ cevent.crossing.time = event->time;
+ cevent.crossing.source = priv->stage;
+ cevent.crossing.related = NULL;
+ cevent.crossing.device = device;
+
+ clutter_input_device_update_from_event (device, &cevent, TRUE);
+
+ clutter_do_event (&cevent);
+
+ return FALSE;
+}
+
static void
gtk_clutter_embed_style_set (GtkWidget *widget,
GtkStyle *old_style)
@@ -658,6 +732,8 @@ gtk_clutter_embed_class_init (GtkClutterEmbedClass *klass)
widget_class->focus_in_event = gtk_clutter_embed_focus_in;
widget_class->focus_out_event = gtk_clutter_embed_focus_out;
widget_class->scroll_event = gtk_clutter_embed_scroll_event;
+ widget_class->enter_notify_event = gtk_clutter_embed_enter_notify_event;
+ widget_class->leave_notify_event = gtk_clutter_embed_leave_notify_event;
container_class->add = gtk_clutter_embed_add;
container_class->remove = gtk_clutter_embed_remove;