Mir

Merge lp:~andreas-pokorny/mir/add-option-to-disable-acceleration into lp:mir

Proposed by Andreas Pokorny
Status: Merged
Approved by: Daniel van Vugt
Approved revision: no longer in the source branch.
Merged at revision: 3256
Proposed branch: lp:~andreas-pokorny/mir/add-option-to-disable-acceleration
Merge into: lp:mir
Prerequisite: lp:~andreas-pokorny/mir/bump-platform-to-5
Diff against target: 454 lines (+118/-45)
11 files modified
examples/server_example_input_device_config.cpp (+30/-11)
examples/server_example_input_device_config.h (+2/-8)
include/client/mir_toolkit/mir_input_device.h (+15/-0)
include/platform/mir/input/pointer_settings.h (+4/-0)
include/server/mir/input/pointer_configuration.h (+10/-4)
src/platforms/evdev/libinput_device.cpp (+16/-9)
src/server/input/default_device.cpp (+4/-2)
tests/include/mir/test/doubles/mock_libinput.h (+2/-0)
tests/mir_test_doubles/mock_libinput.cpp (+12/-0)
tests/mir_test_framework/fake_input_device_impl.cpp (+7/-4)
tests/unit-tests/input/evdev/test_libinput_device.cpp (+16/-7)
To merge this branch: bzr merge lp:~andreas-pokorny/mir/add-option-to-disable-acceleration
Reviewer Review Type Date Requested Status
PS Jenkins bot (community) continuous-integration Approve
Daniel van Vugt Approve
Mir CI Bot continuous-integration Approve
Kevin DuBois (community) Approve
Review via email: mp+280593@code.launchpad.net

This proposal supersedes a proposal from 2015-12-14.

Commit message

add an option to select pointer acceleration profile

Allow the selection of one out of three porfiles: diabled, flat, adaptive. The last one is adaptive to the poimter movement, and our previous default behavior.

Description of the change

This MP adds a configuration option to select the cursor acceleration profile for pointing devices. Libinput offers three profiles including one that disables acceleration. Flat and disabled are now also simulated by the fake input devices.

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal

PASSED: Continuous integration, rev:3192
http://jenkins.qa.ubuntu.com/job/mir-ci/5847/
Executed test runs:
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-android-vivid-i386-build/5309
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-clang-vivid-amd64-build/4215
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-mediumtests-vivid-touch/5258
    FAILURE: http://jenkins.qa.ubuntu.com/job/mir-mediumtests-xenial-touch/157/console
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-xenial-amd64-ci/175
        deb: http://jenkins.qa.ubuntu.com/job/mir-xenial-amd64-ci/175/artifact/work/output/*zip*/output.zip
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-xenial-i386-ci/175
        deb: http://jenkins.qa.ubuntu.com/job/mir-xenial-i386-ci/175/artifact/work/output/*zip*/output.zip
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-mediumtests-builder-vivid-armhf/5258
        deb: http://jenkins.qa.ubuntu.com/job/mir-mediumtests-builder-vivid-armhf/5258/artifact/work/output/*zip*/output.zip
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-mediumtests-runner-touch/7778
    SUCCESS: http://s-jenkins.ubuntu-ci:8080/job/touch-flash-device/26049
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-mediumtests-builder-xenial-armhf/155
        deb: http://jenkins.qa.ubuntu.com/job/mir-mediumtests-builder-xenial-armhf/155/artifact/work/output/*zip*/output.zip
    FAILURE: http://jenkins.qa.ubuntu.com/job/mir-mediumtests-runner-xenial-touch/14/console
    SUCCESS: http://s-jenkins.ubuntu-ci:8080/job/touch-flash-device/26052

Click here to trigger a rebuild:
http://s-jenkins.ubuntu-ci:8080/job/mir-ci/5847/rebuild

review: Approve (continuous-integration)
Revision history for this message
Daniel van Vugt (vanvugt) wrote : Posted in a previous version of this proposal

Thanks for putting the time into this. I suspect this is slightly the wrong approach though:

+ bool enable_cursor_acceleration{true};

would be better replaced by an enum that matches enum libinput_config_accel_profile:

http://wayland.freedesktop.org/libinput/doc/latest/libinput_8h.html#ad63796972347f318b180e322e35cee79

So we could set it as LIBINPUT_CONFIG_ACCEL_PROFILE_NONE (or FLAT or ADAPTIVE) instead of enable_cursor_acceleration=false.

review: Needs Fixing
Revision history for this message
Daniel van Vugt (vanvugt) wrote : Posted in a previous version of this proposal

And therefore we would end up calling libinput_device_config_accel_set_profile:
http://wayland.freedesktop.org/libinput/doc/latest/group__config.html#ga6e72a6214840d76c8a43d3753c1d549d

Revision history for this message
Andreas Pokorny (andreas-pokorny) wrote : Posted in a previous version of this proposal

Agreed. I guess that would turn that into a more permanent solution.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Andreas Pokorny (andreas-pokorny) wrote :

^ needs a newer libinput.. will land with 0.18...

Revision history for this message
Daniel van Vugt (vanvugt) wrote :

Looking good except:

(1) Dead code needs removing: bool enable_cursor_acceleration{true};

(2) I wonder if we can use more concise and accurate naming than libinput does?...

  MirPointerAccelerationProfile --> MirPointerAcceleration
  mir_pointer_acceleration_profile_none --> mir_pointer_acceleration_none
  mir_pointer_acceleration_profile_flat --> mir_pointer_acceleration_constant (is that accurate?)
  mir_pointer_acceleration_profile_adaptive --> mir_pointer_acceleration_adaptive

