[mutter] clutter: Compress instead of discard motion events



commit d893adb290c3740ae57b761d9e57a2f4d79e6c7b
Author: Jonas Ådahl <jadahl gmail com>
Date:   Wed Sep 7 17:38:33 2016 +0800

    clutter: Compress instead of discard motion events
    
    Clutter discards any motion event if next event happens to also be a
    motion event. This is problematic when the motion event carries
    relative motion deltas, since the information about them is completely
    lost.
    
    Until we have moved away made the stage stop discarding motion events,
    lets work around the issue by compressing them, effectively adding
    multiple relative motion deltas together, would one be discarded.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=771049

 clutter/clutter/clutter-device-manager-private.h   |    4 +++
 clutter/clutter/clutter-device-manager.c           |   17 +++++++++++++
 clutter/clutter/clutter-device-manager.h           |    5 +++-
 clutter/clutter/clutter-stage.c                    |   10 +++++++
 .../clutter/evdev/clutter-device-manager-evdev.c   |   26 ++++++++++++++++++++
 5 files changed, 61 insertions(+), 1 deletions(-)
---
diff --git a/clutter/clutter/clutter-device-manager-private.h 
b/clutter/clutter/clutter-device-manager-private.h
index 7efe768..108e8c5 100644
--- a/clutter/clutter/clutter-device-manager-private.h
+++ b/clutter/clutter/clutter-device-manager-private.h
@@ -188,6 +188,10 @@ void            _clutter_device_manager_select_stage_events     (ClutterDeviceMa
                                                                  ClutterStage         *stage);
 ClutterBackend *_clutter_device_manager_get_backend             (ClutterDeviceManager *device_manager);
 
+void            _clutter_device_manager_compress_motion         (ClutterDeviceManager *device_manger,
+                                                                 ClutterEvent         *event,
+                                                                 const ClutterEvent   *to_discard);
+
 /* input device */
 gboolean        _clutter_input_device_has_sequence              (ClutterInputDevice   *device,
                                                                  ClutterEventSequence *sequence);
diff --git a/clutter/clutter/clutter-device-manager.c b/clutter/clutter/clutter-device-manager.c
index c30bc8e..f9222e7 100644
--- a/clutter/clutter/clutter-device-manager.c
+++ b/clutter/clutter/clutter-device-manager.c
@@ -458,3 +458,20 @@ clutter_device_manager_create_virtual_device (ClutterDeviceManager   *device_man
   return manager_class->create_virtual_device (device_manager,
                                                device_type);
 }
+
+void
+_clutter_device_manager_compress_motion (ClutterDeviceManager *device_manager,
+                                         ClutterEvent         *event,
+                                         const ClutterEvent   *to_discard)
+{
+  ClutterDeviceManagerClass *manager_class;
+
+  g_return_if_fail (CLUTTER_IS_DEVICE_MANAGER (device_manager));
+
+
+  manager_class = CLUTTER_DEVICE_MANAGER_GET_CLASS (device_manager);
+  if (!manager_class->compress_motion)
+    return;
+
+  manager_class->compress_motion (device_manager, event, to_discard);
+}
diff --git a/clutter/clutter/clutter-device-manager.h b/clutter/clutter/clutter-device-manager.h
index da6bd2c..926d3b5 100644
--- a/clutter/clutter/clutter-device-manager.h
+++ b/clutter/clutter/clutter-device-manager.h
@@ -85,9 +85,12 @@ struct _ClutterDeviceManagerClass
                                                ClutterStage       *stage);
   ClutterVirtualInputDevice *(* create_virtual_device) (ClutterDeviceManager  *manager,
                                                         ClutterInputDeviceType device_type);
+  void                (* compress_motion) (ClutterDeviceManager *device_manger,
+                                           ClutterEvent         *event,
+                                           const ClutterEvent   *to_discard);
 
   /* padding */
-  gpointer _padding[7];
+  gpointer _padding[6];
 };
 
 CLUTTER_AVAILABLE_IN_1_2
diff --git a/clutter/clutter/clutter-stage.c b/clutter/clutter/clutter-stage.c
index 85cb343..1f0c3f8 100644
--- a/clutter/clutter/clutter-stage.c
+++ b/clutter/clutter/clutter-stage.c
@@ -998,6 +998,16 @@ _clutter_stage_process_queued_events (ClutterStage *stage)
                             "Omitting motion event at %d, %d",
                             (int) event->motion.x,
                             (int) event->motion.y);
+
+              if (next_event->type == CLUTTER_MOTION)
+                {
+                  ClutterDeviceManager *device_manager =
+                    clutter_device_manager_get_default ();
+
+                  _clutter_device_manager_compress_motion (device_manager,
+                                                           next_event, event);
+                }
+
               goto next_event;
             }
           else if (event->type == CLUTTER_TOUCH_UPDATE &&
diff --git a/clutter/clutter/evdev/clutter-device-manager-evdev.c 
b/clutter/clutter/evdev/clutter-device-manager-evdev.c
index 4e52ecf..b42b576 100644
--- a/clutter/clutter/evdev/clutter-device-manager-evdev.c
+++ b/clutter/clutter/evdev/clutter-device-manager-evdev.c
@@ -1970,6 +1970,31 @@ clutter_device_manager_evdev_create_virtual_device (ClutterDeviceManager  *manag
                        NULL);
 }
 
+static void
+clutter_device_manager_evdev_compress_motion (ClutterDeviceManager *device_manger,
+                                              ClutterEvent         *event,
+                                              const ClutterEvent   *to_discard)
+{
+  double dx, dy;
+  double dx_unaccel, dy_unaccel;
+  double dst_dx = 0.0, dst_dy = 0.0;
+  double dst_dx_unaccel = 0.0, dst_dy_unaccel = 0.0;
+
+  if (!clutter_evdev_event_get_relative_motion (to_discard,
+                                                &dx, &dy,
+                                                &dx_unaccel, &dy_unaccel))
+    return;
+
+  clutter_evdev_event_get_relative_motion (event,
+                                           &dst_dx, &dst_dy,
+                                           &dst_dx_unaccel, &dst_dy_unaccel);
+  _clutter_evdev_event_set_relative_motion (event,
+                                            dx + dst_dx,
+                                            dy + dst_dy,
+                                            dx_unaccel + dst_dx_unaccel,
+                                            dy_unaccel + dst_dy_unaccel);
+}
+
 /*
  * GObject implementation
  */
@@ -2110,6 +2135,7 @@ clutter_device_manager_evdev_class_init (ClutterDeviceManagerEvdevClass *klass)
   manager_class->get_core_device = clutter_device_manager_evdev_get_core_device;
   manager_class->get_device = clutter_device_manager_evdev_get_device;
   manager_class->create_virtual_device = clutter_device_manager_evdev_create_virtual_device;
+  manager_class->compress_motion = clutter_device_manager_evdev_compress_motion;
 }
 
 static void


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