[clutter] input-device: don't reset a device's stage until all touch points are gone



commit d6a0f7eb6132f23201856bcc9bd850622c2fb4d1
Author: Lionel Landwerlin <llandwerlin gmail com>
Date:   Tue Aug 21 15:26:30 2012 +0100

    input-device: don't reset a device's stage until all touch points are gone
    
    803b3bafb617c2df703aa8b834ff0df2f0c5c26c introduced a new issue for
    multi touch events.
    
    In the case where 2 touch events for 2 different touch points are
    processed in the same iteration, a call to
    _clutter_stage_remove_device() when processing the first event will
    remove the stage setting of the InputDevice. That means Clutter will
    skip the second event, because it can't find a stage to which relate
    the event, so no related actor and so no emission.
    
    To fix this we move the _clutter_stage_(add/remove)_device() calls
    into the input device. This way the input device can find out exactly
    when to call these functions (i.e. when no touch point were previously
    active or when no touch point remain active).
    
    https://bugzilla.gnome.org/show_bug.cgi?id=682362

 clutter/clutter-device-manager-private.h |   11 ++--
 clutter/clutter-input-device.c           |   76 +++++++++++++++++-------------
 clutter/clutter-main.c                   |   10 +---
 clutter/clutter-stage.c                  |    2 +-
 clutter/x11/clutter-device-manager-xi2.c |    6 --
 5 files changed, 52 insertions(+), 53 deletions(-)
---
diff --git a/clutter/clutter-device-manager-private.h b/clutter/clutter-device-manager-private.h
index f503d4e..8bc5330 100644
--- a/clutter/clutter-device-manager-private.h
+++ b/clutter/clutter-device-manager-private.h
@@ -159,14 +159,15 @@ ClutterBackend *_clutter_device_manager_get_backend             (ClutterDeviceMa
 /* input device */
 gboolean        _clutter_input_device_has_sequence              (ClutterInputDevice   *device,
                                                                  ClutterEventSequence *sequence);
-void            _clutter_input_device_add_sequence              (ClutterInputDevice   *device,
-                                                                 ClutterEventSequence *sequence);
-void            _clutter_input_device_remove_sequence           (ClutterInputDevice   *device,
-                                                                 ClutterEventSequence *sequence);
+void            _clutter_input_device_add_event_sequence        (ClutterInputDevice   *device,
+                                                                 ClutterEvent         *event);
+void            _clutter_input_device_remove_event_sequence     (ClutterInputDevice   *device,
+                                                                 ClutterEvent         *event);
 void            _clutter_input_device_set_coords                (ClutterInputDevice   *device,
                                                                  ClutterEventSequence *sequence,
                                                                  gint                  x,
-                                                                 gint                  y);
+                                                                 gint                  y,
+                                                                 ClutterStage         *stage);
 void            _clutter_input_device_set_state                 (ClutterInputDevice   *device,
                                                                  ClutterModifierType   state);
 void            _clutter_input_device_set_time                  (ClutterInputDevice   *device,
diff --git a/clutter/clutter-input-device.c b/clutter/clutter-input-device.c
index 0917dad..868c2f2 100644
--- a/clutter/clutter-input-device.c
+++ b/clutter/clutter-input-device.c
@@ -394,6 +394,28 @@ clutter_input_device_init (ClutterInputDevice *self)
   self->inv_touch_sequence_actors = g_hash_table_new (NULL, NULL);
 }
 