review: Needs Fixing
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Daniel van Vugt (vanvugt) wrote :

"acceleration" is already a noun so we don't need to call it "acceleration_profile". Drop the "profile" methinks.

Asking people to remember how to spell acceleration is bad enough without adding extra words :)

Revision history for this message
Andreas Pokorny (andreas-pokorny) wrote :

@duflu: in both the enum and commandline option?

Revision history for this message
Andreas Pokorny (andreas-pokorny) wrote :

I think in both cases we could leave the profile out..

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :

PASSED: Continuous integration, rev:3196
http://jenkins.qa.ubuntu.com/job/mir-ci/5900/
Executed test runs:
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-android-vivid-i386-build/5389
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-clang-vivid-amd64-build/4296
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-mediumtests-vivid-touch/5342
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-mediumtests-xenial-touch/218
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-xenial-amd64-ci/226
        deb: http://jenkins.qa.ubuntu.com/job/mir-xenial-amd64-ci/226/artifact/work/output/*zip*/output.zip
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-xenial-i386-ci/226
        deb: http://jenkins.qa.ubuntu.com/job/mir-xenial-i386-ci/226/artifact/work/output/*zip*/output.zip
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-mediumtests-builder-vivid-armhf/5339
        deb: http://jenkins.qa.ubuntu.com/job/mir-mediumtests-builder-vivid-armhf/5339/artifact/work/output/*zip*/output.zip
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-mediumtests-runner-touch/7847
    SUCCESS: http://s-jenkins.ubuntu-ci:8080/job/touch-flash-device/26275
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-mediumtests-builder-xenial-armhf/214
        deb: http://jenkins.qa.ubuntu.com/job/mir-mediumtests-builder-xenial-armhf/214/artifact/work/output/*zip*/output.zip
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-mediumtests-runner-xenial-touch/71
    SUCCESS: http://s-jenkins.ubuntu-ci:8080/job/touch-flash-device/26276

Click here to trigger a rebuild:
http://s-jenkins.ubuntu-ci:8080/job/mir-ci/5900/rebuild

review: Approve (continuous-integration)
Revision history for this message
Daniel van Vugt (vanvugt) wrote :

Oh, we need to check and verify that the libinput API is not misusing the word "acceleration" like others do. If they are using the word acceleration accurately, then curiously there is no option to change the pointer speed without also accelerating.

We need to check the libinput source and make sure their terminology is correct before we do the same.

review: Needs Information
Revision history for this message
Daniel van Vugt (vanvugt) wrote :

Looking at the libinput code and docs, it gives conflicting answers as to what "flat acceleration" means. In the code it kind of looks like "flat acceleration" means "zero acceleration with constant velocity multiplier".

Please check my findings but I think this means LIBINPUT_CONFIG_ACCEL_PROFILE_FLAT is incorrectly named and perhaps in most profiles there is zero acceleration in the physical sense. So more accurate names would be:

  MirPointerAcceleration -> MirPointerSpeed
  mir_pointer_acceleration_none -> mir_pointer_speed_native
  mir_pointer_acceleration_constant -> mir_pointer_speed_constant (with bias 0 same as native?)
  mir_pointer_acceleration_adaptive -> mir_pointer_speed_accelerated

Sorry to be pedantic, but it's libinput that has apparently confused the physics terminology. We should try not to copy their mistakes, if they are mistakes...

review: Needs Fixing
Revision history for this message
Andreas Pokorny (andreas-pokorny) wrote :

profile flat means that the way the relative movement is interpreted is 'constant' - independent of the current velocity of mouse - or better independent of the most recent measured pointer deltas.

So hmm I think speed_native is ok-ish but mir_pointer_speed_constant seems wrong - since the speed of the cursor will not be constant in that case. And since we used the term acceleration in the other enumeration already I would rather stay in that level of derivative. Or we change both... but what is going on is harder to describe in velocity terms.

Revision history for this message
Daniel van Vugt (vanvugt) wrote :

Looking at the libinput source, I *think* LIBINPUT_CONFIG_ACCEL_PROFILE_FLAT means a constant multiple (which is configurable) of the velocity of the mouse. So constant multiple of velocity means acceleration introduced by the input stack is always exactly zero. As such, I think it's misleading to call that "acceleration_constant". It's actually a constant speed (when moving at all) with an acceleration of precisely zero, I think.

I'd be inclined to fix up the terminology for Mir rather than copy the common misnomer. But I'd also like more people to review the libinput source and check my assertion is correct.

Revision history for this message
Andreas Pokorny (andreas-pokorny) wrote :

Ok I see your point. Still speed_constant seems not right. From the users perspective the setting will change the velocity of the movement. So the user will observe an acceleration.

Revision history for this message
Daniel van Vugt (vanvugt) wrote :

Yes, the user will always observe instantaneous acceleration when velocity changes from zero to non-zero. However pointer acceleration is not about that first event, it's about the second and subsequent events. In the second and subsequent motion events your acceleration is precisely zero if your velocity is constant/flat. So a constant velocity or flat mode should not have "acceleration" in its name.

That all said, a constant velocity multiplier of anything other that one is arguably useless. Less than one and a lot of code will never move the cursor. More than one and you lose pixel accuracy on screen. I guess that's why the libinput code limits the multiplier for flat mode to 2.

Revision history for this message
Daniel van Vugt (vanvugt) wrote :

(1) Naming needs clarification per above.

Manual testing results:

(2) Surprisingly --mouse-acceleration=none does not fix bug 1528109 but --mouse-acceleration=constant does. Have we misinterpreted the "none" mode? Should it be removed in favour of constant mode with no bias?

