Merge lp:~andreas-pokorny/mir/libinput-platform-pointer-settings into lp:mir
- libinput-platform-pointer-settings
- Merge into development-branch
Status: | Merged |
---|---|
Approved by: | Andreas Pokorny |
Approved revision: | no longer in the source branch. |
Merged at revision: | 3037 |
Proposed branch: | lp:~andreas-pokorny/mir/libinput-platform-pointer-settings |
Merge into: | lp:mir |
Prerequisite: | lp:~andreas-pokorny/mir/extended-mock-of-libinput |
Diff against target: |
653 lines (+352/-16) 14 files modified
include/client/mir_toolkit/mir_input_device.h (+39/-0) include/platform/mir/input/input_device.h (+8/-0) include/platform/mir/input/pointer_settings.h (+58/-0) src/platforms/evdev/input_modifier_utils.cpp (+7/-3) src/platforms/evdev/input_modifier_utils.h (+2/-1) src/platforms/evdev/libinput_device.cpp (+36/-3) src/platforms/evdev/libinput_device.h (+4/-0) src/platforms/mesa/server/x11/input/input_device.cpp (+18/-1) src/platforms/mesa/server/x11/input/input_device.h (+4/-0) tests/include/mir/test/gmock_fixes.h (+23/-0) tests/mir_test_framework/fake_input_device_impl.cpp (+30/-4) tests/mir_test_framework/fake_input_device_impl.h (+5/-0) tests/unit-tests/input/evdev/test_libinput_device.cpp (+115/-4) tests/unit-tests/input/test_default_input_device_hub.cpp (+3/-0) |
To merge this branch: | bzr merge lp:~andreas-pokorny/mir/libinput-platform-pointer-settings |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
PS Jenkins bot (community) | continuous-integration | Approve | |
Chris Halse Rogers | Approve | ||
Alan Griffiths | Approve | ||
Alexandros Frantzis (community) | Abstain | ||
Daniel van Vugt | Abstain | ||
Andreas Pokorny (community) | Abstain | ||
Review via email: mp+272501@code.launchpad.net |
Commit message
Pointer settings in libinput
Allows configuring cursor acceleration, scroll speed and left-hand/
Description of the change
Add pointer settings to libinput platform.
Pointer settings allow configuring pointer and scroll speed and right-hand / left-hand button ordering. These settings apply to all pointing devices..
Still to come:
- touchpad settings
- keyboard settings
- Exposing settings through mir::input::Device
- supporting settings in x platform
- supporting settings in stub input platforme
PS Jenkins bot (ps-jenkins) wrote : | # |
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:2968
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
FAILURE: http://
SUCCESS: http://
deb: http://
FAILURE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
Alexandros Frantzis (afrantzis) wrote : | # |
+ virtual UniqueModulePtr
Why do we want PointerSettings to keep the module alive?
I would expect just:
PointerSettings get_pointer_
Alan Griffiths (alan-griffiths) wrote : | # |
Looks like some duplication with lp:~andreas-pokorny/mir/let-module-ptr-allow-being-created-in-executable
Alan Griffiths (alan-griffiths) wrote : | # |
> + virtual UniqueModulePtr
>
> Why do we want PointerSettings to keep the module alive?
+1
Andreas Pokorny (andreas-pokorny) wrote : | # |
duplication is because I can only have one prereq branch..
Now looking at that again.. I used the additional nullptr state to indicate that the group of options is not applicable for the device. Initially I thought about not allowing callers to construct their own settings objects. And about turning it into a base class .. but I abandoned those two ideas..
I might also go with optioal<
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:2970
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
FAILURE: http://
SUCCESS: http://
deb: http://
FAILURE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
Andreas Pokorny (andreas-pokorny) wrote : | # |
... or I might use unique_ptr instead, and then do not have to bump the input platform abi when adding properties to the structure. And there we are again: Now I have to make sure that the library outlives the lifetime of the structure since it is the only one that knows how to delete the added values.
So in the end using UniqueModulePtr was a partial solution to ABI changes (it only ensures old mirserver works with new input library not the other way around)...
Andreas Pokorny (andreas-pokorny) wrote : | # |
yeah.. this needs fixing
Andreas Pokorny (andreas-pokorny) wrote : | # |
ok fine now..
[side note:
I had to improve the interface of optional_value (but still not quite happy with its behavior and implementation)]
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:2971
http://
Executed test runs:
FAILURE: http://
SUCCESS: http://
FAILURE: http://
FAILURE: http://
SUCCESS: http://
deb: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
Alan Griffiths (alan-griffiths) wrote : | # |
+ constexpr explicit operator bool() const { return is_set_; }
+ constexpr const T* operator->() const { return &value_; }
+ T* operator->() { return &value_; }
+ constexpr const T& operator*() const { return value_; }
+ T& operator*() { return value_; }
This seems to add a bunch of operators to give different syntax and surprisingly different semantics to the existing interface. Why?
E.g. why do we need operator->()? And why isn't it a synonym for &value()?
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:2974
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
SUCCESS: http://
deb: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
Andreas Pokorny (andreas-pokorny) wrote : | # |
> + constexpr explicit operator bool() const { return is_set_; }
> + constexpr const T* operator->() const { return &value_; }
> + T* operator->() { return &value_; }
> + constexpr const T& operator*() const { return value_; }
> + T& operator*() { return value_; }
>
> This seems to add a bunch of operators to give different syntax and
> surprisingly different semantics to the existing interface. Why?
>
> E.g. why do we need operator->()? And why isn't it a synonym for &value()?
To be closer to std::(experimen
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:2975
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
FAILURE: http://
SUCCESS: http://
deb: http://
FAILURE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:2976
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
Alan Griffiths (alan-griffiths) wrote : | # |
> To be closer to std::(experimen
mir optional_value is a different design to std::(experimen
Andreas Pokorny (andreas-pokorny) wrote : | # |
> > To be closer to std::(experimen
>
> mir optional_value is a different design to std::(experimen
> making them look more alike is probably a bad idea.
Ok the difference between value() and -> in this proposal is odd. I will revert it to the original and update the usage for now.
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:2978
http://
Executed test runs:
SUCCESS: http://
FAILURE: http://
SUCCESS: http://
FAILURE: http://
SUCCESS: http://
deb: http://
FAILURE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
Alan Griffiths (alan-griffiths) wrote : | # |
/mir/include/
optional_
+ PointerSettings() {}
"Otherwise clang does not allow construction with {}"
I'm confused. We're in the optional_
...
Oh! clang is trying to use aggregate initialization and that is defeated by adding any user-defined constructor.
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:2979
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
FAILURE: http://
SUCCESS: http://
deb: http://
FAILURE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:2980
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
FAILURE: http://
SUCCESS: http://
deb: http://
FAILURE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:2981
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
FAILURE: http://
SUCCESS: http://
deb: http://
FAILURE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
Daniel van Vugt (vanvugt) wrote : | # |
(1) It sounds like we're mixing up the terms "speed" (magnitude of velocity) and "acceleration". Acceleration is the rate of change of velocity. However it appears actual acceleration might be always zero, and 'acceleration' here refers to the velocity? Have we confused our physics terminology? If so, that should be cleared up...
(2) So how long before we can declare bug 124440 fixed? :)
Andreas Pokorny (andreas-pokorny) wrote : | # |
> (1) It sounds like we're mixing up the terms "speed" (magnitude of velocity)
> and "acceleration". Acceleration is the rate of change of velocity. However it
> appears actual acceleration might be always zero, and 'acceleration' here
> refers to the velocity? Have we confused our physics terminology? If so, that
> should be cleared up...
Yes kind of .. this is an physical inaccuracy that leaks into the software from the domain model. Naming it acceleration would be incorrect to. Since the cursor speed is actually a scaling of the acceleration curve - which is a curve providing the actual speed scale based on the amount of recent movement. Where recent movement is the relative steps we were able to observe from the device.
I could offer a similar confusing comment to clarify things.
>
> (2) So how long before we can declare bug 124440 fixed? :)
Oh I didn’t realize.. Soon this is one of the values that is planed to be configurable by the initial pocket desktop ui.
Daniel van Vugt (vanvugt) wrote : | # |
Kay.... try to use "velocity" or "speed" if you're referring to the first derivative of position :)
Alan Griffiths (alan-griffiths) wrote : | # |
> > (1) It sounds like we're mixing up the terms "speed" (magnitude of velocity)
> > and "acceleration". Acceleration is the rate of change of velocity. However
> it
> > appears actual acceleration might be always zero, and 'acceleration' here
> > refers to the velocity? Have we confused our physics terminology? If so,
> that
> > should be cleared up...
>
> Yes kind of .. this is an physical inaccuracy that leaks into the software
> from the domain model. Naming it acceleration would be incorrect to. Since the
> cursor speed is actually a scaling of the acceleration curve - which is a
> curve providing the actual speed scale based on the amount of recent movement.
> Where recent movement is the relative steps we were able to observe from the
> device.
>
> I could offer a similar confusing comment to clarify things.
This sounds like a number, not a speed or acceleration. Let's try for clearer terminology.
Alan Griffiths (alan-griffiths) wrote : | # |
Paraphrasing in the hope of confirming (or refuting) my understanding:
"cursor accelaration" is scaling of the first derivative of cursor position (and neither a speed nor an acceleration).
The "acceleration curve" is a function providing this scaling.
PointerSettings
Would it be better to use a term like "speed coefficient" than mixing "acceleration" and "speed"?
[1] Looking at the fake code it is just added to 1 to get the scale factor? If that isn't just an example, wouldn't [0.2] be more intuitive than [-1,1]?
Andreas Pokorny (andreas-pokorny) wrote : | # |
> Paraphrasing in the hope of confirming (or refuting) my understanding:
>
> "cursor accelaration" is scaling of the first derivative of cursor position
> (and neither a speed nor an acceleration).
>
> The "acceleration curve" is a function providing this scaling.
>
> PointerSettings
> (and not a speed nor an acceleration).
>
> Would it be better to use a term like "speed coefficient" than mixing
> "acceleration" and "speed"?
coefficient also implies a linear relation.. What about just calling it 'acceleration curve'?
The default set of curves looks like this:
http://
Afaik other pointing devices get different curve sets...
> [1] Looking at the fake code it is just added to 1 to get the scale factor? If
> that isn't just an example, wouldn't [0.2] be more intuitive than [-1,1]?
Since I wanted to use the acceleration offered by libinput, and since it only provides a weakly defined setting called 'acceleration speed', I decided for this MP that I use the value to affect the positioning of fake pointers, but in a simpler way - not depending on previous events. Also the range is what libinput uses. We could also just have [0,1], and scale it as needed in libinput..
Alexandros Frantzis (afrantzis) wrote : | # |
Unfortunately the historical terms used to describe how mouse movement translates to cursor movement are confusing.
What is called "speed" is actually just distance scaling (e.g. 1 cm of mouse movement => N pixels of cursors movement), and what is called "acceleration" is just changing the scaling dynamically depending on (real) mouse speed.
Not sure what the best term would be, but perhaps it would be better to stick to the historical terms for reasons of familiarity.
+ [-1, 0[
Usually written as [-1, 0)
Alan Griffiths (alan-griffiths) wrote : | # |
+ /**
+ * Scale cursor accelaration.
+ * - 0: default acceleration
+ * - [-1, 0[: reduced acceleration
+ * - ]0, 1]: increased acceleration
+ */
+ double cursor_speed{0.0};
+ double horizontal_
+ double vertical_
/1/ I don't think this actually follows the terminology explained in the comments.
/2/ "accelaration" => "acceleration"
/3/ Is the doc comment intended to apply to all three fields? (It only applies to the first.)
So, as I understand the explanation...
/**
* Bias cursor acceleration:
* - [-1, 0): reduced acceleration
* - 0: default acceleration
* - (0, 1]: increased acceleration
*/
double bias_cursor_
Alan Griffiths (alan-griffiths) wrote : | # |
It would be more consistent with "horizontal_
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:2982
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
FAILURE: http://
FAILURE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
FAILURE: http://
SUCCESS: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
Andreas Pokorny (andreas-pokorny) wrote : | # |
[1444835234.581027] mirserver: Stopping
/bin/bash: line 1: 6450 Segmentation fault mir_demo_server --test-client /usr/bin/
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:2983
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
FAILURE: http://
FAILURE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
FAILURE: http://
SUCCESS: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:2982
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
FAILURE: http://
FAILURE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
Andreas Pokorny (andreas-pokorny) wrote : | # |
Resolving s-jenkins.ubuntu-ci (s-jenkins.
Connecting to s-jenkins.ubuntu-ci (s-jenkins.
HTTP request sent, awaiting response... 500 Internal Server Error
2015-10-14 18:13:32 ERROR 500: Internal Server Error.
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:2982
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
FAILURE: http://
SUCCESS: http://
deb: http://
None: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
Chris Halse Rogers (raof) wrote : | # |
+ /**
+ * Configure left and right handed mode by selecting a primary button
+ * - mir_pointer_
+ * - mir_pointer_
+ */
+ MirPointerButton primary_
Non-blocking: I think this would be better as an explicit mir_pointer_
Feel free to fix that, or not.
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Autolanding.
More details in the following jenkins job:
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
FAILURE: http://
FAILURE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
FAILURE: http://
SUCCESS: http://
FAILURE: http://
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:2984
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
FAILURE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
Preview Diff
1 | === added file 'include/client/mir_toolkit/mir_input_device.h' | |||
2 | --- include/client/mir_toolkit/mir_input_device.h 1970-01-01 00:00:00 +0000 | |||
3 | +++ include/client/mir_toolkit/mir_input_device.h 2015-10-19 10:46:25 +0000 | |||
4 | @@ -0,0 +1,39 @@ | |||
5 | 1 | /* | ||
6 | 2 | * Copyright © 2015 Canonical Ltd. | ||
7 | 3 | * | ||
8 | 4 | * This program is free software: you can redistribute it and/or modify it | ||
9 | 5 | * under the terms of the GNU Lesser General Public License version 3, | ||
10 | 6 | * as published by the Free Software Foundation. | ||
11 | 7 | * | ||
12 | 8 | * This program is distributed in the hope that it will be useful, | ||
13 | 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | 11 | * GNU Lesser General Public License for more details. | ||
16 | 12 | * | ||
17 | 13 | * You should have received a copy of the GNU Lesser General Public License | ||
18 | 14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
19 | 15 | * | ||
20 | 16 | */ | ||
21 | 17 | |||
22 | 18 | #ifndef MIR_TOOLKIT_MIR_INPUT_DEVICE_H_ | ||
23 | 19 | #define MIR_TOOLKIT_MIR_INPUT_DEVICE_H_ | ||
24 | 20 | |||
25 | 21 | /** | ||
26 | 22 | * \addtogroup mir_toolkit | ||
27 | 23 | * @{ | ||
28 | 24 | */ | ||
29 | 25 | #ifdef __cplusplus | ||
30 | 26 | extern "C" { | ||
31 | 27 | #endif | ||
32 | 28 | |||
33 | 29 | typedef enum MirPointerHandedness | ||
34 | 30 | { | ||
35 | 31 | mir_pointer_handedness_right = 0, | ||
36 | 32 | mir_pointer_handedness_left = 1 | ||
37 | 33 | } MirPointerHandedness; | ||
38 | 34 | |||
39 | 35 | #ifdef __cplusplus | ||
40 | 36 | } | ||
41 | 37 | #endif | ||
42 | 38 | |||
43 | 39 | #endif | ||
44 | 0 | 40 | ||
45 | === modified file 'include/platform/mir/input/input_device.h' | |||
46 | --- include/platform/mir/input/input_device.h 2015-09-01 07:41:29 +0000 | |||
47 | +++ include/platform/mir/input/input_device.h 2015-10-19 10:46:25 +0000 | |||
48 | @@ -20,6 +20,9 @@ | |||
49 | 20 | #ifndef MIR_INPUT_INPUT_DEVICE_H_ | 20 | #ifndef MIR_INPUT_INPUT_DEVICE_H_ |
50 | 21 | #define MIR_INPUT_INPUT_DEVICE_H_ | 21 | #define MIR_INPUT_INPUT_DEVICE_H_ |
51 | 22 | 22 | ||
52 | 23 | #include "mir/module_deleter.h" | ||
53 | 24 | #include "mir/optional_value.h" | ||
54 | 25 | |||
55 | 23 | #include <memory> | 26 | #include <memory> |
56 | 24 | 27 | ||
57 | 25 | namespace mir | 28 | namespace mir |
58 | @@ -34,6 +37,8 @@ | |||
59 | 34 | class InputDeviceInfo; | 37 | class InputDeviceInfo; |
60 | 35 | class EventBuilder; | 38 | class EventBuilder; |
61 | 36 | 39 | ||
62 | 40 | class PointerSettings; | ||
63 | 41 | |||
64 | 37 | /** | 42 | /** |
65 | 38 | * Represents an input device. | 43 | * Represents an input device. |
66 | 39 | */ | 44 | */ |
67 | @@ -54,6 +59,9 @@ | |||
68 | 54 | 59 | ||
69 | 55 | virtual InputDeviceInfo get_device_info() = 0; | 60 | virtual InputDeviceInfo get_device_info() = 0; |
70 | 56 | 61 | ||
71 | 62 | virtual mir::optional_value<PointerSettings> get_pointer_settings() const = 0; | ||
72 | 63 | virtual void apply_settings(PointerSettings const&) = 0; | ||
73 | 64 | |||
74 | 57 | protected: | 65 | protected: |
75 | 58 | InputDevice(InputDevice const&) = delete; | 66 | InputDevice(InputDevice const&) = delete; |
76 | 59 | InputDevice& operator=(InputDevice const&) = delete; | 67 | InputDevice& operator=(InputDevice const&) = delete; |
77 | 60 | 68 | ||
78 | === added file 'include/platform/mir/input/pointer_settings.h' | |||
79 | --- include/platform/mir/input/pointer_settings.h 1970-01-01 00:00:00 +0000 | |||
80 | +++ include/platform/mir/input/pointer_settings.h 2015-10-19 10:46:25 +0000 | |||
81 | @@ -0,0 +1,58 @@ | |||
82 | 1 | /* | ||
83 | 2 | * Copyright © 2015 Canonical Ltd. | ||
84 | 3 | * | ||
85 | 4 | * This program is free software: you can redistribute it and/or modify it | ||
86 | 5 | * under the terms of the GNU Lesser General Public License version 3, | ||
87 | 6 | * as published by the Free Software Foundation. | ||
88 | 7 | * | ||
89 | 8 | * This program is distributed in the hope that it will be useful, | ||
90 | 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
91 | 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
92 | 11 | * GNU Lesser General Public License for more details. | ||
93 | 12 | * | ||
94 | 13 | * You should have received a copy of the GNU Lesser General Public License | ||
95 | 14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
96 | 15 | * | ||
97 | 16 | * Authored by: | ||
98 | 17 | * Andreas Pokorny <andreas.pokorny@canonical.com> | ||
99 | 18 | */ | ||
100 | 19 | |||
101 | 20 | #ifndef MIR_INPUT_POINTER_SETTINGS_H_ | ||
102 | 21 | #define MIR_INPUT_POINTER_SETTINGS_H_ | ||
103 | 22 | |||
104 | 23 | #include "mir_toolkit/client_types.h" | ||
105 | 24 | #include "mir_toolkit/mir_input_device.h" | ||
106 | 25 | |||
107 | 26 | namespace mir | ||
108 | 27 | { | ||
109 | 28 | namespace input | ||
110 | 29 | { | ||
111 | 30 | |||
112 | 31 | struct PointerSettings | ||
113 | 32 | { | ||
114 | 33 | PointerSettings() {} | ||
115 | 34 | /** | ||
116 | 35 | * Configure left and right handed mode by selecting a primary button | ||
117 | 36 | */ | ||
118 | 37 | MirPointerHandedness handedness{mir_pointer_handedness_right}; | ||
119 | 38 | /** | ||
120 | 39 | * Bias cursor acceleration. | ||
121 | 40 | * - [-1, 0): reduced acceleration | ||
122 | 41 | * - 0: default acceleration | ||
123 | 42 | * - (0, 1]: increased acceleration | ||
124 | 43 | */ | ||
125 | 44 | double cursor_acceleration_bias{0.0}; | ||
126 | 45 | /** | ||
127 | 46 | * Scale horizontal scrolling linearly | ||
128 | 47 | */ | ||
129 | 48 | double horizontal_scroll_scale{1.0}; | ||
130 | 49 | /** | ||
131 | 50 | * Scale vertical scrolling linearly | ||
132 | 51 | */ | ||
133 | 52 | double vertical_scroll_scale{1.0}; | ||
134 | 53 | }; | ||
135 | 54 | |||
136 | 55 | } | ||
137 | 56 | } | ||
138 | 57 | |||
139 | 58 | #endif | ||
140 | 0 | 59 | ||
141 | === modified file 'src/platforms/evdev/input_modifier_utils.cpp' | |||
142 | --- src/platforms/evdev/input_modifier_utils.cpp 2015-09-17 06:40:14 +0000 | |||
143 | +++ src/platforms/evdev/input_modifier_utils.cpp 2015-10-19 10:46:25 +0000 | |||
144 | @@ -27,12 +27,16 @@ | |||
145 | 27 | 27 | ||
146 | 28 | namespace mie = mir::input::evdev; | 28 | namespace mie = mir::input::evdev; |
147 | 29 | 29 | ||
149 | 30 | MirPointerButton mie::to_pointer_button(int button) | 30 | MirPointerButton mie::to_pointer_button(int button, MirPointerHandedness handedness) |
150 | 31 | { | 31 | { |
151 | 32 | switch(button) | 32 | switch(button) |
152 | 33 | { | 33 | { |
155 | 34 | case BTN_LEFT: return mir_pointer_button_primary; | 34 | case BTN_LEFT: return (handedness == mir_pointer_handedness_right) |
156 | 35 | case BTN_RIGHT: return mir_pointer_button_secondary; | 35 | ? mir_pointer_button_primary |
157 | 36 | : mir_pointer_button_secondary; | ||
158 | 37 | case BTN_RIGHT: return (handedness == mir_pointer_handedness_right) | ||
159 | 38 | ? mir_pointer_button_secondary | ||
160 | 39 | : mir_pointer_button_primary; | ||
161 | 36 | case BTN_MIDDLE: return mir_pointer_button_tertiary; | 40 | case BTN_MIDDLE: return mir_pointer_button_tertiary; |
162 | 37 | case BTN_BACK: return mir_pointer_button_back; | 41 | case BTN_BACK: return mir_pointer_button_back; |
163 | 38 | case BTN_FORWARD: return mir_pointer_button_forward; | 42 | case BTN_FORWARD: return mir_pointer_button_forward; |
164 | 39 | 43 | ||
165 | === modified file 'src/platforms/evdev/input_modifier_utils.h' | |||
166 | --- src/platforms/evdev/input_modifier_utils.h 2015-09-17 06:40:14 +0000 | |||
167 | +++ src/platforms/evdev/input_modifier_utils.h 2015-10-19 10:46:25 +0000 | |||
168 | @@ -20,6 +20,7 @@ | |||
169 | 20 | #define MIR_INPUT_EVDEV_INPUT_MODIFIER_UTILS_H_ | 20 | #define MIR_INPUT_EVDEV_INPUT_MODIFIER_UTILS_H_ |
170 | 21 | 21 | ||
171 | 22 | #include "mir_toolkit/event.h" | 22 | #include "mir_toolkit/event.h" |
172 | 23 | #include "mir_toolkit/mir_input_device.h" | ||
173 | 23 | 24 | ||
174 | 24 | namespace mir | 25 | namespace mir |
175 | 25 | { | 26 | { |
176 | @@ -27,7 +28,7 @@ | |||
177 | 27 | { | 28 | { |
178 | 28 | namespace evdev | 29 | namespace evdev |
179 | 29 | { | 30 | { |
181 | 30 | MirPointerButton to_pointer_button(int button); | 31 | MirPointerButton to_pointer_button(int button, MirPointerHandedness handedness); |
182 | 31 | MirInputEventModifiers to_modifiers(int32_t scan_code); | 32 | MirInputEventModifiers to_modifiers(int32_t scan_code); |
183 | 32 | MirInputEventModifiers expand_modifiers(MirInputEventModifiers modifiers); | 33 | MirInputEventModifiers expand_modifiers(MirInputEventModifiers modifiers); |
184 | 33 | } | 34 | } |
185 | 34 | 35 | ||
186 | === modified file 'src/platforms/evdev/libinput_device.cpp' | |||
187 | --- src/platforms/evdev/libinput_device.cpp 2015-10-07 15:32:10 +0000 | |||
188 | +++ src/platforms/evdev/libinput_device.cpp 2015-10-19 10:46:25 +0000 | |||
189 | @@ -25,6 +25,7 @@ | |||
190 | 25 | #include "mir/input/input_sink.h" | 25 | #include "mir/input/input_sink.h" |
191 | 26 | #include "mir/input/input_report.h" | 26 | #include "mir/input/input_report.h" |
192 | 27 | #include "mir/input/device_capability.h" | 27 | #include "mir/input/device_capability.h" |
193 | 28 | #include "mir/input/pointer_settings.h" | ||
194 | 28 | #include "mir/input/input_device_info.h" | 29 | #include "mir/input/input_device_info.h" |
195 | 29 | #include "mir/events/event_builders.h" | 30 | #include "mir/events/event_builders.h" |
196 | 30 | #include "mir/geometry/displacement.h" | 31 | #include "mir/geometry/displacement.h" |
197 | @@ -159,7 +160,8 @@ | |||
198 | 159 | auto const action = (libinput_event_pointer_get_button_state(pointer) == LIBINPUT_BUTTON_STATE_PRESSED)? | 160 | auto const action = (libinput_event_pointer_get_button_state(pointer) == LIBINPUT_BUTTON_STATE_PRESSED)? |
199 | 160 | mir_pointer_action_button_down : mir_pointer_action_button_up; | 161 | mir_pointer_action_button_down : mir_pointer_action_button_up; |
200 | 161 | 162 | ||
202 | 162 | auto const pointer_button = mie::to_pointer_button(button); | 163 | auto const do_not_swap_buttons = mir_pointer_handedness_right; |
203 | 164 | auto const pointer_button = mie::to_pointer_button(button, do_not_swap_buttons); | ||
204 | 163 | auto const relative_x_value = 0.0f; | 165 | auto const relative_x_value = 0.0f; |
205 | 164 | auto const relative_y_value = 0.0f; | 166 | auto const relative_y_value = 0.0f; |
206 | 165 | auto const hscroll_value = 0.0f; | 167 | auto const hscroll_value = 0.0f; |
207 | @@ -232,10 +234,12 @@ | |||
208 | 232 | auto const relative_x_value = 0.0f; | 234 | auto const relative_x_value = 0.0f; |
209 | 233 | auto const relative_y_value = 0.0f; | 235 | auto const relative_y_value = 0.0f; |
210 | 234 | auto const hscroll_value = libinput_event_pointer_has_axis(pointer, LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL) | 236 | auto const hscroll_value = libinput_event_pointer_has_axis(pointer, LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL) |
212 | 235 | ? libinput_event_pointer_get_axis_value(pointer, LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL) | 237 | ? horizontal_scroll_scale * libinput_event_pointer_get_axis_value(pointer, |
213 | 238 | LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL) | ||
214 | 236 | : 0.0f; | 239 | : 0.0f; |
215 | 237 | auto const vscroll_value = libinput_event_pointer_has_axis(pointer, LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL) | 240 | auto const vscroll_value = libinput_event_pointer_has_axis(pointer, LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL) |
217 | 238 | ? libinput_event_pointer_get_axis_value(pointer, LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL) | 241 | ? vertical_scroll_scale * libinput_event_pointer_get_axis_value(pointer, |
218 | 242 | LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL) | ||
219 | 239 | : 0.0f; | 243 | : 0.0f; |
220 | 240 | 244 | ||
221 | 241 | report->received_event_from_kernel(time.count(), EV_REL, 0, 0); | 245 | report->received_event_from_kernel(time.count(), EV_REL, 0, 0); |
222 | @@ -360,3 +364,32 @@ | |||
223 | 360 | { | 364 | { |
224 | 361 | return devices.front().get(); | 365 | return devices.front().get(); |
225 | 362 | } | 366 | } |
226 | 367 | |||
227 | 368 | mir::optional_value<mi::PointerSettings> mie::LibInputDevice::get_pointer_settings() const | ||
228 | 369 | { | ||
229 | 370 | if (!contains(info.capabilities, mi::DeviceCapability::pointer)) | ||
230 | 371 | return {}; | ||
231 | 372 | |||
232 | 373 | auto dev = device(); | ||
233 | 374 | auto accel_bias = libinput_device_config_accel_get_speed(dev); | ||
234 | 375 | auto left_handed = (libinput_device_config_left_handed_get(dev) == 1); | ||
235 | 376 | |||
236 | 377 | mi::PointerSettings settings; | ||
237 | 378 | settings.cursor_acceleration_bias = accel_bias; | ||
238 | 379 | settings.vertical_scroll_scale = vertical_scroll_scale; | ||
239 | 380 | settings.horizontal_scroll_scale = horizontal_scroll_scale; | ||
240 | 381 | settings.handedness = left_handed? mir_pointer_handedness_left : mir_pointer_handedness_right; | ||
241 | 382 | return settings; | ||
242 | 383 | } | ||
243 | 384 | |||
244 | 385 | void mie::LibInputDevice::apply_settings(mir::input::PointerSettings const& settings) | ||
245 | 386 | { | ||
246 | 387 | if (!contains(info.capabilities, mi::DeviceCapability::pointer)) | ||
247 | 388 | return; | ||
248 | 389 | |||
249 | 390 | auto dev = device(); | ||
250 | 391 | libinput_device_config_accel_set_speed(dev, settings.cursor_acceleration_bias); | ||
251 | 392 | libinput_device_config_left_handed_set(dev, mir_pointer_handedness_left == settings.handedness); | ||
252 | 393 | vertical_scroll_scale = settings.vertical_scroll_scale; | ||
253 | 394 | horizontal_scroll_scale = settings.horizontal_scroll_scale; | ||
254 | 395 | } | ||
255 | 363 | 396 | ||
256 | === modified file 'src/platforms/evdev/libinput_device.h' | |||
257 | --- src/platforms/evdev/libinput_device.h 2015-10-07 15:32:10 +0000 | |||
258 | +++ src/platforms/evdev/libinput_device.h 2015-10-19 10:46:25 +0000 | |||
259 | @@ -54,6 +54,8 @@ | |||
260 | 54 | void start(InputSink* sink, EventBuilder* builder) override; | 54 | void start(InputSink* sink, EventBuilder* builder) override; |
261 | 55 | void stop() override; | 55 | void stop() override; |
262 | 56 | InputDeviceInfo get_device_info() override; | 56 | InputDeviceInfo get_device_info() override; |
263 | 57 | mir::optional_value<PointerSettings> get_pointer_settings() const override; | ||
264 | 58 | void apply_settings(PointerSettings const&) override; | ||
265 | 57 | 59 | ||
266 | 58 | void process_event(libinput_event* event); | 60 | void process_event(libinput_event* event); |
267 | 59 | ::libinput_device* device() const; | 61 | ::libinput_device* device() const; |
268 | @@ -86,6 +88,8 @@ | |||
269 | 86 | mir::geometry::Point pointer_pos; | 88 | mir::geometry::Point pointer_pos; |
270 | 87 | MirInputEventModifiers modifier_state; | 89 | MirInputEventModifiers modifier_state; |
271 | 88 | MirPointerButtons button_state; | 90 | MirPointerButtons button_state; |
272 | 91 | double vertical_scroll_scale{1.0}; | ||
273 | 92 | double horizontal_scroll_scale{1.0}; | ||
274 | 89 | 93 | ||
275 | 90 | struct ContactData | 94 | struct ContactData |
276 | 91 | { | 95 | { |
277 | 92 | 96 | ||
278 | === modified file 'src/platforms/mesa/server/x11/input/input_device.cpp' | |||
279 | --- src/platforms/mesa/server/x11/input/input_device.cpp 2015-09-01 07:41:29 +0000 | |||
280 | +++ src/platforms/mesa/server/x11/input/input_device.cpp 2015-10-19 10:46:25 +0000 | |||
281 | @@ -16,8 +16,11 @@ | |||
282 | 16 | * Authored by: Cemil Azizoglu <cemil.azizoglu@canonical.com> | 16 | * Authored by: Cemil Azizoglu <cemil.azizoglu@canonical.com> |
283 | 17 | */ | 17 | */ |
284 | 18 | 18 | ||
285 | 19 | #include "input_device.h" | ||
286 | 20 | |||
287 | 21 | #include "mir/input/pointer_settings.h" | ||
288 | 19 | #include "mir/input/input_device_info.h" | 22 | #include "mir/input/input_device_info.h" |
290 | 20 | #include "input_device.h" | 23 | #include "mir/input/device_capability.h" |
291 | 21 | 24 | ||
292 | 22 | namespace mi = mir::input; | 25 | namespace mi = mir::input; |
293 | 23 | namespace mix = mi::X; | 26 | namespace mix = mi::X; |
294 | @@ -43,3 +46,17 @@ | |||
295 | 43 | { | 46 | { |
296 | 44 | return info; | 47 | return info; |
297 | 45 | } | 48 | } |
298 | 49 | |||
299 | 50 | mir::optional_value<mi::PointerSettings> mix::XInputDevice::get_pointer_settings() const | ||
300 | 51 | { | ||
301 | 52 | mir::optional_value<PointerSettings> ret; | ||
302 | 53 | if (contains(info.capabilities, DeviceCapability::pointer)) | ||
303 | 54 | ret = PointerSettings(); | ||
304 | 55 | |||
305 | 56 | return ret; | ||
306 | 57 | } | ||
307 | 58 | |||
308 | 59 | void mix::XInputDevice::apply_settings(PointerSettings const&) | ||
309 | 60 | { | ||
310 | 61 | // TODO Make use if X11-XInput2 | ||
311 | 62 | } | ||
312 | 46 | 63 | ||
313 | === modified file 'src/platforms/mesa/server/x11/input/input_device.h' | |||
314 | --- src/platforms/mesa/server/x11/input/input_device.h 2015-09-01 07:41:29 +0000 | |||
315 | +++ src/platforms/mesa/server/x11/input/input_device.h 2015-10-19 10:46:25 +0000 | |||
316 | @@ -21,6 +21,7 @@ | |||
317 | 21 | 21 | ||
318 | 22 | #include "mir/input/input_device.h" | 22 | #include "mir/input/input_device.h" |
319 | 23 | #include "mir/input/input_device_info.h" | 23 | #include "mir/input/input_device_info.h" |
320 | 24 | #include "mir/optional_value.h" | ||
321 | 24 | 25 | ||
322 | 25 | namespace mir | 26 | namespace mir |
323 | 26 | { | 27 | { |
324 | @@ -40,6 +41,9 @@ | |||
325 | 40 | void stop() override; | 41 | void stop() override; |
326 | 41 | InputDeviceInfo get_device_info() override; | 42 | InputDeviceInfo get_device_info() override; |
327 | 42 | 43 | ||
328 | 44 | mir::optional_value<PointerSettings> get_pointer_settings() const override; | ||
329 | 45 | void apply_settings(PointerSettings const& settings) override; | ||
330 | 46 | |||
331 | 43 | InputSink* sink{nullptr}; | 47 | InputSink* sink{nullptr}; |
332 | 44 | EventBuilder* builder{nullptr}; | 48 | EventBuilder* builder{nullptr}; |
333 | 45 | private: | 49 | private: |
334 | 46 | 50 | ||
335 | === modified file 'tests/include/mir/test/gmock_fixes.h' | |||
336 | --- tests/include/mir/test/gmock_fixes.h 2015-08-27 05:59:27 +0000 | |||
337 | +++ tests/include/mir/test/gmock_fixes.h 2015-10-19 10:46:25 +0000 | |||
338 | @@ -142,6 +142,29 @@ | |||
339 | 142 | } | 142 | } |
340 | 143 | }; | 143 | }; |
341 | 144 | 144 | ||
342 | 145 | template<typename T, typename D> | ||
343 | 146 | class DefaultValue<std::unique_ptr<T, D>> { | ||
344 | 147 | public: | ||
345 | 148 | // Unsets the default value for type T. | ||
346 | 149 | static void Clear() {} | ||
347 | 150 | |||
348 | 151 | // Returns true if the user has set the default value for type T. | ||
349 | 152 | static bool IsSet() { return false; } | ||
350 | 153 | |||
351 | 154 | // Returns true if T has a default return value set by the user or there | ||
352 | 155 | // exists a built-in default value. | ||
353 | 156 | static bool Exists() { | ||
354 | 157 | return true; | ||
355 | 158 | } | ||
356 | 159 | |||
357 | 160 | // Returns the default value for type T if the user has set one; | ||
358 | 161 | // otherwise returns the built-in default value if there is one; | ||
359 | 162 | // otherwise aborts the process. | ||
360 | 163 | static std::unique_ptr<T, D> Get() { | ||
361 | 164 | return std::unique_ptr<T, D>(); | ||
362 | 165 | } | ||
363 | 166 | }; | ||
364 | 167 | |||
365 | 145 | 168 | ||
366 | 146 | 169 | ||
367 | 147 | } | 170 | } |
368 | 148 | 171 | ||
369 | === modified file 'tests/mir_test_framework/fake_input_device_impl.cpp' | |||
370 | --- tests/mir_test_framework/fake_input_device_impl.cpp 2015-10-12 08:08:58 +0000 | |||
371 | +++ tests/mir_test_framework/fake_input_device_impl.cpp 2015-10-19 10:46:25 +0000 | |||
372 | @@ -22,9 +22,11 @@ | |||
373 | 22 | #include "mir/input/input_device.h" | 22 | #include "mir/input/input_device.h" |
374 | 23 | #include "mir/input/input_device_info.h" | 23 | #include "mir/input/input_device_info.h" |
375 | 24 | #include "mir/input/input_sink.h" | 24 | #include "mir/input/input_sink.h" |
376 | 25 | #include "mir/input/pointer_settings.h" | ||
377 | 25 | #include "mir/input/event_builder.h" | 26 | #include "mir/input/event_builder.h" |
378 | 26 | #include "mir/dispatch/action_queue.h" | 27 | #include "mir/dispatch/action_queue.h" |
379 | 27 | #include "mir/geometry/displacement.h" | 28 | #include "mir/geometry/displacement.h" |
380 | 29 | #include "mir/module_deleter.h" | ||
381 | 28 | #include "src/platforms/evdev/input_modifier_utils.h" | 30 | #include "src/platforms/evdev/input_modifier_utils.h" |
382 | 29 | 31 | ||
383 | 30 | #include "boost/throw_exception.hpp" | 32 | #include "boost/throw_exception.hpp" |
384 | @@ -117,7 +119,7 @@ | |||
385 | 117 | { | 119 | { |
386 | 118 | auto event_time = std::chrono::duration_cast<std::chrono::nanoseconds>( | 120 | auto event_time = std::chrono::duration_cast<std::chrono::nanoseconds>( |
387 | 119 | std::chrono::system_clock::now().time_since_epoch()); | 121 | std::chrono::system_clock::now().time_since_epoch()); |
389 | 120 | auto action = update_buttons(button.action, mie::to_pointer_button(button.button)); | 122 | auto action = update_buttons(button.action, mie::to_pointer_button(button.button, settings.handedness)); |
390 | 121 | auto event_modifiers = mie::expand_modifiers(modifiers); | 123 | auto event_modifiers = mie::expand_modifiers(modifiers); |
391 | 122 | auto button_event = builder->pointer_event(event_time, | 124 | auto button_event = builder->pointer_event(event_time, |
392 | 123 | event_modifiers, | 125 | event_modifiers, |
393 | @@ -157,7 +159,14 @@ | |||
394 | 157 | auto event_time = std::chrono::duration_cast<std::chrono::nanoseconds>( | 159 | auto event_time = std::chrono::duration_cast<std::chrono::nanoseconds>( |
395 | 158 | std::chrono::system_clock::now().time_since_epoch()); | 160 | std::chrono::system_clock::now().time_since_epoch()); |
396 | 159 | auto event_modifiers = mie::expand_modifiers(modifiers); | 161 | auto event_modifiers = mie::expand_modifiers(modifiers); |
398 | 160 | update_position(pointer.rel_x, pointer.rel_y); | 162 | // constant scaling is used here to simplify checking for the |
399 | 163 | // expected results. Default settings of the device lead to no | ||
400 | 164 | // scaling at all. | ||
401 | 165 | auto acceleration = (settings.cursor_acceleration_bias + 1.0); | ||
402 | 166 | auto rel_x = pointer.rel_x * acceleration; | ||
403 | 167 | auto rel_y = pointer.rel_y * acceleration; | ||
404 | 168 | |||
405 | 169 | update_position(rel_x, rel_y); | ||
406 | 161 | auto pointer_event = builder->pointer_event(event_time, | 170 | auto pointer_event = builder->pointer_event(event_time, |
407 | 162 | event_modifiers, | 171 | event_modifiers, |
408 | 163 | mir_pointer_action_motion, | 172 | mir_pointer_action_motion, |
409 | @@ -166,8 +175,8 @@ | |||
410 | 166 | pos.y.as_float(), | 175 | pos.y.as_float(), |
411 | 167 | scroll.x.as_float(), | 176 | scroll.x.as_float(), |
412 | 168 | scroll.y.as_float(), | 177 | scroll.y.as_float(), |
415 | 169 | pointer.rel_x, | 178 | rel_x, |
416 | 170 | pointer.rel_y); | 179 | rel_y); |
417 | 171 | 180 | ||
418 | 172 | sink->handle_input(*pointer_event); | 181 | sink->handle_input(*pointer_event); |
419 | 173 | } | 182 | } |
420 | @@ -220,6 +229,23 @@ | |||
421 | 220 | sink->handle_input(*touch_event); | 229 | sink->handle_input(*touch_event); |
422 | 221 | } | 230 | } |
423 | 222 | 231 | ||
424 | 232 | mir::optional_value<mi::PointerSettings> mtf::FakeInputDeviceImpl::InputDevice::get_pointer_settings() const | ||
425 | 233 | { | ||
426 | 234 | mir::optional_value<mi::PointerSettings> ret; | ||
427 | 235 | if (!contains(info.capabilities, mi::DeviceCapability::pointer)) | ||
428 | 236 | return ret; | ||
429 | 237 | |||
430 | 238 | ret = mi::PointerSettings(); | ||
431 | 239 | return ret; | ||
432 | 240 | } | ||
433 | 241 | |||
434 | 242 | void mtf::FakeInputDeviceImpl::InputDevice::apply_settings(mi::PointerSettings const& settings) | ||
435 | 243 | { | ||
436 | 244 | if (!contains(info.capabilities, mi::DeviceCapability::pointer)) | ||
437 | 245 | return; | ||
438 | 246 | this->settings = settings; | ||
439 | 247 | } | ||
440 | 248 | |||
441 | 223 | void mtf::FakeInputDeviceImpl::InputDevice::map_touch_coordinates(float& x, float& y) | 249 | void mtf::FakeInputDeviceImpl::InputDevice::map_touch_coordinates(float& x, float& y) |
442 | 224 | { | 250 | { |
443 | 225 | // TODO take orientation of input sink into account? | 251 | // TODO take orientation of input sink into account? |
444 | 226 | 252 | ||
445 | === modified file 'tests/mir_test_framework/fake_input_device_impl.h' | |||
446 | --- tests/mir_test_framework/fake_input_device_impl.h 2015-09-01 07:41:29 +0000 | |||
447 | +++ tests/mir_test_framework/fake_input_device_impl.h 2015-10-19 10:46:25 +0000 | |||
448 | @@ -22,6 +22,7 @@ | |||
449 | 22 | #include "mir_test_framework/fake_input_device.h" | 22 | #include "mir_test_framework/fake_input_device.h" |
450 | 23 | 23 | ||
451 | 24 | #include "mir/input/input_device.h" | 24 | #include "mir/input/input_device.h" |
452 | 25 | #include "mir/input/pointer_settings.h" | ||
453 | 25 | #include "mir/input/input_device_info.h" | 26 | #include "mir/input/input_device_info.h" |
454 | 26 | #include "mir/geometry/point.h" | 27 | #include "mir/geometry/point.h" |
455 | 27 | 28 | ||
456 | @@ -64,6 +65,9 @@ | |||
457 | 64 | return info; | 65 | return info; |
458 | 65 | } | 66 | } |
459 | 66 | 67 | ||
460 | 68 | mir::optional_value<mir::input::PointerSettings> get_pointer_settings() const override; | ||
461 | 69 | void apply_settings(mir::input::PointerSettings const& settings) override; | ||
462 | 70 | |||
463 | 67 | private: | 71 | private: |
464 | 68 | MirPointerAction update_buttons(synthesis::EventAction action, MirPointerButton button); | 72 | MirPointerAction update_buttons(synthesis::EventAction action, MirPointerButton button); |
465 | 69 | void update_position(int rel_x, int rel_y); | 73 | void update_position(int rel_x, int rel_y); |
466 | @@ -76,6 +80,7 @@ | |||
467 | 76 | uint32_t modifiers{0}; | 80 | uint32_t modifiers{0}; |
468 | 77 | mir::geometry::Point pos, scroll; | 81 | mir::geometry::Point pos, scroll; |
469 | 78 | MirPointerButtons buttons; | 82 | MirPointerButtons buttons; |
470 | 83 | mir::input::PointerSettings settings; | ||
471 | 79 | }; | 84 | }; |
472 | 80 | std::shared_ptr<mir::dispatch::ActionQueue> queue; | 85 | std::shared_ptr<mir::dispatch::ActionQueue> queue; |
473 | 81 | std::shared_ptr<InputDevice> device; | 86 | std::shared_ptr<InputDevice> device; |
474 | 82 | 87 | ||
475 | === modified file 'tests/unit-tests/input/evdev/test_libinput_device.cpp' | |||
476 | --- tests/unit-tests/input/evdev/test_libinput_device.cpp 2015-10-07 16:41:50 +0000 | |||
477 | +++ tests/unit-tests/input/evdev/test_libinput_device.cpp 2015-10-19 10:46:25 +0000 | |||
478 | @@ -22,6 +22,7 @@ | |||
479 | 22 | 22 | ||
480 | 23 | #include "mir/input/input_device_registry.h" | 23 | #include "mir/input/input_device_registry.h" |
481 | 24 | #include "mir/input/input_sink.h" | 24 | #include "mir/input/input_sink.h" |
482 | 25 | #include "mir/input/pointer_settings.h" | ||
483 | 25 | #include "mir/geometry/point.h" | 26 | #include "mir/geometry/point.h" |
484 | 26 | #include "mir/geometry/rectangle.h" | 27 | #include "mir/geometry/rectangle.h" |
485 | 27 | #include "mir/test/event_matchers.h" | 28 | #include "mir/test/event_matchers.h" |
486 | @@ -159,12 +160,12 @@ | |||
487 | 159 | mock_libinput.setup_device(fake_input, dev, device_path, umock_name, vendor_id, product_id); | 160 | mock_libinput.setup_device(fake_input, dev, device_path, umock_name, vendor_id, product_id); |
488 | 160 | } | 161 | } |
489 | 161 | 162 | ||
491 | 162 | void setup_pointer_configuration(libinput_device* dev, double accel_speed, MirPointerButton primary) | 163 | void setup_pointer_configuration(libinput_device* dev, double accel_speed, MirPointerHandedness handedness) |
492 | 163 | { | 164 | { |
493 | 164 | EXPECT_CALL(mock_libinput, libinput_device_config_accel_get_speed(dev)) | 165 | EXPECT_CALL(mock_libinput, libinput_device_config_accel_get_speed(dev)) |
494 | 165 | .WillRepeatedly(Return(accel_speed)); | 166 | .WillRepeatedly(Return(accel_speed)); |
495 | 166 | EXPECT_CALL(mock_libinput, libinput_device_config_left_handed_get(dev)) | 167 | EXPECT_CALL(mock_libinput, libinput_device_config_left_handed_get(dev)) |
497 | 167 | .WillRepeatedly(Return(primary == mir_pointer_button_secondary)); | 168 | .WillRepeatedly(Return(handedness == mir_pointer_handedness_left)); |
498 | 168 | } | 169 | } |
499 | 169 | 170 | ||
500 | 170 | void setup_key_event(libinput_event* event, uint64_t event_time, uint32_t key, libinput_key_state state) | 171 | void setup_key_event(libinput_event* event, uint64_t event_time, uint32_t key, libinput_key_state state) |
501 | @@ -318,7 +319,7 @@ | |||
502 | 318 | std::shared_ptr<libinput> lib = mie::make_libinput(); | 319 | std::shared_ptr<libinput> lib = mie::make_libinput(); |
503 | 319 | char const* second_dev = "/dev/input/event13"; | 320 | char const* second_dev = "/dev/input/event13"; |
504 | 320 | char const* second_umock_dev_name = "bluetooth-magic-trackpad"; | 321 | char const* second_umock_dev_name = "bluetooth-magic-trackpad"; |
506 | 321 | 322 | ||
507 | 322 | setup_device(second_fake_device, second_dev, second_umock_dev_name, 9663, 1234); | 323 | setup_device(second_fake_device, second_dev, second_umock_dev_name, 9663, 1234); |
508 | 323 | 324 | ||
509 | 324 | InSequence seq; | 325 | InSequence seq; |
510 | @@ -341,7 +342,7 @@ | |||
511 | 341 | std::shared_ptr<libinput> lib = mie::make_libinput(); | 342 | std::shared_ptr<libinput> lib = mie::make_libinput(); |
512 | 342 | char const* second_dev = "/dev/input/event13"; | 343 | char const* second_dev = "/dev/input/event13"; |
513 | 343 | char const* second_umock_dev_name = "bluetooth-magic-trackpad"; | 344 | char const* second_umock_dev_name = "bluetooth-magic-trackpad"; |
515 | 344 | 345 | ||
516 | 345 | setup_device(second_fake_device, second_dev, second_umock_dev_name, 9663, 1234); | 346 | setup_device(second_fake_device, second_dev, second_umock_dev_name, 9663, 1234); |
517 | 346 | 347 | ||
518 | 347 | mie::LibInputDevice dev(mir::report::null_input_report(), | 348 | mie::LibInputDevice dev(mir::report::null_input_report(), |
519 | @@ -595,3 +596,113 @@ | |||
520 | 595 | dev.process_event(fake_event_3); | 596 | dev.process_event(fake_event_3); |
521 | 596 | dev.process_event(fake_event_4); | 597 | dev.process_event(fake_event_4); |
522 | 597 | } | 598 | } |
523 | 599 | |||
524 | 600 | TEST_F(LibInputDevice, provides_no_pointer_settings_for_non_pointing_devices) | ||
525 | 601 | { | ||
526 | 602 | char const keyboard_name[] = "usb-keyboard"; | ||
527 | 603 | char const keyboard_device_path[] = "/dev/input/event14"; | ||
528 | 604 | setup_device(second_fake_device, keyboard_device_path, keyboard_name, 1231, 4124); | ||
529 | 605 | |||
530 | 606 | std::shared_ptr<libinput> lib = mie::make_libinput(); | ||
531 | 607 | mie::LibInputDevice dev(mir::report::null_input_report(), keyboard_device_path, mie::make_libinput_device(lib.get(), keyboard_device_path)); | ||
532 | 608 | |||
533 | 609 | auto ptr = dev.get_pointer_settings(); | ||
534 | 610 | EXPECT_THAT(ptr.is_set(), Eq(false)); | ||
535 | 611 | } | ||
536 | 612 | |||
537 | 613 | TEST_F(LibInputDevice, reads_pointer_settings_from_libinput) | ||
538 | 614 | { | ||
539 | 615 | char const mouse_device_path[] = "/dev/input/event13"; | ||
540 | 616 | char const mouse_name[] = "usb-mouse"; | ||
541 | 617 | setup_device(second_fake_device, mouse_device_path, mouse_name, 1231, 4124); | ||
542 | 618 | |||
543 | 619 | std::shared_ptr<libinput> lib = mie::make_libinput(); | ||
544 | 620 | mie::LibInputDevice dev(mir::report::null_input_report(), mouse_device_path, mie::make_libinput_device(lib.get(), mouse_device_path)); | ||
545 | 621 | |||
546 | 622 | setup_pointer_configuration(dev.device(), 1, mir_pointer_handedness_right); | ||
547 | 623 | auto optional_settings = dev.get_pointer_settings(); | ||
548 | 624 | |||
549 | 625 | EXPECT_THAT(optional_settings.is_set(), Eq(true)); | ||
550 | 626 | |||
551 | 627 | auto ptr_settings = optional_settings.value(); | ||
552 | 628 | EXPECT_THAT(ptr_settings.handedness, Eq(mir_pointer_handedness_right)); | ||
553 | 629 | EXPECT_THAT(ptr_settings.cursor_acceleration_bias, Eq(1.0)); | ||
554 | 630 | EXPECT_THAT(ptr_settings.horizontal_scroll_scale, Eq(1.0)); | ||
555 | 631 | EXPECT_THAT(ptr_settings.vertical_scroll_scale, Eq(1.0)); | ||
556 | 632 | |||
557 | 633 | setup_pointer_configuration(dev.device(), 0.0, mir_pointer_handedness_left); | ||
558 | 634 | optional_settings = dev.get_pointer_settings(); | ||
559 | 635 | |||
560 | 636 | EXPECT_THAT(optional_settings.is_set(), Eq(true)); | ||
561 | 637 | |||
562 | 638 | ptr_settings = optional_settings.value(); | ||
563 | 639 | EXPECT_THAT(ptr_settings.handedness, Eq(mir_pointer_handedness_left)); | ||
564 | 640 | EXPECT_THAT(ptr_settings.cursor_acceleration_bias, Eq(0.0)); | ||
565 | 641 | EXPECT_THAT(ptr_settings.horizontal_scroll_scale, Eq(1.0)); | ||
566 | 642 | EXPECT_THAT(ptr_settings.vertical_scroll_scale, Eq(1.0)); | ||
567 | 643 | } | ||
568 | 644 | |||
569 | 645 | TEST_F(LibInputDevice, applies_pointer_settings) | ||
570 | 646 | { | ||
571 | 647 | char const mouse_device_path[] = "/dev/input/event13"; | ||
572 | 648 | char const mouse_name[] = "usb-mouse"; | ||
573 | 649 | setup_device(second_fake_device, mouse_device_path, mouse_name, 1231, 4124); | ||
574 | 650 | |||
575 | 651 | std::shared_ptr<libinput> lib = mie::make_libinput(); | ||
576 | 652 | mie::LibInputDevice dev(mir::report::null_input_report(), mouse_device_path, mie::make_libinput_device(lib.get(), path)); | ||
577 | 653 | |||
578 | 654 | setup_pointer_configuration(dev.device(), 1, mir_pointer_handedness_right); | ||
579 | 655 | mi::PointerSettings settings(dev.get_pointer_settings().value()); | ||
580 | 656 | settings.cursor_acceleration_bias = 1.1; | ||
581 | 657 | settings.handedness = mir_pointer_handedness_left; | ||
582 | 658 | |||
583 | 659 | EXPECT_CALL(mock_libinput,libinput_device_config_accel_set_speed(dev.device(), 1.1)).Times(1); | ||
584 | 660 | EXPECT_CALL(mock_libinput,libinput_device_config_left_handed_set(dev.device(), true)).Times(1); | ||
585 | 661 | |||
586 | 662 | dev.apply_settings(settings); | ||
587 | 663 | } | ||
588 | 664 | |||
589 | 665 | TEST_F(LibInputDevice, denies_pointer_settings_on_keyboards) | ||
590 | 666 | { | ||
591 | 667 | char const mouse_device_path[] = "/dev/input/event13"; | ||
592 | 668 | char const mouse_name[] = "usb-mouse"; | ||
593 | 669 | setup_device(second_fake_device, mouse_device_path, mouse_name, 1231, 4124); | ||
594 | 670 | |||
595 | 671 | std::shared_ptr<libinput> lib = mie::make_libinput(); | ||
596 | 672 | mie::LibInputDevice keyboard_dev(mir::report::null_input_report(), path, mie::make_libinput_device(lib.get(), path)); | ||
597 | 673 | mie::LibInputDevice mouse_dev(mir::report::null_input_report(), mouse_device_path, mie::make_libinput_device(lib.get(), path)); | ||
598 | 674 | |||
599 | 675 | auto settings_from_mouse = mouse_dev.get_pointer_settings(); | ||
600 | 676 | |||
601 | 677 | EXPECT_CALL(mock_libinput,libinput_device_config_accel_set_speed(_, _)).Times(0); | ||
602 | 678 | EXPECT_CALL(mock_libinput,libinput_device_config_left_handed_set(_, _)).Times(0); | ||
603 | 679 | |||
604 | 680 | keyboard_dev.apply_settings(settings_from_mouse.value()); | ||
605 | 681 | } | ||
606 | 682 | |||
607 | 683 | TEST_F(LibInputDevice, scroll_speed_scales_scroll_events) | ||
608 | 684 | { | ||
609 | 685 | char const mouse_device_path[] = "/dev/input/event13"; | ||
610 | 686 | char const mouse_name[] = "usb-mouse"; | ||
611 | 687 | setup_device(second_fake_device, mouse_device_path, mouse_name, 1231, 4124); | ||
612 | 688 | |||
613 | 689 | std::shared_ptr<libinput> lib = mie::make_libinput(); | ||
614 | 690 | mie::LibInputDevice dev(mir::report::null_input_report(), mouse_device_path, mie::make_libinput_device(lib.get(), mouse_device_path)); | ||
615 | 691 | |||
616 | 692 | setup_axis_event(fake_event_1, event_time_1, 0.0, 3.0); | ||
617 | 693 | setup_axis_event(fake_event_2, event_time_2, -2.0, 0.0); | ||
618 | 694 | |||
619 | 695 | // expect two scroll events.. | ||
620 | 696 | EXPECT_CALL(mock_sink, handle_input(mt::PointerAxisChange(mir_pointer_axis_vscroll, -3.0f))); | ||
621 | 697 | EXPECT_CALL(mock_sink, handle_input(mt::PointerAxisChange(mir_pointer_axis_hscroll, -10.0f))); | ||
622 | 698 | |||
623 | 699 | setup_pointer_configuration(dev.device(), 1, mir_pointer_handedness_right); | ||
624 | 700 | mi::PointerSettings settings(dev.get_pointer_settings().value()); | ||
625 | 701 | settings.vertical_scroll_scale = -1.0; | ||
626 | 702 | settings.horizontal_scroll_scale = 5.0; | ||
627 | 703 | dev.apply_settings(settings); | ||
628 | 704 | |||
629 | 705 | dev.start(&mock_sink, &mock_builder); | ||
630 | 706 | dev.process_event(fake_event_1); | ||
631 | 707 | dev.process_event(fake_event_2); | ||
632 | 708 | } | ||
633 | 598 | 709 | ||
634 | === modified file 'tests/unit-tests/input/test_default_input_device_hub.cpp' | |||
635 | --- tests/unit-tests/input/test_default_input_device_hub.cpp 2015-10-07 16:41:50 +0000 | |||
636 | +++ tests/unit-tests/input/test_default_input_device_hub.cpp 2015-10-19 10:46:25 +0000 | |||
637 | @@ -25,6 +25,7 @@ | |||
638 | 25 | #include "mir/test/event_matchers.h" | 25 | #include "mir/test/event_matchers.h" |
639 | 26 | 26 | ||
640 | 27 | #include "mir/input/input_device.h" | 27 | #include "mir/input/input_device.h" |
641 | 28 | #include "mir/input/pointer_settings.h" | ||
642 | 28 | #include "mir/input/device.h" | 29 | #include "mir/input/device.h" |
643 | 29 | #include "mir/input/touch_visualizer.h" | 30 | #include "mir/input/touch_visualizer.h" |
644 | 30 | #include "mir/input/input_device_observer.h" | 31 | #include "mir/input/input_device_observer.h" |
645 | @@ -85,6 +86,8 @@ | |||
646 | 85 | MOCK_METHOD2(start, void(mi::InputSink* destination, mi::EventBuilder* builder)); | 86 | MOCK_METHOD2(start, void(mi::InputSink* destination, mi::EventBuilder* builder)); |
647 | 86 | MOCK_METHOD0(stop, void()); | 87 | MOCK_METHOD0(stop, void()); |
648 | 87 | MOCK_METHOD0(get_device_info, mi::InputDeviceInfo()); | 88 | MOCK_METHOD0(get_device_info, mi::InputDeviceInfo()); |
649 | 89 | MOCK_CONST_METHOD0(get_pointer_settings, mir::optional_value<mi::PointerSettings>()); | ||
650 | 90 | MOCK_METHOD1(apply_settings, void(mi::PointerSettings const&)); | ||
651 | 88 | }; | 91 | }; |
652 | 89 | 92 | ||
653 | 90 | template<typename Type> | 93 | template<typename Type> |
FAILED: Continuous integration, rev:2968 jenkins. qa.ubuntu. com/job/ mir-ci/ 5034/ jenkins. qa.ubuntu. com/job/ mir-android- vivid-i386- build/4144 jenkins. qa.ubuntu. com/job/ mir-clang- vivid-amd64- build/3051 jenkins. qa.ubuntu. com/job/ mir-mediumtests -vivid- touch/4086/ console jenkins. qa.ubuntu. com/job/ mir-mediumtests -wily-touch/ 44/console jenkins. qa.ubuntu. com/job/ mir-wily- amd64-ci/ 1185/console jenkins. qa.ubuntu. com/job/ mir-wily- i386-ci/ 44/console jenkins. qa.ubuntu. com/job/ mir-mediumtests -builder- vivid-armhf/ 4087/console jenkins. qa.ubuntu. com/job/ mir-mediumtests -builder- wily-armhf/ 45/console
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
FAILURE: http://
None: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
None: http://
Click here to trigger a rebuild: s-jenkins. ubuntu- ci:8080/ job/mir- ci/5034/ rebuild
http://