+static ClutterTouchInfo *
+_clutter_input_device_ensure_touch_info (ClutterInputDevice *device,
+                                         ClutterEventSequence *sequence,
+                                         ClutterStage *stage)
+{
+  ClutterTouchInfo *info;
+
+  info = g_hash_table_lookup (device->touch_sequences_info, sequence);
+
+  if (info == NULL)
+    {
+      info = g_slice_new0 (ClutterTouchInfo);
+      info->sequence = sequence;
+      g_hash_table_insert (device->touch_sequences_info, sequence, info);
+
+      if (g_hash_table_size (device->touch_sequences_info) == 1)
+        _clutter_input_device_set_stage (device, stage);
+    }
+
+  return info;
+}
+
 /*< private >
  * clutter_input_device_set_coords:
  * @device: a #ClutterInputDevice
@@ -407,7 +429,8 @@ void
 _clutter_input_device_set_coords (ClutterInputDevice   *device,
                                   ClutterEventSequence *sequence,
                                   gint                  x,
-                                  gint                  y)
+                                  gint                  y,
+                                  ClutterStage         *stage)
 {
   g_return_if_fail (CLUTTER_IS_INPUT_DEVICE (device));
 
@@ -421,16 +444,8 @@ _clutter_input_device_set_coords (ClutterInputDevice   *device,
     }
   else
     {
-      ClutterTouchInfo *info =
-        g_hash_table_lookup (device->touch_sequences_info, sequence);
-
-      if (info == NULL)
-        {
-          info = g_slice_new0 (ClutterTouchInfo);
-          info->sequence = sequence;
-          g_hash_table_insert (device->touch_sequences_info, sequence, info);
-        }
-
+      ClutterTouchInfo *info;
+      info = _clutter_input_device_ensure_touch_info (device, sequence, stage);
       info->current_x = x;
       info->current_y = y;
     }
@@ -538,18 +553,12 @@ _clutter_input_device_associate_actor (ClutterInputDevice   *device,
     device->cursor_actor = actor;
   else
     {
-      ClutterTouchInfo *info =
-        g_hash_table_lookup (device->touch_sequences_info, sequence);
       GList *sequences =
         g_hash_table_lookup (device->inv_touch_sequence_actors, actor);
+      ClutterTouchInfo *info;
+      ClutterStage *stage = CLUTTER_STAGE (clutter_actor_get_stage (actor));
 
-      if (info == NULL)
-        {
-          info = g_new0 (ClutterTouchInfo, 1);
-          info->sequence = sequence;
-          g_hash_table_insert (device->touch_sequences_info, sequence, info);
-        }
-
+      info = _clutter_input_device_ensure_touch_info (device, sequence, stage);
       info->actor = actor;
 
       g_hash_table_insert (device->inv_touch_sequence_actors,
@@ -1073,7 +1082,7 @@ clutter_input_device_update_from_event (ClutterInputDevice *device,
   sequence = clutter_event_get_event_sequence (event);
   clutter_event_get_coords (event, &event_x, &event_y);
 
-  _clutter_input_device_set_coords (device, sequence, event_x, event_y);
+  _clutter_input_device_set_coords (device, sequence, event_x, event_y, event_stage);
   _clutter_input_device_set_state (device, event_state);
   _clutter_input_device_set_time (device, event_time);
 
@@ -1467,23 +1476,20 @@ _clutter_input_device_remove_slave (ClutterInputDevice *master,
  * actor underneath the touch point).
  */
 void
-_clutter_input_device_add_sequence (ClutterInputDevice   *device,
-                                    ClutterEventSequence *sequence)
+_clutter_input_device_add_event_sequence (ClutterInputDevice *device,
+                                          ClutterEvent       *event)
 {
-  ClutterTouchInfo *info;
+  ClutterEventSequence *sequence = clutter_event_get_event_sequence (event);
+  ClutterStage *stage;
 
   if (sequence == NULL)
     return;
 
-  info =
-    g_hash_table_lookup (device->touch_sequences_info, sequence);
-
-  if (info != NULL)
+  stage = clutter_event_get_stage (event);
+  if (stage == NULL)
     return;
 
-  info = g_new0 (ClutterTouchInfo, 1);
-  info->sequence = sequence;
-  g_hash_table_insert (device->touch_sequences_info, sequence, info);
+  _clutter_input_device_ensure_touch_info (device, sequence, stage);
 }
 
 /*< private >
@@ -1494,9 +1500,10 @@ _clutter_input_device_add_sequence (ClutterInputDevice   *device,
  * Stop tracking informations related to a touch point.
  */
 void