(3) The --mouse-acceleration option is missing from some servers (mir_proving_server) so still not helpful to me. I guess it or something like it needs to be promoted up into libmirserver default config at some point.

Revision history for this message
Andreas Pokorny (andreas-pokorny) wrote :

> (1) Naming needs clarification per above.
>
> Manual testing results:
>
> (2) Surprisingly --mouse-acceleration=none does not fix bug 1528109 but
> --mouse-acceleration=constant does. Have we misinterpreted the "none" mode?
> Should it be removed in favour of constant mode with no bias?

ok will investigate that..

>
> (3) The --mouse-acceleration option is missing from some servers
> (mir_proving_server) so still not helpful to me. I guess it or something like
> it needs to be promoted up into libmirserver default config at some point.

Yeah we should do that. Hmm it would be nicer if we could make the configuration device specific.. The current unique ids are not good enough for that.. thats another story that needs fixing..

Revision history for this message
Kevin DuBois (kdub) wrote :

+ settings.handedness = left_handed? mir_pointer_handedness_left : mir_pointer_handedness_right;
nit: spacing

lgtm, pending fixing the issues Daniel brought up

Revision history for this message
Mir CI Bot (mir-ci-bot) wrote :

PASSED: Continuous integration, rev:3196
https://mir-jenkins.ubuntu.com/job/mir-ci/17/
Executed test runs:
    None: https://mir-jenkins.ubuntu.com/job/generic-update-mp/17/console

Click here to trigger a rebuild:
https://mir-jenkins.ubuntu.com/job/mir-ci/17/rebuild

review: Approve (continuous-integration)
Revision history for this message
Kevin DuBois (kdub) wrote :

> lgtm, pending fixing the issues Daniel brought up
suppose I'll "pre-approve"

review: Approve
Revision history for this message
Andreas Pokorny (andreas-pokorny) wrote :

Yes this is a bug in libinput. It does not handle the NONE case yet so it falls through to either adaptive high-dpi or low-dpi acceleration.

Revision history for this message
Andreas Pokorny (andreas-pokorny) wrote :

So it seems none was only intended to indicate that there is no acceleraton filter available. We could remap our enum value to flat and 'speed' zero, or document how to acchieve an unaccelerated setting. I would prefer the second option since it would avoid mapping errors when the current status is read back, and we have to interpret a float value.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Daniel van Vugt (vanvugt) wrote :

(1) constant mode means zero acceleration, so the enum should not have "acceleration" in its name. I'm just trying to be physically accurate. I think we need to either remove the word "acceleration" from the enum or rename "mir_pointer_acceleration_constant" to "mir_pointer_acceleration_none".

(2) Nit: Please try to keep code within 80 columns.

(3) Nit: Unwanted blank line and s/separates/separated/

154 + * function based on the current velocity that usually consists of a two linear
155 + *
156 + * inclines separates by a plateau.

review: Needs Fixing
Revision history for this message
Mir CI Bot (mir-ci-bot) wrote :

FAILED: Continuous integration, rev:3202
https://mir-jenkins.ubuntu.com/job/mir-ci/80/
Executed test runs:
    None: https://mir-jenkins.ubuntu.com/job/generic-update-mp/80/console

Click here to trigger a rebuild:
https://mir-jenkins.ubuntu.com/job/mir-ci/80/rebuild

review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :

PASSED: Continuous integration, rev:3202
http://jenkins.qa.ubuntu.com/job/mir-ci/6054/
Executed test runs:
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-android-vivid-i386-build/5585
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-clang-vivid-amd64-build/4492
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-mediumtests-vivid-touch/5541
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-mediumtests-xenial-touch/296
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-xenial-amd64-ci/378
        deb: http://jenkins.qa.ubuntu.com/job/mir-xenial-amd64-ci/378/artifact/work/output/*zip*/output.zip
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-xenial-i386-ci/378
        deb: http://jenkins.qa.ubuntu.com/job/mir-xenial-i386-ci/378/artifact/work/output/*zip*/output.zip
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-mediumtests-builder-vivid-armhf/5538
        deb: http://jenkins.qa.ubuntu.com/job/mir-mediumtests-builder-vivid-armhf/5538/artifact/work/output/*zip*/output.zip
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-mediumtests-runner-touch/7998
    SUCCESS: http://s-jenkins.ubuntu-ci:8080/job/touch-flash-device/26783
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-mediumtests-builder-xenial-armhf/292
        deb: http://jenkins.qa.ubuntu.com/job/mir-mediumtests-builder-xenial-armhf/292/artifact/work/output/*zip*/output.zip
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-mediumtests-runner-xenial-touch/148
    SUCCESS: http://s-jenkins.ubuntu-ci:8080/job/touch-flash-device/26788

Click here to trigger a rebuild:
http://s-jenkins.ubuntu-ci:8080/job/mir-ci/6054/rebuild

review: Approve (continuous-integration)
Revision history for this message
Mir CI Bot (mir-ci-bot) wrote :

PASSED: Continuous integration, rev:3203
https://mir-jenkins.ubuntu.com/job/mir-ci/94/
Executed test runs:
    None: https://mir-jenkins.ubuntu.com/job/generic-update-mp/94/console

Click here to trigger a rebuild:
https://mir-jenkins.ubuntu.com/job/mir-ci/94/rebuild

