[mutter] clutter: Add function to update input device actors to clutter-main



commit a9a9d27ead078c9720f0d9e7a3d6d5df78524236
Author: Jonas Dreßler <verdre v0yd nl>
Date:   Thu Oct 15 16:46:08 2020 +0200

    clutter: Add function to update input device actors to clutter-main
    
    We're moving keeping track of input devices and their associated actors
    out of ClutterInputDevice, this commit basically adds replacements for
    clutter_input_device_update() and clutter_input_device_set_actor() to
    clutter-main and shuffles the internals of those functions around a bit
    for clarity.
    
    clutter_stage_update_device() is made available in clutter-mutter.h
    because we need to update the actor of input devices not only from
    ClutterStage (when repicking after relayout), but also from
    MetaWaylandPointer (inside meta_wayland_pointer_repick()).
    
    Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1633>

 clutter/clutter/clutter-main.c   | 146 +++++++++++++++++++++++++++++++++++++++
 clutter/clutter/clutter-mutter.h |   9 +++
 2 files changed, 155 insertions(+)
---
diff --git a/clutter/clutter/clutter-main.c b/clutter/clutter/clutter-main.c
index f3475c696a..cd2e41c59a 100644
--- a/clutter/clutter/clutter-main.c
+++ b/clutter/clutter/clutter-main.c
@@ -65,6 +65,7 @@
 #include "clutter-paint-node-private.h"
 #include "clutter-private.h"
 #include "clutter-settings-private.h"
+#include "clutter-stage.h"
 #include "clutter-stage-manager.h"
 #include "clutter-stage-private.h"
 #include "clutter-backend-private.h"
@@ -1553,6 +1554,151 @@ clutter_do_event (ClutterEvent *event)
   _clutter_stage_queue_event (event->any.stage, event, TRUE);
 }
 
+static void
+create_crossing_event (ClutterStage         *stage,
+                       ClutterInputDevice   *device,
+                       ClutterEventSequence *sequence,
+                       ClutterEventType      event_type,
+                       ClutterActor         *source,
+                       ClutterActor         *related,
+                       graphene_point_t      coords,
+                       uint32_t              time)
+{
+  ClutterEvent *event;
+
+  event = clutter_event_new (event_type);
+  event->crossing.time = time;
+  event->crossing.flags = 0;
+  event->crossing.stage = stage;
+  event->crossing.source = source;
+  event->crossing.x = coords.x;
+  event->crossing.y = coords.y;
+  event->crossing.related = related;
+  event->crossing.sequence = sequence;
+  clutter_event_set_device (event, device);
+
+  /* we need to make sure that this event is processed
+   * before any other event we might have queued up until
+   * now, so we go on, and synthesize the event emission
+   * ourselves
+   */
+  _clutter_process_event (event);
+
+  clutter_event_free (event);
+}
+
+void
+clutter_stage_update_device (ClutterStage         *stage,
+                             ClutterInputDevice   *device,
+                             ClutterEventSequence *sequence,
+                             graphene_point_t      point,
+                             uint32_t              time,
+                             ClutterActor         *new_actor,
+                             gboolean              emit_crossing)
+{
+  ClutterInputDeviceType device_type;
+  ClutterActor *old_actor;
+  gboolean device_actor_changed;
+
+  device_type = clutter_input_device_get_device_type (device);
+
+  g_assert (device_type != CLUTTER_KEYBOARD_DEVICE &&
+            device_type != CLUTTER_PAD_DEVICE);
+
+  old_actor = clutter_stage_get_device_actor (stage, device, sequence);
+  device_actor_changed = new_actor != old_actor;
+
+  if (device_actor_changed)
+    {
+      CLUTTER_NOTE (EVENT,
+                    "Updating actor under cursor (device %s, at %.2f, %.2f): %s",
+                    clutter_input_device_get_device_name (device),
+                    point.x,
+                    point.y,
+                    _clutter_actor_get_debug_name (new_actor));
+
+      if (old_actor && emit_crossing)
+        {
+          create_crossing_event (stage,
+                                 device, sequence,
+                                 CLUTTER_LEAVE,
+                                 old_actor, new_actor,
+                                 point, time);
+        }
+    }
+
+  clutter_stage_update_device_entry (stage,
+                                     device, sequence,
+                                     point,
+                                     new_actor);
+
+  if (device_actor_changed)
+    {
+      if (new_actor && emit_crossing)
+        {
+          create_crossing_event (stage,
+                                 device, sequence,
+                                 CLUTTER_ENTER,
+                                 new_actor, old_actor,
+                                 point, time);
+        }
+    }
+}
+
+static ClutterActor *
+update_device_for_event (ClutterStage *stage,
+                         ClutterEvent *event,
+                         gboolean      emit_crossing)
+{
+  ClutterInputDevice *device = clutter_event_get_device (event);
+  ClutterEventSequence *sequence = clutter_event_get_event_sequence (event);
+  ClutterActor *new_actor;
+  graphene_point_t point;
+  uint32_t time;
+
+  clutter_event_get_coords (event, &point.x, &point.y);
+  time = clutter_event_get_time (event);
+
+  new_actor =
+    _clutter_stage_do_pick (stage, point.x, point.y, CLUTTER_PICK_REACTIVE);
+
+  /* Picking should never fail, but if it does, we bail out here */
+  g_return_val_if_fail (new_actor != NULL, NULL);
+
+  clutter_stage_update_device (stage,
+                               device, sequence,
+                               point,
+                               time,
+                               new_actor,
+                               emit_crossing);
+
+  return new_actor;
+}
+
+static void
+remove_device_for_event (ClutterStage *stage,
+                         ClutterEvent *event,
+                         gboolean      emit_crossing)
+{
+  ClutterInputDevice *device = clutter_event_get_device (event);
+  ClutterEventSequence *sequence = clutter_event_get_event_sequence (event);
+  graphene_point_t point;
+  uint32_t time;
+
+  clutter_event_get_coords (event, &point.x, &point.y);
+  time = clutter_event_get_time (event);
+
+  clutter_stage_update_device (stage,
+                               device, sequence,
+                               point,
+                               time,
+                               NULL,
+                               TRUE);
+
+  clutter_stage_remove_device_entry (stage, device, sequence);
+}
+
+
 static void
 _clutter_process_event_details (ClutterActor        *stage,
                                 ClutterMainContext  *context,
diff --git a/clutter/clutter/clutter-mutter.h b/clutter/clutter/clutter-mutter.h
index 6e1f439300..63b3fbf358 100644
--- a/clutter/clutter/clutter-mutter.h
+++ b/clutter/clutter/clutter-mutter.h
@@ -75,6 +75,15 @@ CLUTTER_EXPORT
 gboolean clutter_seat_handle_event_post (ClutterSeat        *seat,
                                          const ClutterEvent *event);
 
+CLUTTER_EXPORT
+void clutter_stage_update_device (ClutterStage         *stage,
+                                  ClutterInputDevice   *device,
+                                  ClutterEventSequence *sequence,
+                                  graphene_point_t      point,
+                                  uint32_t              time,
+                                  ClutterActor         *new_actor,
+                                  gboolean              emit_crossing);
+
 CLUTTER_EXPORT
 void clutter_stage_get_device_coords (ClutterStage         *stage,
                                       ClutterInputDevice   *device,


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