After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 778119 - Scale relative motion deltas with monitor scale
Scale relative motion deltas with monitor scale
Status: RESOLVED FIXED
Product: mutter
Classification: Core
Component: wayland
unspecified
Other All
: Normal normal
: ---
Assigned To: mutter-maint
mutter-maint
Depends on:
Blocks:
 
 
Reported: 2017-02-03 05:47 UTC by Jonas Ådahl
Modified: 2017-05-06 23:25 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
clutter: Add API for filtering relative motion events (6.87 KB, patch)
2017-02-03 05:47 UTC, Jonas Ådahl
committed Details | Review
clutter: Also filter relative tablet tool motions (1.89 KB, patch)
2017-02-03 05:47 UTC, Jonas Ådahl
committed Details | Review
backends/native: Scale relative input motions with monitor scale (2.76 KB, patch)
2017-02-03 05:47 UTC, Jonas Ådahl
none Details | Review
backends/native: Scale relative input motions with monitor scale (2.45 KB, patch)
2017-03-24 14:55 UTC, Carlos Garnacho
none Details | Review
backends: Refactor MetaScreenDirection guessing into separate function (4.97 KB, patch)
2017-03-24 14:55 UTC, Carlos Garnacho
committed Details | Review
backends: Add meta_logical_monitor_get_relative_direction() function (2.26 KB, patch)
2017-03-24 14:55 UTC, Carlos Garnacho
none Details | Review
backends/native: Apply per-output scales when moving across outputs (4.39 KB, patch)
2017-03-24 14:55 UTC, Carlos Garnacho
none Details | Review
backends/native: Scale relative input motions with monitor scale (2.36 KB, patch)
2017-03-24 21:14 UTC, Carlos Garnacho
committed Details | Review
backends/native: Apply per-output scales when moving across outputs (5.17 KB, patch)
2017-03-24 21:16 UTC, Carlos Garnacho
committed Details | Review

Description Jonas Ådahl 2017-02-03 05:47:45 UTC
Scale the relative pointer and tablet tool in relative mode with the monitor
scale, to make the same physical motion travel the same distance over a
properly scaled GUI.
Comment 1 Jonas Ådahl 2017-02-03 05:47:48 UTC
Created attachment 344832 [details] [review]
clutter: Add API for filtering relative motion events

Add an API that allows the owner of the clutter context to alter the
relative motion events (so far relative pointer events).
Comment 2 Jonas Ådahl 2017-02-03 05:47:54 UTC
Created attachment 344833 [details] [review]
clutter: Also filter relative tablet tool motions

Pass the relative motion from tablet tools through the same filter
mechanism as used for the relative pointer motions.
Comment 3 Jonas Ådahl 2017-02-03 05:47:59 UTC
Created attachment 344834 [details] [review]
backends/native: Scale relative input motions with monitor scale

To allow for more natural pointer movements from relative pointer
devices (e.g. mouse, touchpad, tablet tool in relative mode, etc), scale
the relative motion from libinput with the scale of the monitor. In
effect, this means that the pointer movement is twice as fast (physical
movement vs numbers of pixels passed) as before, but it also means that
the same physical movement crosses the distance in a GUI no matter if
it is on a HiDPI monitor or not.
Comment 4 Rui Matos 2017-02-03 14:26:55 UTC
Review of attachment 344834 [details] [review]:

::: src/backends/native/meta-backend-native.c
@@ +260,3 @@
+    meta_backend_get_monitor_manager (backend);
+  int monitor;
+  MetaMonitorInfo *monitor_info;

this should be converted to MetaLogicalMonitor

@@ +287,3 @@
   clutter_evdev_set_pointer_constrain_callback (manager, pointer_constrain_callback,
                                                 NULL, NULL);
+  clutter_evdev_set_relative_motion_filter (manager, relative_motion_filter, NULL);

might as well make use of the user_data argument and pass in the MetaMonitorManager instance. same for the existing constrain callback really
Comment 5 Rui Matos 2017-02-03 14:30:54 UTC
Review of attachment 344834 [details] [review]:

