Mir

Merge lp:~andreas-pokorny/mir/libinput-platform-pointer-settings into lp:mir

Proposed by Andreas Pokorny
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
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/right-hand button ordering for all pointing devices.

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

To post a comment you must log in.
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: Approve (continuous-integration)
Revision history for this message
Alexandros Frantzis (afrantzis) wrote :

+ virtual UniqueModulePtr<PointerSettings> get_pointer_settings() const = 0;

Why do we want PointerSettings to keep the module alive?
I would expect just:

PointerSettings get_pointer_settings() const = 0

review: Needs Information
Revision history for this message
Alan Griffiths (alan-griffiths) wrote :
Revision history for this message
Alan Griffiths (alan-griffiths) wrote :

> + virtual UniqueModulePtr<PointerSettings> get_pointer_settings() const = 0;
>
> Why do we want PointerSettings to keep the module alive?

+1

review: Needs Information
Revision history for this message
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<PointerSettings> instead.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
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)...

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

yeah.. this needs fixing

review: Needs Fixing
Revision history for this message
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)]

review: Abstain
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
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()?

review: Needs Fixing
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 :

> + 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::(experimental::)optional. Looking at how we implemented it, I should change the above to be more in line with what mir::optional_value<...>::value() does. Fixing that.

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

> To be closer to std::(experimental::)optional. Looking at how we implemented

mir optional_value is a different design to std::(experimental::)optional - making them look more alike is probably a bad idea.

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

> > To be closer to std::(experimental::)optional. Looking at how we implemented
>
> mir optional_value is a different design to std::(experimental::)optional -
> 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.

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

/mir/include/common/mir/optional_value.h:31:45: error: no viable conversion from 'const mir::input::PointerSettings' to 'MirPointerButton'
    optional_value(T const& value) : value_{value}, is_set_{true} {}

+ PointerSettings() {}

"Otherwise clang does not allow construction with {}"

I'm confused. We're in the optional_value<PointerSettings> converting constructor, are trying to construct a MirPointerButton(!) and this is solved by giving PointerSettings() a user-defined default constructor?
...
Oh! clang is trying to use aggregate initialization and that is defeated by adding any user-defined constructor.

review: Approve
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
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? :)

review: Needs Information
Revision history for this message
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.

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

Kay.... try to use "velocity" or "speed" if you're referring to the first derivative of position :)

review: Abstain
Revision history for this message
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.

review: Needs Information
Revision history for this message
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::cursor_speed is an adjustment[1] to this scaling function (and not a speed nor an acceleration).

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]?

Revision history for this message
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::cursor_speed is an adjustment[1] to this scaling function
> (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://wayland.freedesktop.org/libinput/doc/latest/ptraccel-linear.svg

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..

Revision history for this message
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)

review: Abstain
Revision history for this message
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_scroll_speed{1.0};
+ double vertical_scroll_speed{1.0};

/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_acceleration{0.0};

review: Needs Fixing
Revision history for this message
Alan Griffiths (alan-griffiths) wrote :

It would be more consistent with "horizontal_scroll_scale" to have "cursor_acceleration_bias", but these names do fit better with the explanation of "terms of art".

review: Approve
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 :

[1444835234.581027] mirserver: Stopping
/bin/bash: line 1: 6450 Segmentation fault mir_demo_server --test-client /usr/bin/mir_demo_client_basic

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
Andreas Pokorny (andreas-pokorny) wrote :

Resolving s-jenkins.ubuntu-ci (s-jenkins.ubuntu-ci)... 10.100.0.4
Connecting to s-jenkins.ubuntu-ci (s-jenkins.ubuntu-ci)|10.100.0.4|:8080... connected.
HTTP request sent, awaiting response... 500 Internal Server Error
2015-10-14 18:13:32 ERROR 500: Internal Server Error.

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

+ /**
+ * Configure left and right handed mode by selecting a primary button
+ * - mir_pointer_button_primary -> right handed
+ * - mir_pointer_button_secondary -> left handed
+ */
+ MirPointerButton primary_button{mir_pointer_button_primary};

Non-blocking: I think this would be better as an explicit mir_pointer_left_handed/mir_pointer_right_handed - in the case of those truly monstrous 112-button mice we might reasonably want to be able to switch more than just left-mouse-button and right-mouse-button.

Feel free to fix that, or not.

