summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonas Ådahl <jadahl@gmail.com>2016-09-07 17:38:33 +0800
committerJonas Ådahl <jadahl@gmail.com>2016-09-09 10:03:34 +0800
commitd893adb290c3740ae57b761d9e57a2f4d79e6c7b (patch)
tree993ce9219f66d2106b145595b384a90d2fdec16c
parent0c53677992bede8b785433148bb99ce6031adbad (diff)
downloadmutter-d893adb290c3740ae57b761d9e57a2f4d79e6c7b.tar.gz
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
-rw-r--r--clutter/clutter/clutter-device-manager-private.h4
-rw-r--r--clutter/clutter/clutter-device-manager.c17
-rw-r--r--clutter/clutter/clutter-device-manager.h5
-rw-r--r--clutter/clutter/clutter-stage.c10
-rw-r--r--clutter/clutter/evdev/clutter-device-manager-evdev.c26
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 7efe76857..108e8c5f4 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 c30bc8eef..f9222e765 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 da6bd2cb2..926d3b528 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 85cb343eb..1f0c3f8c0 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 4e52ecf80..b42b57665 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