review: Approve (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :

PASSED: Continuous integration, rev:3203
http://jenkins.qa.ubuntu.com/job/mir-ci/6067/
Executed test runs:
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-android-vivid-i386-build/5600
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-clang-vivid-amd64-build/4507
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-mediumtests-vivid-touch/5556
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-mediumtests-xenial-touch/304
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-xenial-amd64-ci/391
        deb: http://jenkins.qa.ubuntu.com/job/mir-xenial-amd64-ci/391/artifact/work/output/*zip*/output.zip
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-xenial-i386-ci/391
        deb: http://jenkins.qa.ubuntu.com/job/mir-xenial-i386-ci/391/artifact/work/output/*zip*/output.zip
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-mediumtests-builder-vivid-armhf/5553
        deb: http://jenkins.qa.ubuntu.com/job/mir-mediumtests-builder-vivid-armhf/5553/artifact/work/output/*zip*/output.zip
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-mediumtests-runner-touch/8008
    SUCCESS: http://s-jenkins.ubuntu-ci:8080/job/touch-flash-device/26810
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-mediumtests-builder-xenial-armhf/300
        deb: http://jenkins.qa.ubuntu.com/job/mir-mediumtests-builder-xenial-armhf/300/artifact/work/output/*zip*/output.zip
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-mediumtests-runner-xenial-touch/156
    SUCCESS: http://s-jenkins.ubuntu-ci:8080/job/touch-flash-device/26813

Click here to trigger a rebuild:
http://s-jenkins.ubuntu-ci:8080/job/mir-ci/6067/rebuild

review: Approve (continuous-integration)
Revision history for this message
Daniel van Vugt (vanvugt) wrote :

Works nicely now: mir_demo_server --vt 1 --mouse-acceleration=none

review: Approve
Revision history for this message
PS Jenkins bot (ps-jenkins) :
review: Approve (continuous-integration)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'examples/server_example_input_device_config.cpp'
2--- examples/server_example_input_device_config.cpp 2015-12-06 23:57:03 +0000
3+++ examples/server_example_input_device_config.cpp 2016-01-19 22:31:46 +0000
4@@ -31,21 +31,26 @@
5
6 ///\example server_example_input_device_config.cpp
7 /// Demonstrate input device configuration
8-
9-char const* const me::disable_while_typing_opt = "disable-while-typing";
10-char const* const me::mouse_cursor_acceleration_bias_opt = "mouse-cursor-acceleration-bias";
11-char const* const me::mouse_scroll_speed_scale_opt = "mouse-scroll-speed-scale";
12-char const* const me::touchpad_cursor_acceleration_bias_opt = "touchpad-cursor-acceleration-bias";
13-char const* const me::touchpad_scroll_speed_scale_opt = "touchpad-scroll-speed-scale";
14-char const* const me::touchpad_scroll_mode_opt = "touchpad-scroll-mode";
15+namespace
16+{
17+char const* const disable_while_typing_opt = "disable-while-typing";
18+char const* const mouse_acceleration_opt = "mouse-acceleration";
19+char const* const acceleration_none = "none";
20+char const* const acceleration_adaptive = "adaptive";
21+char const* const mouse_cursor_acceleration_bias_opt = "mouse-cursor-acceleration-bias";
22+char const* const mouse_scroll_speed_scale_opt = "mouse-scroll-speed-scale";
23+char const* const touchpad_cursor_acceleration_bias_opt = "touchpad-cursor-acceleration-bias";
24+char const* const touchpad_scroll_speed_scale_opt = "touchpad-scroll-speed-scale";
25+char const* const touchpad_scroll_mode_opt = "touchpad-scroll-mode";
26
27 char const* const touchpad_scroll_mode_two_finger = "two-finger";
28 char const* const touchpad_scroll_mode_edge = "edge";
29
30-char const* const me::touchpad_click_mode_opt= "touchpad-click-mode";
31+char const* const touchpad_click_mode_opt= "touchpad-click-mode";
32
33 char const* const touchpad_click_mode_area = "area";
34 char const* const touchpad_click_mode_finger_count = "finger-count";
35+}
36
37 void me::add_input_device_configuration_options_to(mir::Server& server)
38 {
39@@ -53,14 +58,17 @@
40 server.add_configuration_option(disable_while_typing_opt,
41 "Disable touchpad while typing on keyboard configuration [true, false]",
42 false);
43+ server.add_configuration_option(mouse_acceleration_opt,
44+ "Select acceleration profile for mice and trackballs [none, adaptive]",
45+ acceleration_adaptive);
46 server.add_configuration_option(mouse_cursor_acceleration_bias_opt,
47- "Bias to the acceleration curve within the range [-1.0, 1.0] for mice",
48+ "Constant factor (+1) to velocity or bias to the acceleration curve within the range [-1.0, 1.0] for mice",
49 0.0);
50 server.add_configuration_option(mouse_scroll_speed_scale_opt,
51 "Scales mice scroll events, use negative values for natural scrolling",
52 1.0);
53 server.add_configuration_option(touchpad_cursor_acceleration_bias_opt,
54- "Bias to the acceleration curve within the range [-1.0, 1.0] for touchpads",
55+ "Constant factor (+1) to velocity or bias to the acceleration curve within the range [-1.0, 1.0] for touchpads",
56 0.0);
57 server.add_configuration_option(touchpad_scroll_speed_scale_opt,
58 "Scales touchpad scroll events, use negative values for natural scrolling",
59@@ -93,6 +101,13 @@
60 return mir_touchpad_scroll_mode_none;
61 };
62
63+ auto to_profile = [](std::string const& val)
64+ {
65+ if (val == acceleration_none)
66+ return mir_pointer_acceleration_none;
67+ return mir_pointer_acceleration_adaptive;
68+ };
69+
70 auto convert_to_click_mode = [](std::string const& val)
71 {
72 if (val == touchpad_click_mode_finger_count)
73@@ -107,6 +122,7 @@
74 auto const options = server.get_options();
75 auto const input_config = std::make_shared<me::InputDeviceConfig>(
76 options->get<bool>(disable_while_typing_opt),
77+ to_profile(options->get<std::string>(mouse_acceleration_opt)),
78 clamp_to_range(options->get<double>(mouse_cursor_acceleration_bias_opt)),
79 options->get<double>(mouse_scroll_speed_scale_opt),
80 clamp_to_range(options->get<double>(touchpad_cursor_acceleration_bias_opt)),
81@@ -122,13 +138,15 @@
82 /// Demonstrate how to implement an InputDeviceObserver that identifies and configures input devices.
83
84 me::InputDeviceConfig::InputDeviceConfig(bool disable_while_typing,
85+ MirPointerAcceleration mouse_profile,
86 double mouse_cursor_acceleration_bias,
87 double mouse_scroll_speed_scale,
88 double touchpad_cursor_acceleration_bias,
89 double touchpad_scroll_speed_scale,
90 MirTouchpadClickModes click_mode,
91 MirTouchpadClickModes scroll_mode)
92- : disable_while_typing(disable_while_typing), mouse_cursor_acceleration_bias(mouse_cursor_acceleration_bias),
93+ : disable_while_typing(disable_while_typing), mouse_profile{mouse_profile},
94+ mouse_cursor_acceleration_bias(mouse_cursor_acceleration_bias),
95 mouse_scroll_speed_scale(mouse_scroll_speed_scale),
96 touchpad_cursor_acceleration_bias(touchpad_cursor_acceleration_bias),
97 touchpad_scroll_speed_scale(touchpad_scroll_speed_scale), click_mode(click_mode), scroll_mode(scroll_mode)
98@@ -154,6 +172,7 @@
99 else if (contains(device->capabilities(), mi::DeviceCapability::pointer))
100 {
101 mi::PointerConfiguration pointer_config( device->pointer_configuration().value() );
102+ pointer_config.acceleration = mouse_profile;
103 pointer_config.cursor_acceleration_bias = mouse_cursor_acceleration_bias;
104 pointer_config.vertical_scroll_scale = mouse_scroll_speed_scale;
105 pointer_config.horizontal_scroll_scale = mouse_scroll_speed_scale;
106
107=== modified file 'examples/server_example_input_device_config.h'
108--- examples/server_example_input_device_config.h 2015-12-06 23:57:03 +0000
109+++ examples/server_example_input_device_config.h 2016-01-19 22:31:46 +0000
110@@ -33,20 +33,13 @@
111
112 namespace examples
113 {
114-extern char const* const disable_while_typing_opt;
115-extern char const* const mouse_cursor_acceleration_bias_opt;
116-extern char const* const mouse_scroll_speed_scale_opt;
117-extern char const* const touchpad_cursor_acceleration_bias_opt;
118-extern char const* const touchpad_scroll_speed_scale_opt;
119-extern char const* const touchpad_click_mode_opt;
120-extern char const* const touchpad_scroll_mode_opt;
121-
122 void add_input_device_configuration_options_to(Server& server);
123
124 class InputDeviceConfig : public mir::input::InputDeviceObserver
125 {
126 public:
127 InputDeviceConfig(bool disable_while_typing,
128+ MirPointerAcceleration mouse_profile,
129 double mouse_cursor_acceleration_bias,
130 double mouse_scroll_speed_scale,
131 double touchpad_cursor_acceleration_bias,
132@@ -59,6 +52,7 @@
133 void changes_complete() override {}
134 private:
135 bool disable_while_typing;
136+ MirPointerAcceleration mouse_profile;
137 double mouse_cursor_acceleration_bias;
138 double mouse_scroll_speed_scale;
139 double touchpad_cursor_acceleration_bias;
140
141=== modified file 'include/client/mir_toolkit/mir_input_device.h'
142--- include/client/mir_toolkit/mir_input_device.h 2015-10-26 03:33:22 +0000
143+++ include/client/mir_toolkit/mir_input_device.h 2016-01-19 22:31:46 +0000
144@@ -32,6 +32,21 @@
145 mir_pointer_handedness_left = 1
146 } MirPointerHandedness;
147
148+/**
149+ * MirPointerAcceleration describes the way pointer movement is filtered:
150+ * - mir_pointer_acceleration_none: (acceleration bias + 1.0) is applied as
151+ * a factor to the current velocity of the pointer. So a bias of 0 to results
152+ * to no change of velocity.
153+ * - mir_pointer_acceleration_adaptive: acceleration bias selects an
154+ * acceleration function based on the current velocity that usually consists
155+ * of two linear inclines separated by a plateau.
156+ */
157+typedef enum MirPointerAcceleration
158+{
159+ mir_pointer_acceleration_none = 1,
160+ mir_pointer_acceleration_adaptive = 2
161+} MirPointerAcceleration;
162+
163 typedef enum MirTouchpadClickMode
164 {
165 mir_touchpad_click_mode_none = 0,
166
167=== modified file 'include/platform/mir/input/pointer_settings.h'
168--- include/platform/mir/input/pointer_settings.h 2015-10-26 03:33:22 +0000
169+++ include/platform/mir/input/pointer_settings.h 2016-01-19 22:31:46 +0000
170@@ -43,6 +43,10 @@
171 */
172 double cursor_acceleration_bias{0.0};
173 /**
174+ * Acceleration profile
175+ */
176+ MirPointerAcceleration acceleration{mir_pointer_acceleration_adaptive};
177+ /**
178 * Scale horizontal scrolling linearly
179 */
180 double horizontal_scroll_scale{1.0};
181
182=== modified file 'include/server/mir/input/pointer_configuration.h'
183--- include/server/mir/input/pointer_configuration.h 2015-11-04 16:30:42 +0000
184+++ include/server/mir/input/pointer_configuration.h 2016-01-19 22:31:46 +0000
185@@ -33,10 +33,11 @@
186 {
187 PointerConfiguration() {}
188
189- PointerConfiguration(MirPointerHandedness handedness, double acceleration_bias, double horizontal_scroll_scale,
190- double vertical_scroll_scale)
191- : handedness{handedness}, cursor_acceleration_bias{acceleration_bias},
192- horizontal_scroll_scale{horizontal_scroll_scale}, vertical_scroll_scale{vertical_scroll_scale}
193+ PointerConfiguration(MirPointerHandedness handedness, MirPointerAcceleration acceleration, double acceleration_bias,
194+ double horizontal_scroll_scale, double vertical_scroll_scale)
195+ : handedness{handedness}, acceleration{acceleration},
196+ cursor_acceleration_bias{acceleration_bias}, horizontal_scroll_scale{horizontal_scroll_scale},
197+ vertical_scroll_scale{vertical_scroll_scale}
198 {
199 }
200
201@@ -47,6 +48,11 @@
202 MirPointerHandedness handedness{mir_pointer_handedness_right};
203
204 /*!
205+ * Configure cursor acceleration profile
206+ */
207+ MirPointerAcceleration acceleration{mir_pointer_acceleration_adaptive};
208+
209+ /*!
210 * Configures the intensity of the cursor acceleration. Values within the range of [-1, 1] are allowed.
211 * - 0: default acceleration
212 * - [-1, 0): reduced acceleration
213
214=== modified file 'src/platforms/evdev/libinput_device.cpp'
215--- src/platforms/evdev/libinput_device.cpp 2016-01-07 11:55:03 +0000
216+++ src/platforms/evdev/libinput_device.cpp 2016-01-19 22:31:46 +0000
217@@ -167,9 +167,8 @@
218
219 report->received_event_from_kernel(time.count(), EV_REL, 0, 0);
220
221- mir::geometry::Displacement const movement{
222- libinput_event_pointer_get_dx(pointer),
223- libinput_event_pointer_get_dy(pointer)};
224+ mir::geometry::Displacement const movement{libinput_event_pointer_get_dx(pointer),
225+ libinput_event_pointer_get_dy(pointer)};
226
227 return builder->pointer_event(time, action, button_state, hscroll_value, vscroll_value, movement.dx.as_float(),
228 movement.dy.as_float());
229@@ -336,15 +335,18 @@
230 if (!contains(info.capabilities, mi::DeviceCapability::pointer))
231 return {};
232
233- auto dev = device();
234- auto accel_bias = libinput_device_config_accel_get_speed(dev);
235- auto left_handed = (libinput_device_config_left_handed_get(dev) == 1);
236-
237 mi::PointerSettings settings;
238- settings.cursor_acceleration_bias = accel_bias;
239+ auto dev = device();
240+ auto const left_handed = (libinput_device_config_left_handed_get(dev) == 1);
241+ settings.handedness = left_handed? mir_pointer_handedness_left : mir_pointer_handedness_right;
242+ if (libinput_device_config_accel_get_profile(dev) == LIBINPUT_CONFIG_ACCEL_PROFILE_FLAT)
243+ settings.acceleration = mir_pointer_acceleration_none;
244+ else
245+ settings.acceleration = mir_pointer_acceleration_adaptive;
246+
247+ settings.cursor_acceleration_bias = libinput_device_config_accel_get_speed(dev);
248 settings.vertical_scroll_scale = vertical_scroll_scale;
249 settings.horizontal_scroll_scale = horizontal_scroll_scale;
250- settings.handedness = left_handed? mir_pointer_handedness_left : mir_pointer_handedness_right;
251 return settings;
252 }
253
254@@ -354,10 +356,15 @@
255 return;
256
257 auto dev = device();
258+
259+ auto accel_profile = settings.acceleration == mir_pointer_acceleration_adaptive ?
260+ LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE :
261+ LIBINPUT_CONFIG_ACCEL_PROFILE_FLAT;
262 libinput_device_config_accel_set_speed(dev, settings.cursor_acceleration_bias);
263 libinput_device_config_left_handed_set(dev, mir_pointer_handedness_left == settings.handedness);
264 vertical_scroll_scale = settings.vertical_scroll_scale;
265 horizontal_scroll_scale = settings.horizontal_scroll_scale;
266+ libinput_device_config_accel_set_profile(dev, accel_profile);
267 }
268
269 mir::optional_value<mi::TouchpadSettings> mie::LibInputDevice::get_touchpad_settings() const
270
271=== modified file 'src/server/input/default_device.cpp'
272--- src/server/input/default_device.cpp 2015-11-04 19:47:19 +0000
273+++ src/server/input/default_device.cpp 2016-01-19 22:31:46 +0000
274@@ -62,8 +62,9 @@
275
276 auto const& settings = pointer.value();
277
278- return PointerConfiguration(settings.handedness, settings.cursor_acceleration_bias,
279- settings.horizontal_scroll_scale, settings.vertical_scroll_scale);
280+ return PointerConfiguration(settings.handedness, settings.acceleration,
281+ settings.cursor_acceleration_bias, settings.horizontal_scroll_scale,
282+ settings.vertical_scroll_scale);
283 }
284
285 mir::optional_value<mi::TouchpadConfiguration> mi::DefaultDevice::touchpad_configuration() const
286@@ -88,6 +89,7 @@
287
288 PointerSettings settings;
289 settings.handedness = conf.handedness;
290+ settings.acceleration = conf.acceleration;
291 settings.cursor_acceleration_bias = conf.cursor_acceleration_bias;
292 settings.vertical_scroll_scale = conf.vertical_scroll_scale;
293 settings.horizontal_scroll_scale = conf.horizontal_scroll_scale;
294
295=== modified file 'tests/include/mir/test/doubles/mock_libinput.h'
296--- tests/include/mir/test/doubles/mock_libinput.h 2016-01-07 11:55:03 +0000
297+++ tests/include/mir/test/doubles/mock_libinput.h 2016-01-19 22:31:46 +0000
298@@ -121,6 +121,8 @@
299 MOCK_METHOD2(libinput_device_config_accel_set_speed, libinput_config_status(libinput_device*, double speed));
300 MOCK_METHOD1(libinput_device_config_accel_get_speed, double(libinput_device*));
301 MOCK_METHOD1(libinput_device_config_accel_get_default_speed, double(libinput_device*));
302+ MOCK_METHOD2(libinput_device_config_accel_set_profile, libinput_config_status(libinput_device*, libinput_config_accel_profile));
303+ MOCK_METHOD1(libinput_device_config_accel_get_profile, libinput_config_accel_profile(libinput_device*));
304 MOCK_METHOD1(libinput_device_config_scroll_has_natural_scroll, int(libinput_device*));
305 MOCK_METHOD2(libinput_device_config_scroll_set_natural_scroll_enabled, libinput_config_status(libinput_device*, int enable));
306 MOCK_METHOD1(libinput_device_config_scroll_get_natural_scroll_enabled, int(libinput_device*));
307
308=== modified file 'tests/mir_test_doubles/mock_libinput.cpp'
309--- tests/mir_test_doubles/mock_libinput.cpp 2016-01-07 11:55:03 +0000
310+++ tests/mir_test_doubles/mock_libinput.cpp 2016-01-19 22:31:46 +0000
311@@ -51,6 +51,8 @@
312 .WillByDefault(Return(LIBINPUT_CONFIG_STATUS_SUCCESS));
313 ON_CALL(*this, libinput_device_config_middle_emulation_set_enabled(_, _))
314 .WillByDefault(Return(LIBINPUT_CONFIG_STATUS_SUCCESS));
315+ ON_CALL(*this, libinput_device_config_accel_set_profile(_, _))
316+ .WillByDefault(Return(LIBINPUT_CONFIG_STATUS_SUCCESS));
317 }
318
319 void mtd::MockLibInput::wake()
320@@ -458,6 +460,16 @@
321 return global_libinput->libinput_device_config_accel_get_default_speed(device);
322 }
323
324+libinput_config_status libinput_device_config_accel_set_profile(libinput_device* dev, libinput_config_accel_profile profile)
325+{
326+ return global_libinput->libinput_device_config_accel_set_profile(dev, profile);
327+}
328+
329+libinput_config_accel_profile libinput_device_config_accel_get_profile(libinput_device* dev)
330+{
331+ return global_libinput->libinput_device_config_accel_get_profile(dev);
332+}
333+
334 int libinput_device_config_scroll_has_natural_scroll(libinput_device *device)
335 {
336 return global_libinput->libinput_device_config_scroll_has_natural_scroll(device);
337
338=== modified file 'tests/mir_test_framework/fake_input_device_impl.cpp'
339--- tests/mir_test_framework/fake_input_device_impl.cpp 2015-11-25 20:26:59 +0000
340+++ tests/mir_test_framework/fake_input_device_impl.cpp 2016-01-19 22:31:46 +0000
341@@ -90,6 +90,9 @@
342 std::shared_ptr<mir::dispatch::Dispatchable> const& dispatchable)
343 : info(info), queue{dispatchable}, buttons{0}
344 {
345+ // the default setup results in a direct mapping of input velocity to output velocity.
346+ settings.acceleration = mir_pointer_acceleration_none;
347+ settings.cursor_acceleration_bias = 0.0;
348 }
349
350 void mtf::FakeInputDeviceImpl::InputDevice::synthesize_events(synthesis::KeyParameters const& key_params)
351@@ -151,9 +154,9 @@
352 // constant scaling is used here to simplify checking for the
353 // expected results. Default settings of the device lead to no
354 // scaling at all.
355- auto acceleration = (settings.cursor_acceleration_bias + 1.0);
356- auto rel_x = pointer.rel_x * acceleration;
357- auto rel_y = pointer.rel_y * acceleration;
358+ auto const acceleration = settings.cursor_acceleration_bias + 1.0;
359+ auto const rel_x = pointer.rel_x * acceleration;
360+ auto const rel_y = pointer.rel_y * acceleration;
361
362 auto pointer_event = builder->pointer_event(event_time,
363 mir_pointer_action_motion,
364@@ -213,7 +216,7 @@
365 if (!contains(info.capabilities, mi::DeviceCapability::pointer))
366 return ret;
367
368- ret = mi::PointerSettings();
369+ ret = settings;
370 return ret;
371 }
372
373
374=== modified file 'tests/unit-tests/input/evdev/test_libinput_device.cpp'
375--- tests/unit-tests/input/evdev/test_libinput_device.cpp 2016-01-07 11:55:03 +0000
376+++ tests/unit-tests/input/evdev/test_libinput_device.cpp 2016-01-19 22:31:46 +0000
377@@ -208,12 +208,16 @@
378 return device_path;
379 }
380
381- void setup_pointer_configuration(libinput_device* dev, double accel_speed, MirPointerHandedness handedness)
382+ void setup_pointer_configuration(libinput_device* dev, double accel_speed, MirPointerHandedness handedness, MirPointerAcceleration profile)
383 {
384 ON_CALL(mock_libinput, libinput_device_config_accel_get_speed(dev))
385 .WillByDefault(Return(accel_speed));
386 ON_CALL(mock_libinput, libinput_device_config_left_handed_get(dev))
387 .WillByDefault(Return(handedness == mir_pointer_handedness_left));
388+ ON_CALL(mock_libinput, libinput_device_config_accel_get_profile(dev))
389+ .WillByDefault(Return((profile == mir_pointer_acceleration_none) ?
390+ LIBINPUT_CONFIG_ACCEL_PROFILE_FLAT :
391+ LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE));
392 }
393
394 void setup_touchpad_configuration(libinput_device* dev,
395@@ -779,7 +783,7 @@
396
397 TEST_F(LibInputDeviceOnMouse, reads_pointer_settings_from_libinput)
398 {
399- setup_pointer_configuration(mouse.device(), 1, mir_pointer_handedness_right);
400+ setup_pointer_configuration(mouse.device(), 1, mir_pointer_handedness_right, mir_pointer_acceleration_none);
401 auto optional_settings = mouse.get_pointer_settings();
402
403 EXPECT_THAT(optional_settings.is_set(), Eq(true));
404@@ -789,8 +793,9 @@
405 EXPECT_THAT(ptr_settings.cursor_acceleration_bias, Eq(1.0));
406 EXPECT_THAT(ptr_settings.horizontal_scroll_scale, Eq(1.0));
407 EXPECT_THAT(ptr_settings.vertical_scroll_scale, Eq(1.0));
408+ EXPECT_THAT(ptr_settings.acceleration, Eq(mir_pointer_acceleration_none));
409
410- setup_pointer_configuration(mouse.device(), 0.0, mir_pointer_handedness_left);
411+ setup_pointer_configuration(mouse.device(), 0.0, mir_pointer_handedness_left, mir_pointer_acceleration_adaptive);
412 optional_settings = mouse.get_pointer_settings();
413
414 EXPECT_THAT(optional_settings.is_set(), Eq(true));
415@@ -800,23 +805,27 @@
416 EXPECT_THAT(ptr_settings.cursor_acceleration_bias, Eq(0.0));
417 EXPECT_THAT(ptr_settings.horizontal_scroll_scale, Eq(1.0));
418 EXPECT_THAT(ptr_settings.vertical_scroll_scale, Eq(1.0));
419+ EXPECT_THAT(ptr_settings.acceleration, Eq(mir_pointer_acceleration_adaptive));
420 }
421
422 TEST_F(LibInputDeviceOnMouse, applies_pointer_settings)
423 {
424- setup_pointer_configuration(mouse.device(), 1, mir_pointer_handedness_right);
425+ setup_pointer_configuration(mouse.device(), 1, mir_pointer_handedness_right, mir_pointer_acceleration_adaptive);
426 mi::PointerSettings settings(mouse.get_pointer_settings().value());
427 settings.cursor_acceleration_bias = 1.1;
428 settings.handedness = mir_pointer_handedness_left;
429+ settings.acceleration = mir_pointer_acceleration_none;
430
431- EXPECT_CALL(mock_libinput,libinput_device_config_accel_set_speed(mouse.device(), 1.1)).Times(1);
432- EXPECT_CALL(mock_libinput,libinput_device_config_left_handed_set(mouse.device(), true)).Times(1);
433+ EXPECT_CALL(mock_libinput, libinput_device_config_accel_set_speed(mouse.device(), 1.1)).Times(1);
434+ EXPECT_CALL(mock_libinput, libinput_device_config_accel_set_profile(mouse.device(), LIBINPUT_CONFIG_ACCEL_PROFILE_FLAT)).Times(1);
435+ EXPECT_CALL(mock_libinput, libinput_device_config_left_handed_set(mouse.device(), true)).Times(1);
436
437 mouse.apply_settings(settings);
438 }
439
440 TEST_F(LibInputDeviceOnLaptopKeyboardAndMouse, denies_pointer_settings_on_keyboards)
441 {
442+ setup_pointer_configuration(mouse.device(), 1, mir_pointer_handedness_right, mir_pointer_acceleration_adaptive);
443 auto settings_from_mouse = mouse.get_pointer_settings();
444
445 EXPECT_CALL(mock_libinput,libinput_device_config_accel_set_speed(_, _)).Times(0);
446@@ -834,7 +843,7 @@
447 EXPECT_CALL(mock_sink, handle_input(mt::PointerAxisChange(mir_pointer_axis_vscroll, 3.0f)));
448 EXPECT_CALL(mock_sink, handle_input(mt::PointerAxisChange(mir_pointer_axis_hscroll, -10.0f)));
449
450- setup_pointer_configuration(mouse.device(), 1, mir_pointer_handedness_right);
451+ setup_pointer_configuration(mouse.device(), 1, mir_pointer_handedness_right, mir_pointer_acceleration_none);
452 mi::PointerSettings settings(mouse.get_pointer_settings().value());
453 settings.vertical_scroll_scale = -1.0;
454 settings.horizontal_scroll_scale = 5.0;

Subscribers

People subscribed via source and target branches