-_clutter_input_device_remove_sequence (ClutterInputDevice   *device,
-                                       ClutterEventSequence *sequence)
+_clutter_input_device_remove_event_sequence (ClutterInputDevice *device,
+                                             ClutterEvent       *event)
 {
+  ClutterEventSequence *sequence = clutter_event_get_event_sequence (event);
   ClutterTouchInfo *info =
     g_hash_table_lookup (device->touch_sequences_info, sequence);
 
@@ -1515,6 +1522,9 @@ _clutter_input_device_remove_sequence (ClutterInputDevice   *device,
     }
 
   g_hash_table_remove (device->touch_sequences_info, sequence);
+
+  if (g_hash_table_size (device->touch_sequences_info) == 0)
+    _clutter_input_device_set_stage (device, NULL);
 }
 
 /**
diff --git a/clutter/clutter-main.c b/clutter/clutter-main.c
index ed995d3..3701605 100644
--- a/clutter/clutter-main.c
+++ b/clutter/clutter-main.c
@@ -2678,10 +2678,7 @@ _clutter_process_event_details (ClutterActor        *stage,
             clutter_event_get_event_sequence (event);
 
           if (event->type == CLUTTER_TOUCH_BEGIN)
-            {
-              _clutter_input_device_set_stage (device, CLUTTER_STAGE (stage));
-              _clutter_input_device_add_sequence (device, sequence);
-            }
+            _clutter_input_device_add_event_sequence (device, event);
 
           clutter_event_get_coords (event, &x, &y);
 
@@ -2716,10 +2713,7 @@ _clutter_process_event_details (ClutterActor        *stage,
           emit_touch_event (event, device);
 
           if (event->type == CLUTTER_TOUCH_END)
-            {
-              _clutter_input_device_set_stage (device, NULL);
-              _clutter_input_device_remove_sequence (device, sequence);
-            }
+            _clutter_input_device_remove_event_sequence (device, event);
 
           break;
         }
diff --git a/clutter/clutter-stage.c b/clutter/clutter-stage.c
index f551de6..7862edf 100644
--- a/clutter/clutter-stage.c
+++ b/clutter/clutter-stage.c
@@ -946,7 +946,7 @@ _clutter_stage_queue_event (ClutterStage *stage,
 
       clutter_event_get_coords (event, &event_x, &event_y);
 
-      _clutter_input_device_set_coords (device, sequence, event_x, event_y);
+      _clutter_input_device_set_coords (device, sequence, event_x, event_y, stage);
       _clutter_input_device_set_state (device, event_state);
       _clutter_input_device_set_time (device, event_time);
     }
diff --git a/clutter/x11/clutter-device-manager-xi2.c b/clutter/x11/clutter-device-manager-xi2.c
index a714f8d..292ee76 100644
--- a/clutter/x11/clutter-device-manager-xi2.c
+++ b/clutter/x11/clutter-device-manager-xi2.c
@@ -1086,9 +1086,6 @@ clutter_device_manager_xi2_translate_event (ClutterEventTranslator *translator,
                                             stage_x11,
                                             &xev->valuators);
 
-        if (source_device != NULL && device->stage != NULL)
-          _clutter_input_device_set_stage (source_device, device->stage);
-
         if (xi_event->evtype == XI_TouchBegin)
           {
             event->touch.modifier_state |= CLUTTER_BUTTON1_MASK;
@@ -1139,9 +1136,6 @@ clutter_device_manager_xi2_translate_event (ClutterEventTranslator *translator,
                                             stage_x11,
                                             &xev->valuators);
 
-        if (source_device != NULL && device->stage != NULL)
-          _clutter_input_device_set_stage (source_device, device->stage);
-
         event->touch.modifier_state =
           _clutter_input_device_xi2_translate_state (&xev->mods,
                                                      &xev->buttons);



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]