::: src/backends/native/meta-backend-native.c
@@ +249,3 @@
+static void
+relative_motion_filter (ClutterInputDevice *device,
+                        guint32             time,

the time argument is unused, maybe it shouldn't be in the API?
Comment 6 Jonas Ådahl 2017-02-20 02:47:57 UTC
(In reply to Rui Matos from comment #4)
> Review of attachment 344834 [details] [review] [review]:
> 
> ::: src/backends/native/meta-backend-native.c
> @@ +260,3 @@
> +    meta_backend_get_monitor_manager (backend);
> +  int monitor;
> +  MetaMonitorInfo *monitor_info;
> 
> this should be converted to MetaLogicalMonitor

This is for the gnome-3-22 branch, but maybe we shouldn't mess with gnome-3.22.

> 
> @@ +287,3 @@
>    clutter_evdev_set_pointer_constrain_callback (manager,
> pointer_constrain_callback,
>                                                  NULL, NULL);
> +  clutter_evdev_set_relative_motion_filter (manager,
> relative_motion_filter, NULL);
> 
> might as well make use of the user_data argument and pass in the
> MetaMonitorManager instance. same for the existing constrain callback really
Comment 7 Carlos Garnacho 2017-03-14 18:11:30 UTC
Review of attachment 344832 [details] [review]:

Looks correct. I however wonder, couldn't this be put together with the pointer constrain function? I mean, both are about taking some coordinates and maybe transforming those into something else.

Both this and pointer constraints should probably also apply to tablets configured as relative.
Comment 8 Carlos Garnacho 2017-03-14 18:16:03 UTC
Review of attachment 344834 [details] [review]:

Besides the s/MetaMonitorInfo/MetaLogicalMonitor/ stuff (why didn't these patches target master btw?), I think we need to bisect motion in the case it crosses monitors, and apply the corresponding scale*distance for each of those. Otherwise quick pointer motions come across as too fast or too slow depending on the monitor they're crossing into.
Comment 9 Carlos Garnacho 2017-03-14 18:17:16 UTC
Given I have the hw to test this, do you mind me continuing on these patches?
Comment 10 Jonas Ådahl 2017-03-15 02:28:12 UTC
(In reply to Carlos Garnacho from comment #7)
> Review of attachment 344832 [details] [review] [review]:
> 
> Looks correct. I however wonder, couldn't this be put together with the
> pointer constrain function? I mean, both are about taking some coordinates
> and maybe transforming those into something else.
> 
> Both this and pointer constraints should probably also apply to tablets
> configured as relative.

We constrain both absolute and relative pointer events, but we can only filter a dx/dy for relative ones.

(In reply to Carlos Garnacho from comment #8)
> Review of attachment 344834 [details] [review] [review]:
> 
> Besides the s/MetaMonitorInfo/MetaLogicalMonitor/ stuff (why didn't these
> patches target master btw?),

I did the same patch both on top of s/MetaMonitorInfo/MetaLogicalMonitor and not, and choose the one people could test more easily (the reason this came up was because of libinput pointer acceleration having issue on hidpi, and that it would be good with something like this to test)

> I think we need to bisect motion in the case it
> crosses monitors, and apply the corresponding scale*distance for each of
> those. Otherwise quick pointer motions come across as too fast or too slow
> depending on the monitor they're crossing into.

True.

(In reply to Carlos Garnacho from comment #9)
> Given I have the hw to test this, do you mind me continuing on these patches?

I don't mind, go ahead! I pushed a rebased master branch version of the above patches to https://github.com/jadahl/mutter/commits/wip/dpi-scale-motion
Comment 11 Carlos Garnacho 2017-03-24 14:55:23 UTC
Created attachment 348650 [details] [review]
backends/native: Scale relative input motions with monitor scale

To allow for more natural pointer movements from relative pointer
devices (e.g. mouse, touchpad, tablet tool in relative mode, etc), scale
the relative motion from libinput with the scale of the monitor. In
effect, this means that the pointer movement is twice as fast (physical
movement vs numbers of pixels passed) as before, but it also means that
the same physical movement crosses the distance in a GUI no matter if
it is on a HiDPI monitor or not.
Comment 12 Carlos Garnacho 2017-03-24 14:55:31 UTC
Created attachment 348651 [details] [review]
backends: Refactor MetaScreenDirection guessing into separate function

Make it a helper MetaLogicalMonitor API, and use it on the
MetaMonitorManager.
Comment 13 Carlos Garnacho 2017-03-24 14:55:39 UTC
Created attachment 348652 [details] [review]
backends: Add meta_logical_monitor_get_relative_direction() function

This function tries all directions between two given logical monitors
and returns TRUE (plus the direction) if they are arranged together, or
returns FALSE if they are not.
Comment 14 Carlos Garnacho 2017-03-24 14:55:48 UTC
Created attachment 348653 [details] [review]
backends/native: Apply per-output scales when moving across outputs

Quick motions can come across as too fast (or slow) if it crosses outputs
with different scales. If this happens, check both source/dest logical
monitors and try to apply the relative distance * scale that applies to
each of them.
Comment 15 Jonas Ådahl 2017-03-24 15:48:34 UTC
Review of attachment 348653 [details] [review]:

Did you ever consider using the line intersection vector math method used by pointer barriers and pointer confinements? They do pretty much the same thing (find borders of rectangles and cut vectors) except they cut the motion vector off instead of scaling it.

It'd work more or less by finding the target logical monitor, calculate the length of the vector within the target and scale it accordingly, and do the same with the source logical monitor.

That is if the motion doesn't travel through more than one logical monitor (e.g. crosses the corner of one in a three triple head configuration). Using the vector math solution here would be trivial; it'd just mean calculate the length of the vector within every logical monitor and scale accordingly.

See meta_line2_intersects_with() in meta-border.c.
Comment 16 Jonas Ådahl 2017-03-24 15:54:42 UTC
Review of attachment 348650 [details] [review]:

::: src/backends/native/meta-backend-native.c
@@ +294,3 @@
   clutter_evdev_set_pointer_constrain_callback (manager, pointer_constrain_callback,
                                                 NULL, NULL);
+  clutter_evdev_set_relative_motion_filter (manager, relative_motion_filter, NULL);

I think Rui's comment was valid here; i.e. pass manager as user_data here.
Comment 17 Carlos Garnacho 2017-03-24 16:12:54 UTC
(In reply to Jonas Ådahl from comment #15)
> Review of attachment 348653 [details] [review] [review]:
> 
> Did you ever consider using the line intersection vector math method used by
> pointer barriers and pointer confinements? They do pretty much the same
> thing (find borders of rectangles and cut vectors) except they cut the
> motion vector off instead of scaling it.

Nah, math is fun :P.

> 
> It'd work more or less by finding the target logical monitor, calculate the
> length of the vector within the target and scale it accordingly, and do the
> same with the source logical monitor.
> 
> That is if the motion doesn't travel through more than one logical monitor
> (e.g. crosses the corner of one in a three triple head configuration). Using
> the vector math solution here would be trivial; it'd just mean calculate the
> length of the vector within every logical monitor and scale accordingly.

Right, I didn't think of L-shaped setups.

> 
> See meta_line2_intersects_with() in meta-border.c.

Yup, indeed seems I can use that.

(In reply to Jonas Ådahl from comment #16)
> Review of attachment 348650 [details] [review] [review]:
> 
> ::: src/backends/native/meta-backend-native.c
> @@ +294,3 @@
>    clutter_evdev_set_pointer_constrain_callback (manager,
> pointer_constrain_callback,
>                                                  NULL, NULL);
> +  clutter_evdev_set_relative_motion_filter (manager,
> relative_motion_filter, NULL);
> 
> I think Rui's comment was valid here; i.e. pass manager as user_data here.

Oops, right, forgot to locally fix that one.
Comment 18 Carlos Garnacho 2017-03-24 21:14:30 UTC
Created attachment 348674 [details] [review]
backends/native: Scale relative input motions with monitor scale

To allow for more natural pointer movements from relative pointer
devices (e.g. mouse, touchpad, tablet tool in relative mode, etc), scale
the relative motion from libinput with the scale of the monitor. In
effect, this means that the pointer movement is twice as fast (physical
movement vs numbers of pixels passed) as before, but it also means that
the same physical movement crosses the distance in a GUI no matter if
it is on a HiDPI monitor or not.
Comment 19 Carlos Garnacho 2017-03-24 21:16:02 UTC
Created attachment 348675 [details] [review]
backends/native: Apply per-output scales when moving across outputs

Quick motions can come across as too fast (or slow) if it crosses outputs
with different scales. If this happens, check both source/dest logical
monitors and try to apply the relative distance * scale that applies to
each of them.
Comment 20 Carlos Garnacho 2017-03-24 21:24:41 UTC
(In reply to Carlos Garnacho from comment #12)
> Created attachment 348651 [details] [review] [review]
> backends: Refactor MetaScreenDirection guessing into separate function
> 
> Make it a helper MetaLogicalMonitor API, and use it on the
> MetaMonitorManager.

This one is not strictly needed anymore, still makes some sense as a minor refactor IMHO.

(In reply to Rui Matos from comment #5)
> Review of attachment 344834 [details] [review] [review]:
> 
> ::: src/backends/native/meta-backend-native.c
> @@ +249,3 @@
> +static void
> +relative_motion_filter (ClutterInputDevice *device,
> +                        guint32             time,
> 
> the time argument is unused, maybe it shouldn't be in the API?

I also did this locally fwiw, not much of a big change, so I'm not resubmitting the first two patches.
Comment 21 Jonas Ådahl 2017-03-27 07:52:53 UTC
Review of attachment 348651 [details] [review]:

Name suggestion (I couldn't understand what "has direction" means): meta_logical_monitor_is_neighbour()/is_adjecent_to()
Comment 22 Jonas Ådahl 2017-03-27 07:53:38 UTC
Review of attachment 348674 [details] [review]:

Looks good to me.
Comment 23 Jonas Ådahl 2017-03-27 08:19:18 UTC
Review of attachment 348675 [details] [review]:

::: src/backends/native/meta-backend-native.c
@@ +277,3 @@
+      motion = (MetaLine2) {{ x, y },
+                            { x + (dx * cur->scale),
+                              y + (dy * cur->scale) }};

Quite unimportant, but the "style" of defining the lines etc differ from elsewhere.

@@ +309,3 @@
+      dy -= intersection.y - motion.a.y;
+      x = intersection.x + ((dx > 0) ? 1 : -1);
+      y = intersection.y + ((dy > 0) ? 1 : -1);

This looks a bit odd, and I think it might create odd mini "jumps" when moving slowly across two monitors.

I guess what you are doing here is avoid re-intersecting at the same place next time, but can't you just do this by setting the new x/y to intersection.x/y +/- FLOAT_EPSILON? I dealt with a similar thing clamp_to_border() and used something similar, except that it had to not be rounded away as a wl_fixed_t.
Comment 24 Carlos Garnacho 2017-03-27 10:50:07 UTC
(In reply to Jonas Ådahl from comment #21)
> Review of attachment 348651 [details] [review] [review]:
> 
> Name suggestion (I couldn't understand what "has direction" means):
> meta_logical_monitor_is_neighbour()/is_adjecent_to()

I like the first, used the american spelling though (which seems already used in api).

(In reply to Jonas Ådahl from comment #23)
> Review of attachment 348675 [details] [review] [review]:
> 
> ::: src/backends/native/meta-backend-native.c
> @@ +277,3 @@
> +      motion = (MetaLine2) {{ x, y },
> +                            { x + (dx * cur->scale),
> +                              y + (dy * cur->scale) }};
> 
> Quite unimportant, but the "style" of defining the lines etc differ from
> elsewhere.

Fixed

> 
> @@ +309,3 @@
> +      dy -= intersection.y - motion.a.y;
> +      x = intersection.x + ((dx > 0) ? 1 : -1);
> +      y = intersection.y + ((dy > 0) ? 1 : -1);
> 
> This looks a bit odd, and I think it might create odd mini "jumps" when
> moving slowly across two monitors.
> 
> I guess what you are doing here is avoid re-intersecting at the same place
> next time, but can't you just do this by setting the new x/y to
> intersection.x/y +/- FLOAT_EPSILON? I dealt with a similar thing
> clamp_to_border() and used something similar, except that it had to not be
> rounded away as a wl_fixed_t.

seems off by more than that... I made it check the last direction, and avoid checking intersections on the border it just came from, so I can just set the intersection coordinates as the new motion starting point.
Comment 25 Carlos Garnacho 2017-03-27 11:03:49 UTC
Pushed after having fixed all review comments.

Attachment 344832 [details] pushed as 8f691c2 - clutter: Add API for filtering relative motion events
Attachment 344833 [details] pushed as df45c50 - clutter: Also filter relative tablet tool motions
Attachment 348651 [details] pushed as efae039 - backends: Refactor MetaScreenDirection guessing into separate function
Attachment 348674 [details] pushed as e60dfd5 - backends/native: Scale relative input motions with monitor scale
Attachment 348675 [details] pushed as 420311b - backends/native: Apply per-output scales when moving across outputs
Comment 26 Adam Williamson 2017-03-30 13:43:42 UTC
Would it be possible to backport this to the 3.22 branch and cut a release, so we can get it in Fedora 25? It seems like a bit too large of a change to just carry as a downstream patch...thanks!
Comment 27 Kanishk Dudeja 2017-04-18 13:56:41 UTC
Is this functionality available in Gnome 3.24?

If not, how can I get it in Gnome 3.24?
Comment 28 Jonas Ådahl 2017-04-18 14:00:04 UTC
(In reply to Kanishk Dudeja from comment #27)
> Is this functionality available in Gnome 3.24?
> 
> If not, how can I get it in Gnome 3.24?

It was included in mutter 3.24.1.
Comment 29 Kanishk Dudeja 2017-04-18 14:10:23 UTC
Thanks for the reply Jonas :).
Comment 30 Kanishk Dudeja 2017-05-06 18:50:37 UTC
I just installed Ubuntu Gnome 17.04 and upgraded to Gnome 3.24.1 with Mutter 3.24.1. This doesn't look to have changed anything.

Can anything help on checking the following things:

1) In the Wayland session, how do i check if the libinput driver is being used or if the synaptics driver is being used?

2) In the X session, how do i check if the libinput driver is being used or if the synaptics driver is being used?
Comment 31 Peter Hutterer 2017-05-06 23:25:00 UTC
Wayland always uses libinput, synaptics is an xorg-only driver and cannot be used in a wayland compositor. Easiest way to check under X is to run xinput list-props "device name" and check the prefix for the driver property names.