[mutter] clutter: Update pointer position on master clock's update stage



commit 4b23eb064c9c3a87cf07c39593dcff5c27a23bbd
Author: Carlos Garnacho <carlosg gnome org>
Date:   Fri Nov 11 20:26:54 2016 +0100

    clutter: Update pointer position on master clock's update stage
    
    Ensure the pointer position is up-to-date for the pointers inside
    the clip area after the stage got actors relayout.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=755164

 clutter/clutter/clutter-stage.c |   67 +++++++++++++++++++++++++++++++++++++++
 1 files changed, 67 insertions(+), 0 deletions(-)
---
diff --git a/clutter/clutter/clutter-stage.c b/clutter/clutter/clutter-stage.c
index c07d039..a3ee001 100644
--- a/clutter/clutter/clutter-stage.c
+++ b/clutter/clutter/clutter-stage.c
@@ -161,6 +161,7 @@ struct _ClutterStagePrivate
   guint accept_focus           : 1;
   guint motion_events_enabled  : 1;
   guint has_custom_perspective : 1;
+  guint stage_was_relayout     : 1;
 };
 
 enum
@@ -1059,6 +1060,7 @@ _clutter_stage_maybe_relayout (ClutterActor *actor)
   if (!CLUTTER_ACTOR_IN_RELAYOUT (stage))
     {
       priv->relayout_pending = FALSE;
+      priv->stage_was_relayout = TRUE;
 
       CLUTTER_NOTE (ACTOR, "Recomputing layout");
 
@@ -1129,6 +1131,58 @@ clutter_stage_do_redraw (ClutterStage *stage)
                 stage);
 }
 
+static GSList *
+_clutter_stage_check_updated_pointers (ClutterStage *stage)
+{
+  ClutterStagePrivate *priv = stage->priv;
+  ClutterDeviceManager *device_manager;
+  GSList *updating = NULL;
+  const GSList *devices;
+  cairo_rectangle_int_t clip;
+  ClutterPoint point;
+  gboolean has_clip;
+
+  has_clip = _clutter_stage_window_get_redraw_clip_bounds (priv->impl, &clip);
+
+  device_manager = clutter_device_manager_get_default ();
+  devices = clutter_device_manager_peek_devices (device_manager);
+
+  for (; devices != NULL; devices = devices->next)
+    {
+      ClutterInputDevice *dev = devices->data;
+
+      if (clutter_input_device_get_device_mode (dev) !=
+          CLUTTER_INPUT_MODE_MASTER)
+        continue;
+
+      switch (clutter_input_device_get_device_type (dev))
+        {
+        case CLUTTER_POINTER_DEVICE:
+        case CLUTTER_TABLET_DEVICE:
+        case CLUTTER_PEN_DEVICE:
+        case CLUTTER_ERASER_DEVICE:
+        case CLUTTER_CURSOR_DEVICE:
+          if (!clutter_input_device_get_coords (dev, NULL, &point))
+            continue;
+
+          if (!has_clip ||
+              (point.x >= clip.x && point.x < clip.x + clip.width &&
+               point.y >= clip.y && point.y < clip.y + clip.height))
+            updating = g_slist_prepend (updating, dev);
+          break;
+        default:
+          /* Any other devices don't need checking, either because they
+           * don't have x/y coordinates, or because they're implicitly
+           * grabbed on an actor by default as it's the case of
+           * touch(screens).
+           */
+          break;
+        }
+    }
+
+  return updating;
+}
+
 /**
  * _clutter_stage_do_update:
  * @stage: A #ClutterStage
@@ -1141,6 +1195,10 @@ gboolean
 _clutter_stage_do_update (ClutterStage *stage)
 {
   ClutterStagePrivate *priv = stage->priv;
+  gboolean stage_was_relayout = priv->stage_was_relayout;
+  GSList *pointers = NULL;
+
+  priv->stage_was_relayout = FALSE;
 
   /* if the stage is being destroyed, or if the destruction already
    * happened and we don't have an StageWindow any more, then we
@@ -1161,6 +1219,9 @@ _clutter_stage_do_update (ClutterStage *stage)
   if (!priv->redraw_pending)
     return FALSE;
 
+  if (stage_was_relayout)
+    pointers = _clutter_stage_check_updated_pointers (stage);
+
   clutter_stage_maybe_finish_queue_redraws (stage);
 
   clutter_stage_do_redraw (stage);
@@ -1178,6 +1239,12 @@ _clutter_stage_do_update (ClutterStage *stage)
     }
 #endif /* CLUTTER_ENABLE_DEBUG */
 
+  while (pointers)
+    {
+      _clutter_input_device_update (pointers->data, NULL, TRUE);
+      pointers = g_slist_delete_link (pointers, pointers);
+    }
+
   return TRUE;
 }
 


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