[mutter/wip/carlosg/unthrottled-wayland: 1/2] WIP: clutter: Move event filter handling to happen before throttling




commit 5b083a853ba3227423f93efe7cd713aa1f48d1f0
Author: Carlos Garnacho <carlosg gnome org>
Date:   Tue Oct 27 19:43:50 2020 +0100

    WIP: clutter: Move event filter handling to happen before throttling
    
    As event handling goes:
    1) Events get generated and queued by the seat (from another thread in
       native, in the same thread in X11)
    2) The MetaBackend gets those events and forwards them to Clutter
       via clutter_do_event()
    3) The events get queued in the ClutterStage
    4) At the time of processing a frame, the input events are processed,
    5) Motion events are throttled, only the last is effectively handled
    6) Events are filtered, wayland and WM handling happens here
    7) Events maybe reach to clutter
    
    This commit moves 6 to happen between 2 and 3. The end result is that:
    
    - Throttling only applies to Clutter event handling, The wayland event
      forwarding bits will handle the event stream as soon as it comes, as
      timely as possible.
    - WM event handling is also unthrottled, but that's more of a side
      effect.
    - This all still happens on the main thread, so there's the possibility
      that other busy areas (e.g. relayout) temporarily block this event
      forwarding.
    - Sending events unthrottled inherently means more CPU, probably
      dependent on input devices' frequency. The impact is not measured.
    
    This should bring the best of both worlds with e.g. 1000Hz mice, wayland
    clients get unthrottled events, while GNOME Shell UI still behaves like
    it used to do.

 clutter/clutter/clutter-main.c | 65 +++++++++++++++++++++++-------------------
 1 file changed, 36 insertions(+), 29 deletions(-)
---
diff --git a/clutter/clutter/clutter-main.c b/clutter/clutter/clutter-main.c
index 3b48f12d11..0373240be2 100644
--- a/clutter/clutter/clutter-main.c
+++ b/clutter/clutter/clutter-main.c
@@ -1424,9 +1424,6 @@ static inline void
 emit_pointer_event (ClutterEvent       *event,
                     ClutterInputDevice *device)
 {
-  if (_clutter_event_process_filters (event))
-    return;
-
   if (device != NULL && device->pointer_grab_actor != NULL)
     clutter_actor_event (device->pointer_grab_actor, event, FALSE);
   else
@@ -1440,9 +1437,6 @@ emit_crossing_event (ClutterEvent       *event,
   ClutterEventSequence *sequence = clutter_event_get_event_sequence (event);
   ClutterActor *grab_actor = NULL;
 
-  if (_clutter_event_process_filters (event))
-    return;
-
   if (sequence)
     {
       if (device->sequence_grab_actors != NULL)
@@ -1466,9 +1460,6 @@ emit_touch_event (ClutterEvent       *event,
 {
   ClutterActor *grab_actor = NULL;
 
-  if (_clutter_event_process_filters (event))
-    return;
-
   if (device->sequence_grab_actors != NULL)
     {
       grab_actor = g_hash_table_lookup (device->sequence_grab_actors,
@@ -1491,9 +1482,6 @@ static inline void
 emit_keyboard_event (ClutterEvent       *event,
                      ClutterInputDevice *device)
 {
-  if (_clutter_event_process_filters (event))
-    return;
-
   if (device != NULL && device->keyboard_grab_actor != NULL)
     clutter_actor_event (device->keyboard_grab_actor, event, FALSE);
   else
@@ -1547,6 +1535,10 @@ is_off_stage (ClutterActor *stage,
 void
 clutter_do_event (ClutterEvent *event)
 {
+  ClutterEventSequence *sequence;
+  ClutterInputDevice *device;
+  ClutterActor *actor;
+
   /* we need the stage for the event */
   if (event->any.stage == NULL)
     {
@@ -1558,6 +1550,37 @@ clutter_do_event (ClutterEvent *event)
   if (CLUTTER_ACTOR_IN_DESTRUCTION (event->any.stage))
     return;
 
+  device = clutter_event_get_device (event);
+  sequence = clutter_event_get_event_sequence (event);
+
+  if (device)
+    {
+      if (event->any.type == CLUTTER_ENTER ||
+          event->any.type == CLUTTER_MOTION ||
+          event->any.type == CLUTTER_TOUCH_BEGIN ||
+          event->any.type == CLUTTER_TOUCH_UPDATE)
+        {
+          device = clutter_event_get_device (event);
+          sequence = clutter_event_get_event_sequence (event);
+          actor = clutter_input_device_update (device, sequence,
+                                               event->any.stage,
+                                               TRUE, event);
+          clutter_event_set_source (event, actor);
+        }
+      else if (event->any.type != CLUTTER_KEY_PRESS &&
+               event->any.type != CLUTTER_KEY_RELEASE)
+        {
+          actor = clutter_input_device_get_actor (device, sequence);
+          clutter_event_set_source (event, actor);
+        }
+    }
+
+  if (_clutter_event_process_filters (event))
+    return;
+
+  /* FIXME: clutter stage event handling gets confused without this ATM */
+  clutter_event_set_source (event, NULL);
+
   /* Instead of processing events when received, we queue them up to
    * handle per-frame before animations, layout, and drawing.
    *
@@ -1671,9 +1694,6 @@ _clutter_process_event_details (ClutterActor        *stage,
       case CLUTTER_DESTROY_NOTIFY:
         event->any.source = stage;
 
-        if (_clutter_event_process_filters (event))
-          break;
-
         /* the stage did not handle the event, so we just quit */
         clutter_stage_event (CLUTTER_STAGE (stage), event);
         break;
@@ -1697,9 +1717,6 @@ _clutter_process_event_details (ClutterActor        *stage,
             /* Only stage gets motion events */
             event->any.source = stage;
 
-            if (_clutter_event_process_filters (event))
-              break;
-
             if (device != NULL && device->pointer_grab_actor != NULL)
               {
                 clutter_actor_event (device->pointer_grab_actor,
@@ -1818,9 +1835,6 @@ _clutter_process_event_details (ClutterActor        *stage,
             /* Only stage gets motion events */
             event->any.source = stage;
 
-            if (_clutter_event_process_filters (event))
-              break;
-
             /* global grabs */
             if (device->sequence_grab_actors != NULL)
               {
@@ -1914,9 +1928,6 @@ _clutter_process_event_details (ClutterActor        *stage,
 
       case CLUTTER_PROXIMITY_IN:
       case CLUTTER_PROXIMITY_OUT:
-        if (_clutter_event_process_filters (event))
-          break;
-
         if (!clutter_actor_event (stage, event, TRUE))
           {
             /* and bubbling phase */
@@ -1928,8 +1939,7 @@ _clutter_process_event_details (ClutterActor        *stage,
       case CLUTTER_STAGE_STATE:
         /* focus - forward to stage */
         event->any.source = stage;
-        if (!_clutter_event_process_filters (event))
-          clutter_stage_event (CLUTTER_STAGE (stage), event);
+        clutter_stage_event (CLUTTER_STAGE (stage), event);
         break;
 
       case CLUTTER_CLIENT_MESSAGE:
@@ -1937,9 +1947,6 @@ _clutter_process_event_details (ClutterActor        *stage,
 
       case CLUTTER_DEVICE_ADDED:
       case CLUTTER_DEVICE_REMOVED:
-        _clutter_event_process_filters (event);
-        break;
-
       case CLUTTER_EVENT_LAST:
         break;
     }


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