review: Approve
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: Approve (continuous-integration)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== added file 'include/client/mir_toolkit/mir_input_device.h'
--- include/client/mir_toolkit/mir_input_device.h 1970-01-01 00:00:00 +0000
+++ include/client/mir_toolkit/mir_input_device.h 2015-10-19 10:46:25 +0000
@@ -0,0 +1,39 @@
1/*
2 * Copyright © 2015 Canonical Ltd.
3 *
4 * This program is free software: you can redistribute it and/or modify it
5 * under the terms of the GNU Lesser General Public License version 3,
6 * as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 */
17
18#ifndef MIR_TOOLKIT_MIR_INPUT_DEVICE_H_
19#define MIR_TOOLKIT_MIR_INPUT_DEVICE_H_
20
21/**
22 * \addtogroup mir_toolkit
23 * @{
24 */
25#ifdef __cplusplus
26extern "C" {
27#endif
28
29typedef enum MirPointerHandedness
30{
31 mir_pointer_handedness_right = 0,
32 mir_pointer_handedness_left = 1
33} MirPointerHandedness;
34
35#ifdef __cplusplus
36}
37#endif
38
39#endif
040
=== modified file 'include/platform/mir/input/input_device.h'
--- include/platform/mir/input/input_device.h 2015-09-01 07:41:29 +0000
+++ include/platform/mir/input/input_device.h 2015-10-19 10:46:25 +0000
@@ -20,6 +20,9 @@
20#ifndef MIR_INPUT_INPUT_DEVICE_H_20#ifndef MIR_INPUT_INPUT_DEVICE_H_
21#define MIR_INPUT_INPUT_DEVICE_H_21#define MIR_INPUT_INPUT_DEVICE_H_
2222
23#include "mir/module_deleter.h"
24#include "mir/optional_value.h"
25
23#include <memory>26#include <memory>
2427
25namespace mir28namespace mir
@@ -34,6 +37,8 @@
34class InputDeviceInfo;37class InputDeviceInfo;
35class EventBuilder;38class EventBuilder;
3639
40class PointerSettings;
41
37/**42/**
38 * Represents an input device.43 * Represents an input device.
39 */44 */
@@ -54,6 +59,9 @@
5459
55 virtual InputDeviceInfo get_device_info() = 0;60 virtual InputDeviceInfo get_device_info() = 0;
5661
62 virtual mir::optional_value<PointerSettings> get_pointer_settings() const = 0;
63 virtual void apply_settings(PointerSettings const&) = 0;
64
57protected:65protected:
58 InputDevice(InputDevice const&) = delete;66 InputDevice(InputDevice const&) = delete;
59 InputDevice& operator=(InputDevice const&) = delete;67 InputDevice& operator=(InputDevice const&) = delete;
6068
=== added file 'include/platform/mir/input/pointer_settings.h'
--- include/platform/mir/input/pointer_settings.h 1970-01-01 00:00:00 +0000
+++ include/platform/mir/input/pointer_settings.h 2015-10-19 10:46:25 +0000
@@ -0,0 +1,58 @@
1/*
2 * Copyright © 2015 Canonical Ltd.
3 *
4 * This program is free software: you can redistribute it and/or modify it
5 * under the terms of the GNU Lesser General Public License version 3,
6 * as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authored by:
17 * Andreas Pokorny <andreas.pokorny@canonical.com>
18 */
19
20#ifndef MIR_INPUT_POINTER_SETTINGS_H_
21#define MIR_INPUT_POINTER_SETTINGS_H_
22
23#include "mir_toolkit/client_types.h"
24#include "mir_toolkit/mir_input_device.h"
25
26namespace mir
27{
28namespace input
29{
30
31struct PointerSettings
32{
33 PointerSettings() {}
34 /**
35 * Configure left and right handed mode by selecting a primary button
36 */
37 MirPointerHandedness handedness{mir_pointer_handedness_right};
38 /**
39 * Bias cursor acceleration.
40 * - [-1, 0): reduced acceleration
41 * - 0: default acceleration
42 * - (0, 1]: increased acceleration
43 */
44 double cursor_acceleration_bias{0.0};
45 /**
46 * Scale horizontal scrolling linearly
47 */
48 double horizontal_scroll_scale{1.0};
49 /**
50 * Scale vertical scrolling linearly
51 */
52 double vertical_scroll_scale{1.0};
53};
54
55}
56}
57
58#endif
059
=== modified file 'src/platforms/evdev/input_modifier_utils.cpp'
--- src/platforms/evdev/input_modifier_utils.cpp 2015-09-17 06:40:14 +0000
+++ src/platforms/evdev/input_modifier_utils.cpp 2015-10-19 10:46:25 +0000
@@ -27,12 +27,16 @@
2727
28namespace mie = mir::input::evdev;28namespace mie = mir::input::evdev;
2929
30MirPointerButton mie::to_pointer_button(int button)30MirPointerButton mie::to_pointer_button(int button, MirPointerHandedness handedness)
31{31{
32 switch(button)32 switch(button)
33 {33 {
34 case BTN_LEFT: return mir_pointer_button_primary;34 case BTN_LEFT: return (handedness == mir_pointer_handedness_right)
35 case BTN_RIGHT: return mir_pointer_button_secondary;35 ? mir_pointer_button_primary
36 : mir_pointer_button_secondary;
37 case BTN_RIGHT: return (handedness == mir_pointer_handedness_right)
38 ? mir_pointer_button_secondary
39 : mir_pointer_button_primary;
36 case BTN_MIDDLE: return mir_pointer_button_tertiary;40 case BTN_MIDDLE: return mir_pointer_button_tertiary;
37 case BTN_BACK: return mir_pointer_button_back;41 case BTN_BACK: return mir_pointer_button_back;
38 case BTN_FORWARD: return mir_pointer_button_forward;42 case BTN_FORWARD: return mir_pointer_button_forward;
3943
=== modified file 'src/platforms/evdev/input_modifier_utils.h'
--- src/platforms/evdev/input_modifier_utils.h 2015-09-17 06:40:14 +0000
+++ src/platforms/evdev/input_modifier_utils.h 2015-10-19 10:46:25 +0000
@@ -20,6 +20,7 @@
20#define MIR_INPUT_EVDEV_INPUT_MODIFIER_UTILS_H_20#define MIR_INPUT_EVDEV_INPUT_MODIFIER_UTILS_H_
2121
22#include "mir_toolkit/event.h"22#include "mir_toolkit/event.h"
23#include "mir_toolkit/mir_input_device.h"
2324
24namespace mir25namespace mir
25{26{
@@ -27,7 +28,7 @@
27{28{
28namespace evdev29namespace evdev
29{30{
30MirPointerButton to_pointer_button(int button);31MirPointerButton to_pointer_button(int button, MirPointerHandedness handedness);
31MirInputEventModifiers to_modifiers(int32_t scan_code);32MirInputEventModifiers to_modifiers(int32_t scan_code);
32MirInputEventModifiers expand_modifiers(MirInputEventModifiers modifiers);33MirInputEventModifiers expand_modifiers(MirInputEventModifiers modifiers);
33}34}
3435
=== modified file 'src/platforms/evdev/libinput_device.cpp'
--- src/platforms/evdev/libinput_device.cpp 2015-10-07 15:32:10 +0000
+++ src/platforms/evdev/libinput_device.cpp 2015-10-19 10:46:25 +0000
@@ -25,6 +25,7 @@
25#include "mir/input/input_sink.h"25#include "mir/input/input_sink.h"
26#include "mir/input/input_report.h"26#include "mir/input/input_report.h"
27#include "mir/input/device_capability.h"27#include "mir/input/device_capability.h"
28#include "mir/input/pointer_settings.h"
28#include "mir/input/input_device_info.h"29#include "mir/input/input_device_info.h"
29#include "mir/events/event_builders.h"30#include "mir/events/event_builders.h"
30#include "mir/geometry/displacement.h"31#include "mir/geometry/displacement.h"
@@ -159,7 +160,8 @@
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)?
160 mir_pointer_action_button_down : mir_pointer_action_button_up;161 mir_pointer_action_button_down : mir_pointer_action_button_up;
161162
162 auto const pointer_button = mie::to_pointer_button(button);163 auto const do_not_swap_buttons = mir_pointer_handedness_right;
164 auto const pointer_button = mie::to_pointer_button(button, do_not_swap_buttons);
163 auto const relative_x_value = 0.0f;165 auto const relative_x_value = 0.0f;
164 auto const relative_y_value = 0.0f;166 auto const relative_y_value = 0.0f;
165 auto const hscroll_value = 0.0f;167 auto const hscroll_value = 0.0f;
@@ -232,10 +234,12 @@
232 auto const relative_x_value = 0.0f;234 auto const relative_x_value = 0.0f;
233 auto const relative_y_value = 0.0f;235 auto const relative_y_value = 0.0f;
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)
235 ? libinput_event_pointer_get_axis_value(pointer, LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL)237 ? horizontal_scroll_scale * libinput_event_pointer_get_axis_value(pointer,
238 LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL)
236 : 0.0f;239 : 0.0f;
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)
238 ? libinput_event_pointer_get_axis_value(pointer, LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL)241 ? vertical_scroll_scale * libinput_event_pointer_get_axis_value(pointer,
242 LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL)
239 : 0.0f;243 : 0.0f;
240244
241 report->received_event_from_kernel(time.count(), EV_REL, 0, 0);245 report->received_event_from_kernel(time.count(), EV_REL, 0, 0);
@@ -360,3 +364,32 @@
360{364{
361 return devices.front().get();365 return devices.front().get();
362}366}
367
368mir::optional_value<mi::PointerSettings> mie::LibInputDevice::get_pointer_settings() const
369{
370 if (!contains(info.capabilities, mi::DeviceCapability::pointer))
371 return {};
372
373 auto dev = device();
374 auto accel_bias = libinput_device_config_accel_get_speed(dev);
375 auto left_handed = (libinput_device_config_left_handed_get(dev) == 1);
376
377 mi::PointerSettings settings;
378 settings.cursor_acceleration_bias = accel_bias;
379 settings.vertical_scroll_scale = vertical_scroll_scale;
380 settings.horizontal_scroll_scale = horizontal_scroll_scale;
381 settings.handedness = left_handed? mir_pointer_handedness_left : mir_pointer_handedness_right;
382 return settings;
383}
384
385void mie::LibInputDevice::apply_settings(mir::input::PointerSettings const& settings)
386{
387 if (!contains(info.capabilities, mi::DeviceCapability::pointer))
388 return;
389
390 auto dev = device();
391 libinput_device_config_accel_set_speed(dev, settings.cursor_acceleration_bias);
392 libinput_device_config_left_handed_set(dev, mir_pointer_handedness_left == settings.handedness);
393 vertical_scroll_scale = settings.vertical_scroll_scale;
394 horizontal_scroll_scale = settings.horizontal_scroll_scale;
395}
363396
=== modified file 'src/platforms/evdev/libinput_device.h'
--- src/platforms/evdev/libinput_device.h 2015-10-07 15:32:10 +0000
+++ src/platforms/evdev/libinput_device.h 2015-10-19 10:46:25 +0000
@@ -54,6 +54,8 @@
54 void start(InputSink* sink, EventBuilder* builder) override;54 void start(InputSink* sink, EventBuilder* builder) override;
55 void stop() override;55 void stop() override;
56 InputDeviceInfo get_device_info() override;56 InputDeviceInfo get_device_info() override;
57 mir::optional_value<PointerSettings> get_pointer_settings() const override;
58 void apply_settings(PointerSettings const&) override;
5759
58 void process_event(libinput_event* event);60 void process_event(libinput_event* event);
59 ::libinput_device* device() const;61 ::libinput_device* device() const;
@@ -86,6 +88,8 @@
86 mir::geometry::Point pointer_pos;88 mir::geometry::Point pointer_pos;
87 MirInputEventModifiers modifier_state;89 MirInputEventModifiers modifier_state;
88 MirPointerButtons button_state;90 MirPointerButtons button_state;
91 double vertical_scroll_scale{1.0};
92 double horizontal_scroll_scale{1.0};
8993
90 struct ContactData94 struct ContactData
91 {95 {
9296
=== modified file 'src/platforms/mesa/server/x11/input/input_device.cpp'
--- src/platforms/mesa/server/x11/input/input_device.cpp 2015-09-01 07:41:29 +0000
+++ src/platforms/mesa/server/x11/input/input_device.cpp 2015-10-19 10:46:25 +0000
@@ -16,8 +16,11 @@
16 * Authored by: Cemil Azizoglu <cemil.azizoglu@canonical.com>16 * Authored by: Cemil Azizoglu <cemil.azizoglu@canonical.com>
17 */17 */
1818
19#include "input_device.h"
20
21#include "mir/input/pointer_settings.h"
19#include "mir/input/input_device_info.h"22#include "mir/input/input_device_info.h"
20#include "input_device.h"23#include "mir/input/device_capability.h"
2124
22namespace mi = mir::input;25namespace mi = mir::input;
23namespace mix = mi::X;26namespace mix = mi::X;
@@ -43,3 +46,17 @@
43{46{
44 return info;47 return info;
45}48}
49
50mir::optional_value<mi::PointerSettings> mix::XInputDevice::get_pointer_settings() const
51{
52 mir::optional_value<PointerSettings> ret;
53 if (contains(info.capabilities, DeviceCapability::pointer))
54 ret = PointerSettings();
55
56 return ret;
57}
58
59void mix::XInputDevice::apply_settings(PointerSettings const&)
60{
61 // TODO Make use if X11-XInput2
62}
4663
=== modified file 'src/platforms/mesa/server/x11/input/input_device.h'
--- src/platforms/mesa/server/x11/input/input_device.h 2015-09-01 07:41:29 +0000
+++ src/platforms/mesa/server/x11/input/input_device.h 2015-10-19 10:46:25 +0000
@@ -21,6 +21,7 @@
2121
22#include "mir/input/input_device.h"22#include "mir/input/input_device.h"
23#include "mir/input/input_device_info.h"23#include "mir/input/input_device_info.h"
24#include "mir/optional_value.h"
2425
25namespace mir26namespace mir
26{27{
@@ -40,6 +41,9 @@
40 void stop() override;41 void stop() override;
41 InputDeviceInfo get_device_info() override;42 InputDeviceInfo get_device_info() override;
4243
44 mir::optional_value<PointerSettings> get_pointer_settings() const override;
45 void apply_settings(PointerSettings const& settings) override;
46
43 InputSink* sink{nullptr};47 InputSink* sink{nullptr};
44 EventBuilder* builder{nullptr};48 EventBuilder* builder{nullptr};
45private:49private:
4650
=== modified file 'tests/include/mir/test/gmock_fixes.h'
--- tests/include/mir/test/gmock_fixes.h 2015-08-27 05:59:27 +0000
+++ tests/include/mir/test/gmock_fixes.h 2015-10-19 10:46:25 +0000
@@ -142,6 +142,29 @@
142 }142 }
143};143};
144144
145template<typename T, typename D>
146class DefaultValue<std::unique_ptr<T, D>> {
147 public:
148 // Unsets the default value for type T.
149 static void Clear() {}
150
151 // Returns true if the user has set the default value for type T.
152 static bool IsSet() { return false; }
153
154 // Returns true if T has a default return value set by the user or there
155 // exists a built-in default value.
156 static bool Exists() {
157 return true;
158 }
159
160 // Returns the default value for type T if the user has set one;
161 // otherwise returns the built-in default value if there is one;
162 // otherwise aborts the process.
163 static std::unique_ptr<T, D> Get() {
164 return std::unique_ptr<T, D>();
165 }
166};
167
145168
146169
147}170}
148171
=== modified file 'tests/mir_test_framework/fake_input_device_impl.cpp'
--- tests/mir_test_framework/fake_input_device_impl.cpp 2015-10-12 08:08:58 +0000
+++ tests/mir_test_framework/fake_input_device_impl.cpp 2015-10-19 10:46:25 +0000
@@ -22,9 +22,11 @@
22#include "mir/input/input_device.h"22#include "mir/input/input_device.h"
23#include "mir/input/input_device_info.h"23#include "mir/input/input_device_info.h"
24#include "mir/input/input_sink.h"24#include "mir/input/input_sink.h"
25#include "mir/input/pointer_settings.h"
25#include "mir/input/event_builder.h"26#include "mir/input/event_builder.h"
26#include "mir/dispatch/action_queue.h"27#include "mir/dispatch/action_queue.h"
27#include "mir/geometry/displacement.h"28#include "mir/geometry/displacement.h"
29#include "mir/module_deleter.h"
28#include "src/platforms/evdev/input_modifier_utils.h"30#include "src/platforms/evdev/input_modifier_utils.h"
2931
30#include "boost/throw_exception.hpp"32#include "boost/throw_exception.hpp"
@@ -117,7 +119,7 @@
117{119{
118 auto event_time = std::chrono::duration_cast<std::chrono::nanoseconds>(120 auto event_time = std::chrono::duration_cast<std::chrono::nanoseconds>(
119 std::chrono::system_clock::now().time_since_epoch());121 std::chrono::system_clock::now().time_since_epoch());
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));
121 auto event_modifiers = mie::expand_modifiers(modifiers);123 auto event_modifiers = mie::expand_modifiers(modifiers);
122 auto button_event = builder->pointer_event(event_time,124 auto button_event = builder->pointer_event(event_time,
123 event_modifiers,125 event_modifiers,
@@ -157,7 +159,14 @@
157 auto event_time = std::chrono::duration_cast<std::chrono::nanoseconds>(159 auto event_time = std::chrono::duration_cast<std::chrono::nanoseconds>(
158 std::chrono::system_clock::now().time_since_epoch());160 std::chrono::system_clock::now().time_since_epoch());
159 auto event_modifiers = mie::expand_modifiers(modifiers);161 auto event_modifiers = mie::expand_modifiers(modifiers);
160 update_position(pointer.rel_x, pointer.rel_y);162 // constant scaling is used here to simplify checking for the
163 // expected results. Default settings of the device lead to no
164 // scaling at all.
165 auto acceleration = (settings.cursor_acceleration_bias + 1.0);
166 auto rel_x = pointer.rel_x * acceleration;
167 auto rel_y = pointer.rel_y * acceleration;
168
169 update_position(rel_x, rel_y);
161 auto pointer_event = builder->pointer_event(event_time,170 auto pointer_event = builder->pointer_event(event_time,
162 event_modifiers,171 event_modifiers,
163 mir_pointer_action_motion,172 mir_pointer_action_motion,
@@ -166,8 +175,8 @@
166 pos.y.as_float(),175 pos.y.as_float(),
167 scroll.x.as_float(),176 scroll.x.as_float(),
168 scroll.y.as_float(),177 scroll.y.as_float(),
169 pointer.rel_x,178 rel_x,
170 pointer.rel_y);179 rel_y);
171180
172 sink->handle_input(*pointer_event);181 sink->handle_input(*pointer_event);
173}182}
@@ -220,6 +229,23 @@
220 sink->handle_input(*touch_event);229 sink->handle_input(*touch_event);
221}230}
222231
232mir::optional_value<mi::PointerSettings> mtf::FakeInputDeviceImpl::InputDevice::get_pointer_settings() const
233{
234 mir::optional_value<mi::PointerSettings> ret;
235 if (!contains(info.capabilities, mi::DeviceCapability::pointer))
236 return ret;
237
238 ret = mi::PointerSettings();
239 return ret;
240}
241
242void mtf::FakeInputDeviceImpl::InputDevice::apply_settings(mi::PointerSettings const& settings)
243{
244 if (!contains(info.capabilities, mi::DeviceCapability::pointer))
245 return;
246 this->settings = settings;
247}
248
223void mtf::FakeInputDeviceImpl::InputDevice::map_touch_coordinates(float& x, float& y)249void mtf::FakeInputDeviceImpl::InputDevice::map_touch_coordinates(float& x, float& y)
224{250{
225 // TODO take orientation of input sink into account?251 // TODO take orientation of input sink into account?
226252
=== modified file 'tests/mir_test_framework/fake_input_device_impl.h'
--- tests/mir_test_framework/fake_input_device_impl.h 2015-09-01 07:41:29 +0000
+++ tests/mir_test_framework/fake_input_device_impl.h 2015-10-19 10:46:25 +0000
@@ -22,6 +22,7 @@
22#include "mir_test_framework/fake_input_device.h"22#include "mir_test_framework/fake_input_device.h"
2323
24#include "mir/input/input_device.h"24#include "mir/input/input_device.h"
25#include "mir/input/pointer_settings.h"
25#include "mir/input/input_device_info.h"26#include "mir/input/input_device_info.h"
26#include "mir/geometry/point.h"27#include "mir/geometry/point.h"
2728
@@ -64,6 +65,9 @@
64 return info;65 return info;
65 }66 }
6667
68 mir::optional_value<mir::input::PointerSettings> get_pointer_settings() const override;
69 void apply_settings(mir::input::PointerSettings const& settings) override;
70
67 private:71 private:
68 MirPointerAction update_buttons(synthesis::EventAction action, MirPointerButton button);72 MirPointerAction update_buttons(synthesis::EventAction action, MirPointerButton button);
69 void update_position(int rel_x, int rel_y);73 void update_position(int rel_x, int rel_y);
@@ -76,6 +80,7 @@
76 uint32_t modifiers{0};80 uint32_t modifiers{0};
77 mir::geometry::Point pos, scroll;81 mir::geometry::Point pos, scroll;
78 MirPointerButtons buttons;82 MirPointerButtons buttons;
83 mir::input::PointerSettings settings;
79 };84 };
80 std::shared_ptr<mir::dispatch::ActionQueue> queue;85 std::shared_ptr<mir::dispatch::ActionQueue> queue;
81 std::shared_ptr<InputDevice> device;86 std::shared_ptr<InputDevice> device;
8287
=== modified file 'tests/unit-tests/input/evdev/test_libinput_device.cpp'
--- tests/unit-tests/input/evdev/test_libinput_device.cpp 2015-10-07 16:41:50 +0000
+++ tests/unit-tests/input/evdev/test_libinput_device.cpp 2015-10-19 10:46:25 +0000
@@ -22,6 +22,7 @@
2222
23#include "mir/input/input_device_registry.h"23#include "mir/input/input_device_registry.h"
24#include "mir/input/input_sink.h"24#include "mir/input/input_sink.h"
25#include "mir/input/pointer_settings.h"
25#include "mir/geometry/point.h"26#include "mir/geometry/point.h"
26#include "mir/geometry/rectangle.h"27#include "mir/geometry/rectangle.h"
27#include "mir/test/event_matchers.h"28#include "mir/test/event_matchers.h"
@@ -159,12 +160,12 @@
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);
160 }161 }
161162
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)
163 {164 {
164 EXPECT_CALL(mock_libinput, libinput_device_config_accel_get_speed(dev))165 EXPECT_CALL(mock_libinput, libinput_device_config_accel_get_speed(dev))
165 .WillRepeatedly(Return(accel_speed));166 .WillRepeatedly(Return(accel_speed));
166 EXPECT_CALL(mock_libinput, libinput_device_config_left_handed_get(dev))167 EXPECT_CALL(mock_libinput, libinput_device_config_left_handed_get(dev))
167 .WillRepeatedly(Return(primary == mir_pointer_button_secondary));168 .WillRepeatedly(Return(handedness == mir_pointer_handedness_left));
168 }169 }
169170
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)
@@ -318,7 +319,7 @@
318 std::shared_ptr<libinput> lib = mie::make_libinput();319 std::shared_ptr<libinput> lib = mie::make_libinput();
319 char const* second_dev = "/dev/input/event13";320 char const* second_dev = "/dev/input/event13";
320 char const* second_umock_dev_name = "bluetooth-magic-trackpad";321 char const* second_umock_dev_name = "bluetooth-magic-trackpad";
321 322
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);
323324
324 InSequence seq;325 InSequence seq;
@@ -341,7 +342,7 @@
341 std::shared_ptr<libinput> lib = mie::make_libinput();342 std::shared_ptr<libinput> lib = mie::make_libinput();
342 char const* second_dev = "/dev/input/event13";343 char const* second_dev = "/dev/input/event13";
343 char const* second_umock_dev_name = "bluetooth-magic-trackpad";344 char const* second_umock_dev_name = "bluetooth-magic-trackpad";
344 345
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);
346347
347 mie::LibInputDevice dev(mir::report::null_input_report(),348 mie::LibInputDevice dev(mir::report::null_input_report(),
@@ -595,3 +596,113 @@
595 dev.process_event(fake_event_3);596 dev.process_event(fake_event_3);
596 dev.process_event(fake_event_4);597 dev.process_event(fake_event_4);
597}598}
599
600TEST_F(LibInputDevice, provides_no_pointer_settings_for_non_pointing_devices)
601{
602 char const keyboard_name[] = "usb-keyboard";
603 char const keyboard_device_path[] = "/dev/input/event14";
604 setup_device(second_fake_device, keyboard_device_path, keyboard_name, 1231, 4124);
605
606 std::shared_ptr<libinput> lib = mie::make_libinput();
607 mie::LibInputDevice dev(mir::report::null_input_report(), keyboard_device_path, mie::make_libinput_device(lib.get(), keyboard_device_path));
608
609 auto ptr = dev.get_pointer_settings();
610 EXPECT_THAT(ptr.is_set(), Eq(false));
611}
612
613TEST_F(LibInputDevice, reads_pointer_settings_from_libinput)
614{
615 char const mouse_device_path[] = "/dev/input/event13";
616 char const mouse_name[] = "usb-mouse";
617 setup_device(second_fake_device, mouse_device_path, mouse_name, 1231, 4124);
618
619 std::shared_ptr<libinput> lib = mie::make_libinput();
620 mie::LibInputDevice dev(mir::report::null_input_report(), mouse_device_path, mie::make_libinput_device(lib.get(), mouse_device_path));
621
622 setup_pointer_configuration(dev.device(), 1, mir_pointer_handedness_right);
623 auto optional_settings = dev.get_pointer_settings();
624
625 EXPECT_THAT(optional_settings.is_set(), Eq(true));
626
627 auto ptr_settings = optional_settings.value();
628 EXPECT_THAT(ptr_settings.handedness, Eq(mir_pointer_handedness_right));
629 EXPECT_THAT(ptr_settings.cursor_acceleration_bias, Eq(1.0));
630 EXPECT_THAT(ptr_settings.horizontal_scroll_scale, Eq(1.0));
631 EXPECT_THAT(ptr_settings.vertical_scroll_scale, Eq(1.0));
632
633 setup_pointer_configuration(dev.device(), 0.0, mir_pointer_handedness_left);
634 optional_settings = dev.get_pointer_settings();
635
636 EXPECT_THAT(optional_settings.is_set(), Eq(true));
637
638 ptr_settings = optional_settings.value();
639 EXPECT_THAT(ptr_settings.handedness, Eq(mir_pointer_handedness_left));
640 EXPECT_THAT(ptr_settings.cursor_acceleration_bias, Eq(0.0));
641 EXPECT_THAT(ptr_settings.horizontal_scroll_scale, Eq(1.0));
642 EXPECT_THAT(ptr_settings.vertical_scroll_scale, Eq(1.0));
643}
644
645TEST_F(LibInputDevice, applies_pointer_settings)
646{
647 char const mouse_device_path[] = "/dev/input/event13";
648 char const mouse_name[] = "usb-mouse";
649 setup_device(second_fake_device, mouse_device_path, mouse_name, 1231, 4124);
650
651 std::shared_ptr<libinput> lib = mie::make_libinput();
652 mie::LibInputDevice dev(mir::report::null_input_report(), mouse_device_path, mie::make_libinput_device(lib.get(), path));
653
654 setup_pointer_configuration(dev.device(), 1, mir_pointer_handedness_right);
655 mi::PointerSettings settings(dev.get_pointer_settings().value());
656 settings.cursor_acceleration_bias = 1.1;
657 settings.handedness = mir_pointer_handedness_left;
658
659 EXPECT_CALL(mock_libinput,libinput_device_config_accel_set_speed(dev.device(), 1.1)).Times(1);
660 EXPECT_CALL(mock_libinput,libinput_device_config_left_handed_set(dev.device(), true)).Times(1);
661
662 dev.apply_settings(settings);
663}
664
665TEST_F(LibInputDevice, denies_pointer_settings_on_keyboards)
666{
667 char const mouse_device_path[] = "/dev/input/event13";
668 char const mouse_name[] = "usb-mouse";
669 setup_device(second_fake_device, mouse_device_path, mouse_name, 1231, 4124);
670
671 std::shared_ptr<libinput> lib = mie::make_libinput();
672 mie::LibInputDevice keyboard_dev(mir::report::null_input_report(), path, mie::make_libinput_device(lib.get(), path));
673 mie::LibInputDevice mouse_dev(mir::report::null_input_report(), mouse_device_path, mie::make_libinput_device(lib.get(), path));
674
675 auto settings_from_mouse = mouse_dev.get_pointer_settings();
676
677 EXPECT_CALL(mock_libinput,libinput_device_config_accel_set_speed(_, _)).Times(0);
678 EXPECT_CALL(mock_libinput,libinput_device_config_left_handed_set(_, _)).Times(0);
679
680 keyboard_dev.apply_settings(settings_from_mouse.value());
681}
682
683TEST_F(LibInputDevice, scroll_speed_scales_scroll_events)
684{
685 char const mouse_device_path[] = "/dev/input/event13";
686 char const mouse_name[] = "usb-mouse";
687 setup_device(second_fake_device, mouse_device_path, mouse_name, 1231, 4124);
688
689 std::shared_ptr<libinput> lib = mie::make_libinput();
690 mie::LibInputDevice dev(mir::report::null_input_report(), mouse_device_path, mie::make_libinput_device(lib.get(), mouse_device_path));
691
692 setup_axis_event(fake_event_1, event_time_1, 0.0, 3.0);
693 setup_axis_event(fake_event_2, event_time_2, -2.0, 0.0);
694
695 // expect two scroll events..
696 EXPECT_CALL(mock_sink, handle_input(mt::PointerAxisChange(mir_pointer_axis_vscroll, -3.0f)));
697 EXPECT_CALL(mock_sink, handle_input(mt::PointerAxisChange(mir_pointer_axis_hscroll, -10.0f)));
698
699 setup_pointer_configuration(dev.device(), 1, mir_pointer_handedness_right);
700 mi::PointerSettings settings(dev.get_pointer_settings().value());
701 settings.vertical_scroll_scale = -1.0;
702 settings.horizontal_scroll_scale = 5.0;
703 dev.apply_settings(settings);
704
705 dev.start(&mock_sink, &mock_builder);
706 dev.process_event(fake_event_1);
707 dev.process_event(fake_event_2);
708}
598709
=== modified file 'tests/unit-tests/input/test_default_input_device_hub.cpp'
--- tests/unit-tests/input/test_default_input_device_hub.cpp 2015-10-07 16:41:50 +0000
+++ tests/unit-tests/input/test_default_input_device_hub.cpp 2015-10-19 10:46:25 +0000
@@ -25,6 +25,7 @@
25#include "mir/test/event_matchers.h"25#include "mir/test/event_matchers.h"
2626
27#include "mir/input/input_device.h"27#include "mir/input/input_device.h"
28#include "mir/input/pointer_settings.h"
28#include "mir/input/device.h"29#include "mir/input/device.h"
29#include "mir/input/touch_visualizer.h"30#include "mir/input/touch_visualizer.h"
30#include "mir/input/input_device_observer.h"31#include "mir/input/input_device_observer.h"
@@ -85,6 +86,8 @@
85 MOCK_METHOD2(start, void(mi::InputSink* destination, mi::EventBuilder* builder));86 MOCK_METHOD2(start, void(mi::InputSink* destination, mi::EventBuilder* builder));
86 MOCK_METHOD0(stop, void());87 MOCK_METHOD0(stop, void());
87 MOCK_METHOD0(get_device_info, mi::InputDeviceInfo());88 MOCK_METHOD0(get_device_info, mi::InputDeviceInfo());
89 MOCK_CONST_METHOD0(get_pointer_settings, mir::optional_value<mi::PointerSettings>());
90 MOCK_METHOD1(apply_settings, void(mi::PointerSettings const&));
88};91};
8992
90template<typename Type>93template<typename Type>

Subscribers

People subscribed via source and target branches