From bc08ad2fbbc127762b275c1db72ddd36b1fee8b4 Mon Sep 17 00:00:00 2001 From: Daniel van Vugt Date: Tue, 6 Aug 2019 19:04:51 +0800 Subject: [PATCH 1/2] clutter/device-manager-evdev: Update device modifiers before queuing Until now we would: 1. Enqueue modifier key event on the stage. 2. Update device modifier state. 3. Dequeue and process modifier key event with NEW device modifier state. But if we consider optimizing out the queuing in some cases then there will become a problem: 1. Process modifier key event with OLD device modifier state. 2. Update device modifier state. To correct the above we now do: 1. Update device modifier state. 2. Queue/process modifier key event with NEW device modifier state. It appears commit dd940a71 which introduced the old behaviour was correct in the need to update the device modifier state, but is at least no longer correct (if it ever was) that it should be done after queuing the event. If queuing is working, as it is right now, then it makes no difference whether the device modifier state is updated before or after. Because both cases will come before the dequeing and processing. https://gitlab.gnome.org/GNOME/mutter/merge_requests/711 --- clutter/clutter/evdev/clutter-device-manager-evdev.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/clutter/clutter/evdev/clutter-device-manager-evdev.c b/clutter/clutter/evdev/clutter-device-manager-evdev.c index 84b0aad490a..dc8d4fb0543 100644 --- a/clutter/clutter/evdev/clutter-device-manager-evdev.c +++ b/clutter/clutter/evdev/clutter-device-manager-evdev.c @@ -701,14 +701,14 @@ clutter_event_dispatch (GSource *g_source, if (!_clutter_input_device_get_stage (input_device)) goto out; - /* forward the event into clutter for emission etc. */ - _clutter_stage_queue_event (event->any.stage, event, FALSE); - - /* update the device states *after* the event */ + /* update the device states *before* the event */ event_state = seat->button_state | xkb_state_serialize_mods (seat->xkb, XKB_STATE_MODS_EFFECTIVE); _clutter_input_device_set_state (seat->core_pointer, event_state); _clutter_input_device_set_state (seat->core_keyboard, event_state); + + /* forward the event into clutter for emission etc. */ + _clutter_stage_queue_event (event->any.stage, event, FALSE); } out: -- GitLab From 5c617ac2864a7e040dd3646fbef9f5cd9c5fb788 Mon Sep 17 00:00:00 2001 From: Daniel van Vugt Date: Fri, 2 Aug 2019 19:30:31 +0800 Subject: [PATCH 2/2] clutter/stage: Only queue compressible events Incompressible events already pass through unmodified, so queuing them just wasted time and memory. We would however like to keep the ordering of events so we can only apply this optimization if the queue is empty. This reduces the input latency of incompressible events like touchpad scrolling or drawing tablets by up to one frame. It also means the same series of events now arrives at the client more smoothly and not in bursts. https://gitlab.gnome.org/GNOME/mutter/merge_requests/711 --- clutter/clutter/clutter-stage.c | 31 ++++++++++++++++++++++--------- 1 file changed, 22 insertions(+), 9 deletions(-) diff --git a/clutter/clutter/clutter-stage.c b/clutter/clutter/clutter-stage.c index 107da475d5c..eece2450b0f 100644 --- a/clutter/clutter/clutter-stage.c +++ b/clutter/clutter/clutter-stage.c @@ -875,15 +875,6 @@ _clutter_stage_queue_event (ClutterStage *stage, if (copy_event) event = clutter_event_copy (event); - g_queue_push_tail (priv->event_queue, event); - - if (first_event) - { - ClutterMasterClock *master_clock = _clutter_master_clock_get_default (); - _clutter_master_clock_start_running (master_clock); - _clutter_stage_schedule_update (stage); - } - /* if needed, update the state of the input device of the event. * we do it here to avoid calling the same code from every backend * event processing function @@ -904,6 +895,28 @@ _clutter_stage_queue_event (ClutterStage *stage, _clutter_input_device_set_state (device, event_state); _clutter_input_device_set_time (device, event_time); } + + if (first_event) + { + gboolean compressible = event->type == CLUTTER_MOTION || + event->type == CLUTTER_TOUCH_UPDATE; + + if (!compressible) + { + _clutter_process_event (event); + clutter_event_free (event); + return; + } + } + + g_queue_push_tail (priv->event_queue, event); + + if (first_event) + { + ClutterMasterClock *master_clock = _clutter_master_clock_get_default (); + _clutter_master_clock_start_running (master_clock); + _clutter_stage_schedule_update (stage); + } } gboolean -- GitLab