Mir

Merge lp:~andreas-pokorny/mir/libinput-platform-touch-pad-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: 3052
Proposed branch: lp:~andreas-pokorny/mir/libinput-platform-touch-pad-settings
Merge into: lp:mir
Prerequisite: lp:~andreas-pokorny/mir/libinput-platform-pointer-settings
Diff against target: 1248 lines (+546/-274)
12 files modified
include/client/mir_toolkit/mir_input_device.h (+17/-0)
include/platform/mir/input/input_device.h (+4/-1)
include/platform/mir/input/touchpad_settings.h (+46/-0)
include/server/mir/input/device.h (+1/-1)
src/platforms/evdev/libinput_device.cpp (+75/-0)
src/platforms/evdev/libinput_device.h (+3/-1)
src/platforms/mesa/server/x11/input/input_device.cpp (+14/-0)
src/platforms/mesa/server/x11/input/input_device.h (+3/-1)
tests/mir_test_framework/fake_input_device_impl.cpp (+16/-0)
tests/mir_test_framework/fake_input_device_impl.h (+2/-0)
tests/unit-tests/input/evdev/test_libinput_device.cpp (+362/-270)
tests/unit-tests/input/test_default_input_device_hub.cpp (+3/-0)
To merge this branch: bzr merge lp:~andreas-pokorny/mir/libinput-platform-touch-pad-settings
Reviewer Review Type Date Requested Status
PS Jenkins bot (community) continuous-integration Approve
Daniel van Vugt Abstain
Alan Griffiths Approve
Kevin DuBois (community) Approve
Review via email: mp+272845@code.launchpad.net

Commit message

Add mir::input::TouchPadSettings and support for it in libinput platform

Description of the change

Adds settings for touch pads. So far again only supported within libinput...

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

+ char const* path = setup_mouse(fake_device);

There's an awful lot of this. Would it be worth creating a fixture that does this in SetUp() instead of repeating it in so many tests? Or setting up all the devices in SetUp()?

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

+ EXPECT_CALL(mock_libinput, libinput_device_config_click_get_method(dev))
+ .WillRepeatedly(Return(static_cast<libinput_config_click_method>(click_method.value())));
+ EXPECT_CALL(mock_libinput, libinput_device_config_scroll_get_method(dev))
+ .WillRepeatedly(Return(static_cast<libinput_config_scroll_method>(scroll_method.value())));
+ EXPECT_CALL(mock_libinput, libinput_device_config_scroll_get_button(dev))
+ .WillRepeatedly(Return(scroll_button));
+ EXPECT_CALL(mock_libinput, libinput_device_config_tap_get_enabled(dev))
+ .WillRepeatedly(Return(tap_to_click?
+ LIBINPUT_CONFIG_TAP_ENABLED:
+ LIBINPUT_CONFIG_TAP_DISABLED));
+ EXPECT_CALL(mock_libinput, libinput_device_config_dwt_get_enabled(dev))
+ .WillRepeatedly(Return(disable_while_typing?
+ LIBINPUT_CONFIG_DWT_ENABLED:
+ LIBINPUT_CONFIG_DWT_DISABLED));
+ EXPECT_CALL(mock_libinput, libinput_device_config_send_events_get_mode(dev))
+ .WillRepeatedly(Return(disable_with_mouse?
+ LIBINPUT_CONFIG_SEND_EVENTS_DISABLED_ON_EXTERNAL_MOUSE:
+ LIBINPUT_CONFIG_SEND_EVENTS_ENABLED));
+ EXPECT_CALL(mock_libinput, libinput_device_config_middle_emulation_get_enabled(dev))
+ .WillRepeatedly(Return(middle_button_emulation?
+ LIBINPUT_CONFIG_MIDDLE_EMULATION_ENABLED:
+ LIBINPUT_CONFIG_MIDDLE_EMULATION_DISABLED));

Setting expectations in the test setup is best avoided (admittedly not always possible).

But these look like they could be replaced with:

ON_CALL(...).WillByDefault(...);

Is there something I'm missing?

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

just some nits:

+ TouchPadSettings() {}
not needed

+const int no_scroll_button = 0;
const ordering

+ // forwards aldready interpreted events.
typo

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

> just some nits:
>
> + TouchPadSettings() {}
> not needed

This is needed when I want to use that with mir::optional_value, as it initializes stuff with curly braces. Also the = default constructor is not enough... Without that clang treats it as a pod and assumes a by member initialization.

fixiing the rest now

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

thanks, okay by me

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

+ TouchPadSettings() {}

I think our current practice is to write "TouchPadSettings() = default;" - but I don't know if that avoids the problems you note with clang. (And isn't a blocker.)

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

OK

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

Your plural/singulars are backwards :)

MirTouchPadClickModes a_single_mode;
MirTouchPadClickMode a_set_of_modes;

8 +typedef enum MirTouchPadClickModes
9 +{
10 + mir_touch_pad_click_mode_none = 0,
11 + mir_touch_pad_click_mode_area_to_click = 1 << 1,
12 + mir_touch_pad_click_mode_finger_count = 1 << 2
13 +} MirTouchPadClickModes;
14 +typedef unsigned int MirTouchPadClickMode;
15 +
16 +typedef enum MirTouchPadScrollModes
17 +{
18 + mir_touch_pad_scroll_mode_none = 0,
19 + mir_touch_pad_scroll_mode_two_finger_scroll = 1 << 1,
20 + mir_touch_pad_scroll_mode_edge_scroll = 1 << 2,
21 + mir_touch_pad_scroll_mode_button_down_scroll = 1 << 3
22 +} MirTouchPadScrollModes;
23 +typedef unsigned int MirTouchPadScrollMode;

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

(2) Also your forgot to make use of bit zero: foo = 1 << 0;

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

> (2) Also your forgot to make use of bit zero: foo = 1 << 0;

ack done.

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
Daniel van Vugt (vanvugt) wrote :

Thanks.

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

Although Touchpad is a single word, so maybe also:

s/mir_touch_pad/mir_touchpad/

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

Minor spelling correction suggested per above.

review: Abstain
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
1=== modified file 'include/client/mir_toolkit/mir_input_device.h'
2--- include/client/mir_toolkit/mir_input_device.h 2015-10-19 10:45:47 +0000
3+++ include/client/mir_toolkit/mir_input_device.h 2015-10-23 10:50:47 +0000
4@@ -32,6 +32,23 @@
5 mir_pointer_handedness_left = 1
6 } MirPointerHandedness;
7
8+typedef enum MirTouchpadClickMode
9+{
10+ mir_touchpad_click_mode_none = 0,
11+ mir_touchpad_click_mode_area_to_click = 1 << 0,
12+ mir_touchpad_click_mode_finger_count = 1 << 1
13+} MirTouchpadClickMode;
14+typedef unsigned int MirTouchpadClickModes;
15+
16+typedef enum MirTouchpadScrollMode
17+{
18+ mir_touchpad_scroll_mode_none = 0,
19+ mir_touchpad_scroll_mode_two_finger_scroll = 1 << 0,
20+ mir_touchpad_scroll_mode_edge_scroll = 1 << 1,
21+ mir_touchpad_scroll_mode_button_down_scroll = 1 << 2
22+} MirTouchpadScrollMode;
23+typedef unsigned int MirTouchpadScrollModes;
24+
25 #ifdef __cplusplus
26 }
27 #endif
28
29=== modified file 'include/platform/mir/input/input_device.h'
30--- include/platform/mir/input/input_device.h 2015-10-20 03:30:00 +0000
31+++ include/platform/mir/input/input_device.h 2015-10-23 10:50:47 +0000
32@@ -38,6 +38,7 @@
33 class EventBuilder;
34
35 class PointerSettings;
36+class TouchpadSettings;
37
38 /**
39 * Represents an input device.
40@@ -59,9 +60,11 @@
41
42 virtual InputDeviceInfo get_device_info() = 0;
43
44- virtual mir::optional_value<PointerSettings> get_pointer_settings() const = 0;
45+ virtual optional_value<PointerSettings> get_pointer_settings() const = 0;
46 virtual void apply_settings(PointerSettings const&) = 0;
47
48+ virtual optional_value<TouchpadSettings> get_touchpad_settings() const = 0;
49+ virtual void apply_settings(TouchpadSettings const&) = 0;
50 protected:
51 InputDevice(InputDevice const&) = delete;
52 InputDevice& operator=(InputDevice const&) = delete;
53
54=== added file 'include/platform/mir/input/touchpad_settings.h'
55--- include/platform/mir/input/touchpad_settings.h 1970-01-01 00:00:00 +0000
56+++ include/platform/mir/input/touchpad_settings.h 2015-10-23 10:50:47 +0000
57@@ -0,0 +1,46 @@
58+/*
59+ * Copyright © 2015 Canonical Ltd.
60+ *
61+ * This program is free software: you can redistribute it and/or modify it
62+ * under the terms of the GNU Lesser General Public License version 3,
63+ * as published by the Free Software Foundation.
64+ *
65+ * This program is distributed in the hope that it will be useful,
66+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
67+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
68+ * GNU Lesser General Public License for more details.
69+ *
70+ * You should have received a copy of the GNU Lesser General Public License
71+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
72+ *
73+ * Authored by:
74+ * Andreas Pokorny <andreas.pokorny@canonical.com>
75+ */
76+
77+#ifndef MIR_INPUT_TOUCH_PAD_SETTINGS_H_
78+#define MIR_INPUT_TOUCH_PAD_SETTINGS_H_
79+
80+#include "mir_toolkit/mir_input_device.h"
81+
82+namespace mir
83+{
84+namespace input
85+{
86+int const no_scroll_button = 0;
87+
88+struct TouchpadSettings
89+{
90+ TouchpadSettings() {}
91+ MirTouchpadClickModes click_mode{mir_touchpad_click_mode_finger_count};
92+ MirTouchpadScrollModes scroll_mode{mir_touchpad_scroll_mode_two_finger_scroll};
93+ int button_down_scroll_button{no_scroll_button};
94+ bool tap_to_click{true};
95+ bool disable_while_typing{false};
96+ bool disable_with_mouse{false};
97+ bool middle_mouse_button_emulation{true};
98+};
99+
100+}
101+}
102+
103+#endif
104
105=== modified file 'include/server/mir/input/device.h'
106--- include/server/mir/input/device.h 2015-10-01 09:52:28 +0000
107+++ include/server/mir/input/device.h 2015-10-23 10:50:47 +0000
108@@ -31,7 +31,7 @@
109 {
110
111 class PointerSettings;
112-class TouchPadSettings;
113+class TouchpadSettings;
114
115 class Device
116 {
117
118=== modified file 'src/platforms/evdev/libinput_device.cpp'
119--- src/platforms/evdev/libinput_device.cpp 2015-10-20 03:30:00 +0000
120+++ src/platforms/evdev/libinput_device.cpp 2015-10-23 10:50:47 +0000
121@@ -26,6 +26,7 @@
122 #include "mir/input/input_report.h"
123 #include "mir/input/device_capability.h"
124 #include "mir/input/pointer_settings.h"
125+#include "mir/input/touchpad_settings.h"
126 #include "mir/input/input_device_info.h"
127 #include "mir/events/event_builders.h"
128 #include "mir/geometry/displacement.h"
129@@ -393,3 +394,77 @@
130 vertical_scroll_scale = settings.vertical_scroll_scale;
131 horizontal_scroll_scale = settings.horizontal_scroll_scale;
132 }
133+
134+mir::optional_value<mi::TouchpadSettings> mie::LibInputDevice::get_touchpad_settings() const
135+{
136+ if (!contains(info.capabilities, mi::DeviceCapability::touchpad))
137+ return {};
138+
139+ auto dev = device();
140+ auto click_modes = libinput_device_config_click_get_method(dev);
141+ auto scroll_modes = libinput_device_config_scroll_get_method(dev);
142+
143+ TouchpadSettings settings;
144+
145+ settings.click_mode = mir_touchpad_click_mode_none;
146+ if (click_modes & LIBINPUT_CONFIG_CLICK_METHOD_BUTTON_AREAS)
147+ settings.click_mode |= mir_touchpad_click_mode_area_to_click;
148+ if (click_modes & LIBINPUT_CONFIG_CLICK_METHOD_CLICKFINGER)
149+ settings.click_mode |= mir_touchpad_click_mode_finger_count;
150+
151+ settings.scroll_mode = mir_touchpad_scroll_mode_none;
152+ if (scroll_modes & LIBINPUT_CONFIG_SCROLL_2FG)
153+ settings.scroll_mode |= mir_touchpad_scroll_mode_two_finger_scroll;
154+ if (scroll_modes & LIBINPUT_CONFIG_SCROLL_EDGE)
155+ settings.scroll_mode |= mir_touchpad_scroll_mode_edge_scroll;
156+ if (scroll_modes & LIBINPUT_CONFIG_SCROLL_ON_BUTTON_DOWN)
157+ settings.scroll_mode |= mir_touchpad_scroll_mode_button_down_scroll;
158+
159+ settings.tap_to_click = libinput_device_config_tap_get_enabled(dev) == LIBINPUT_CONFIG_TAP_ENABLED;
160+ settings.disable_while_typing = libinput_device_config_dwt_get_enabled(dev) == LIBINPUT_CONFIG_DWT_ENABLED;
161+ settings.disable_with_mouse =
162+ libinput_device_config_send_events_get_mode(dev) == LIBINPUT_CONFIG_SEND_EVENTS_DISABLED_ON_EXTERNAL_MOUSE;
163+ settings.middle_mouse_button_emulation =
164+ libinput_device_config_middle_emulation_get_enabled(dev) == LIBINPUT_CONFIG_MIDDLE_EMULATION_ENABLED;
165+
166+ return settings;
167+}
168+
169+void mie::LibInputDevice::apply_settings(mi::TouchpadSettings const& settings)
170+{
171+ auto dev = device();
172+
173+ uint32_t click_method = LIBINPUT_CONFIG_CLICK_METHOD_NONE;
174+ if (settings.click_mode & mir_touchpad_click_mode_area_to_click)
175+ click_method |= LIBINPUT_CONFIG_CLICK_METHOD_BUTTON_AREAS;
176+ if (settings.click_mode & mir_touchpad_click_mode_finger_count)
177+ click_method |= LIBINPUT_CONFIG_CLICK_METHOD_CLICKFINGER;
178+
179+ uint32_t scroll_method = LIBINPUT_CONFIG_CLICK_METHOD_NONE;
180+ if (settings.scroll_mode & mir_touchpad_scroll_mode_button_down_scroll)
181+ {
182+ scroll_method |= LIBINPUT_CONFIG_SCROLL_ON_BUTTON_DOWN;
183+ libinput_device_config_scroll_set_button(dev, settings.button_down_scroll_button);
184+ }
185+ if (settings.scroll_mode & mir_touchpad_scroll_mode_edge_scroll)
186+ scroll_method |= LIBINPUT_CONFIG_SCROLL_EDGE;
187+ if (settings.scroll_mode & mir_touchpad_scroll_mode_two_finger_scroll)
188+ scroll_method |= LIBINPUT_CONFIG_SCROLL_2FG;
189+
190+ libinput_device_config_click_set_method(dev, static_cast<libinput_config_click_method>(click_method));
191+ libinput_device_config_scroll_set_method(dev, static_cast<libinput_config_scroll_method>(scroll_method));
192+
193+ libinput_device_config_tap_set_enabled(
194+ dev, settings.tap_to_click ? LIBINPUT_CONFIG_TAP_ENABLED : LIBINPUT_CONFIG_TAP_DISABLED);
195+
196+ libinput_device_config_dwt_set_enabled(
197+ dev, settings.disable_while_typing ? LIBINPUT_CONFIG_DWT_ENABLED : LIBINPUT_CONFIG_DWT_DISABLED);
198+
199+ libinput_device_config_send_events_set_mode(dev, settings.disable_with_mouse ?
200+ LIBINPUT_CONFIG_SEND_EVENTS_DISABLED_ON_EXTERNAL_MOUSE :
201+ LIBINPUT_CONFIG_SEND_EVENTS_ENABLED);
202+
203+ libinput_device_config_middle_emulation_set_enabled(dev, settings.middle_mouse_button_emulation ?
204+ LIBINPUT_CONFIG_MIDDLE_EMULATION_ENABLED :
205+ LIBINPUT_CONFIG_MIDDLE_EMULATION_DISABLED);
206+}
207
208=== modified file 'src/platforms/evdev/libinput_device.h'
209--- src/platforms/evdev/libinput_device.h 2015-10-20 03:30:00 +0000
210+++ src/platforms/evdev/libinput_device.h 2015-10-23 10:50:47 +0000
211@@ -54,8 +54,10 @@
212 void start(InputSink* sink, EventBuilder* builder) override;
213 void stop() override;
214 InputDeviceInfo get_device_info() override;
215- mir::optional_value<PointerSettings> get_pointer_settings() const override;
216+ optional_value<PointerSettings> get_pointer_settings() const override;
217 void apply_settings(PointerSettings const&) override;
218+ optional_value<TouchpadSettings> get_touchpad_settings() const override;
219+ void apply_settings(TouchpadSettings const&) override;
220
221 void process_event(libinput_event* event);
222 ::libinput_device* device() const;
223
224=== modified file 'src/platforms/mesa/server/x11/input/input_device.cpp'
225--- src/platforms/mesa/server/x11/input/input_device.cpp 2015-10-20 03:30:00 +0000
226+++ src/platforms/mesa/server/x11/input/input_device.cpp 2015-10-23 10:50:47 +0000
227@@ -19,6 +19,7 @@
228 #include "input_device.h"
229
230 #include "mir/input/pointer_settings.h"
231+#include "mir/input/touchpad_settings.h"
232 #include "mir/input/input_device_info.h"
233 #include "mir/input/device_capability.h"
234
235@@ -60,3 +61,16 @@
236 {
237 // TODO Make use if X11-XInput2
238 }
239+
240+mir::optional_value<mi::TouchpadSettings> mix::XInputDevice::get_touchpad_settings() const
241+{
242+ optional_value<TouchpadSettings> ret;
243+ if (contains(info.capabilities, DeviceCapability::touchpad))
244+ ret = TouchpadSettings();
245+
246+ return ret;
247+}
248+
249+void mix::XInputDevice::apply_settings(TouchpadSettings const&)
250+{
251+}
252
253=== modified file 'src/platforms/mesa/server/x11/input/input_device.h'
254--- src/platforms/mesa/server/x11/input/input_device.h 2015-10-20 03:30:00 +0000
255+++ src/platforms/mesa/server/x11/input/input_device.h 2015-10-23 10:50:47 +0000
256@@ -41,8 +41,10 @@
257 void stop() override;
258 InputDeviceInfo get_device_info() override;
259
260- mir::optional_value<PointerSettings> get_pointer_settings() const override;
261+ optional_value<PointerSettings> get_pointer_settings() const override;
262 void apply_settings(PointerSettings const& settings) override;
263+ optional_value<TouchpadSettings> get_touchpad_settings() const override;
264+ void apply_settings(TouchpadSettings const& settings) override;
265
266 InputSink* sink{nullptr};
267 EventBuilder* builder{nullptr};
268
269=== modified file 'tests/mir_test_framework/fake_input_device_impl.cpp'
270--- tests/mir_test_framework/fake_input_device_impl.cpp 2015-10-20 03:30:00 +0000
271+++ tests/mir_test_framework/fake_input_device_impl.cpp 2015-10-23 10:50:47 +0000
272@@ -23,6 +23,7 @@
273 #include "mir/input/input_device_info.h"
274 #include "mir/input/input_sink.h"
275 #include "mir/input/pointer_settings.h"
276+#include "mir/input/touchpad_settings.h"
277 #include "mir/input/event_builder.h"
278 #include "mir/dispatch/action_queue.h"
279 #include "mir/geometry/displacement.h"
280@@ -246,6 +247,21 @@
281 this->settings = settings;
282 }
283
284+mir::optional_value<mi::TouchpadSettings> mtf::FakeInputDeviceImpl::InputDevice::get_touchpad_settings() const
285+{
286+ mir::optional_value<mi::TouchpadSettings> ret;
287+ if (contains(info.capabilities, mi::DeviceCapability::pointer))
288+ ret = mi::TouchpadSettings();
289+
290+ return ret;
291+}
292+
293+void mtf::FakeInputDeviceImpl::InputDevice::apply_settings(mi::TouchpadSettings const&)
294+{
295+ // Not applicable for configuration since FakeInputDevice just
296+ // forwards already interpreted events.
297+}
298+
299 void mtf::FakeInputDeviceImpl::InputDevice::map_touch_coordinates(float& x, float& y)
300 {
301 // TODO take orientation of input sink into account?
302
303=== modified file 'tests/mir_test_framework/fake_input_device_impl.h'
304--- tests/mir_test_framework/fake_input_device_impl.h 2015-10-20 03:30:00 +0000
305+++ tests/mir_test_framework/fake_input_device_impl.h 2015-10-23 10:50:47 +0000
306@@ -67,6 +67,8 @@
307
308 mir::optional_value<mir::input::PointerSettings> get_pointer_settings() const override;
309 void apply_settings(mir::input::PointerSettings const& settings) override;
310+ mir::optional_value<mir::input::TouchpadSettings> get_touchpad_settings() const override;
311+ void apply_settings(mir::input::TouchpadSettings const& settings) override;
312
313 private:
314 MirPointerAction update_buttons(synthesis::EventAction action, MirPointerButton button);
315
316=== modified file 'tests/unit-tests/input/evdev/test_libinput_device.cpp'
317--- tests/unit-tests/input/evdev/test_libinput_device.cpp 2015-10-20 03:30:00 +0000
318+++ tests/unit-tests/input/evdev/test_libinput_device.cpp 2015-10-23 10:50:47 +0000
319@@ -23,17 +23,21 @@
320 #include "mir/input/input_device_registry.h"
321 #include "mir/input/input_sink.h"
322 #include "mir/input/pointer_settings.h"
323+#include "mir/input/touchpad_settings.h"
324+#include "mir/flags.h"
325 #include "mir/geometry/point.h"
326 #include "mir/geometry/rectangle.h"
327 #include "mir/test/event_matchers.h"
328 #include "mir/test/doubles/mock_libinput.h"
329 #include "mir/test/gmock_fixes.h"
330+#include "mir/udev/wrapper.h"
331 #include "mir/cookie_factory.h"
332 #include "mir_test_framework/udev_environment.h"
333
334 #include <gmock/gmock.h>
335 #include <gtest/gtest.h>
336 #include <linux/input.h>
337+#include <libinput.h>
338
339 #include <chrono>
340
341@@ -125,6 +129,7 @@
342 ::testing::NiceMock<mir::test::doubles::MockLibInput> mock_libinput;
343 ::testing::NiceMock<MockInputSink> mock_sink;
344 ::testing::NiceMock<MockEventBuilder> mock_builder;
345+ std::shared_ptr<libinput> lib;
346
347 libinput* fake_input = reinterpret_cast<libinput*>(0xF4C3);
348 libinput_device* fake_device = reinterpret_cast<libinput_device*>(0xF4C4);
349@@ -144,96 +149,186 @@
350 const mi::EventBuilder::Timestamp time_stamp_4{std::chrono::microseconds{event_time_4}};
351
352 char const* laptop_keyboard_device_path = "/dev/input/event4";
353- char const* path{laptop_keyboard_device_path};
354+ char const* trackpad_dev_path = "/dev/input/event13";
355+ char const* touch_screen_dev_path = "/dev/input/event4";
356+ char const* usb_mouse_dev_path = "/dev/input/event13";
357+ char const* touchpad_dev_path = "/dev/input/event12";
358
359 LibInputDevice()
360 {
361- setup_device(fake_device, path, "laptop-keyboard", 5252, 3113);
362-
363 ON_CALL(mock_libinput, libinput_path_create_context(_,_))
364 .WillByDefault(Return(fake_input));
365- }
366-
367- void setup_device(libinput_device* dev, char const* device_path, char const* umock_name, unsigned int vendor_id, unsigned int product_id)
368+ lib = mie::make_libinput();
369+ }
370+
371+ char const* setup_laptop_keyboard(libinput_device* dev)
372+ {
373+ return setup_device(dev, laptop_keyboard_device_path, "laptop-keyboard", 5252, 3113);
374+ }
375+
376+ char const* setup_trackpad(libinput_device* dev)
377+ {
378+ return setup_device(dev, trackpad_dev_path, "bluetooth-magic-trackpad", 9663, 1234);
379+ }
380+
381+ char const* setup_touch_screen(libinput_device* dev)
382+ {
383+ return setup_device(dev, touch_screen_dev_path, "mt-screen-detection", 858, 484);
384+ }
385+
386+ char const* setup_touchpad(libinput_device* dev)
387+ {
388+ return setup_device(dev, touchpad_dev_path, "synaptics-touchpad", 858, 484);
389+ }
390+
391+ char const* setup_mouse(libinput_device* dev)
392+ {
393+ return setup_device(dev, usb_mouse_dev_path, "usb-mouse", 858, 484);
394+ }
395+
396+ void remove_devices()
397+ {
398+ mir::udev::Enumerator devices{std::make_shared<mir::udev::Context>()};
399+ devices.scan_devices();
400+
401+ for (auto& device : devices)
402+ {
403+ if (device.devnode() && (std::string(device.devnode()).find("input/event") != std::string::npos))
404+ {
405+ env.remove_device((std::string("/sys") + device.devpath()).c_str());
406+ }
407+ }
408+ }
409+
410+ char const* setup_device(libinput_device* dev, char const* device_path, char const* umock_name, unsigned int vendor_id, unsigned int product_id)
411 {
412 env.add_standard_device(umock_name);
413 mock_libinput.setup_device(fake_input, dev, device_path, umock_name, vendor_id, product_id);
414+ return device_path;
415 }
416
417 void setup_pointer_configuration(libinput_device* dev, double accel_speed, MirPointerHandedness handedness)
418 {
419- EXPECT_CALL(mock_libinput, libinput_device_config_accel_get_speed(dev))
420- .WillRepeatedly(Return(accel_speed));
421- EXPECT_CALL(mock_libinput, libinput_device_config_left_handed_get(dev))
422- .WillRepeatedly(Return(handedness == mir_pointer_handedness_left));
423+ ON_CALL(mock_libinput, libinput_device_config_accel_get_speed(dev))
424+ .WillByDefault(Return(accel_speed));
425+ ON_CALL(mock_libinput, libinput_device_config_left_handed_get(dev))
426+ .WillByDefault(Return(handedness == mir_pointer_handedness_left));
427+ }
428+
429+ void setup_touchpad_configuration(libinput_device* dev,
430+ MirTouchpadClickMode click_mode,
431+ MirTouchpadScrollMode scroll_mode,
432+ int scroll_button,
433+ bool tap_to_click,
434+ bool disable_while_typing,
435+ bool disable_with_mouse,
436+ bool middle_button_emulation)
437+ {
438+ mir::Flags<libinput_config_click_method> click_method = LIBINPUT_CONFIG_CLICK_METHOD_NONE;
439+ if (click_mode & mir_touchpad_click_mode_finger_count)
440+ click_method |= LIBINPUT_CONFIG_CLICK_METHOD_CLICKFINGER;
441+ if (click_mode & mir_touchpad_click_mode_area_to_click)
442+ click_method |= LIBINPUT_CONFIG_CLICK_METHOD_BUTTON_AREAS;
443+
444+ mir::Flags<libinput_config_scroll_method> scroll_method = LIBINPUT_CONFIG_SCROLL_NO_SCROLL;
445+ if (scroll_mode & mir_touchpad_scroll_mode_two_finger_scroll)
446+ scroll_method |= LIBINPUT_CONFIG_SCROLL_2FG;
447+ if (scroll_mode & mir_touchpad_scroll_mode_edge_scroll)
448+ scroll_method |= LIBINPUT_CONFIG_SCROLL_EDGE;
449+ if (scroll_mode & mir_touchpad_scroll_mode_button_down_scroll)
450+ scroll_method |= LIBINPUT_CONFIG_SCROLL_ON_BUTTON_DOWN;
451+
452+ ON_CALL(mock_libinput, libinput_device_config_click_get_method(dev))
453+ .WillByDefault(Return(static_cast<libinput_config_click_method>(click_method.value())));
454+ ON_CALL(mock_libinput, libinput_device_config_scroll_get_method(dev))
455+ .WillByDefault(Return(static_cast<libinput_config_scroll_method>(scroll_method.value())));
456+ ON_CALL(mock_libinput, libinput_device_config_scroll_get_button(dev))
457+ .WillByDefault(Return(scroll_button));
458+ ON_CALL(mock_libinput, libinput_device_config_tap_get_enabled(dev))
459+ .WillByDefault(Return(tap_to_click?
460+ LIBINPUT_CONFIG_TAP_ENABLED:
461+ LIBINPUT_CONFIG_TAP_DISABLED));
462+ ON_CALL(mock_libinput, libinput_device_config_dwt_get_enabled(dev))
463+ .WillByDefault(Return(disable_while_typing?
464+ LIBINPUT_CONFIG_DWT_ENABLED:
465+ LIBINPUT_CONFIG_DWT_DISABLED));
466+ ON_CALL(mock_libinput, libinput_device_config_send_events_get_mode(dev))
467+ .WillByDefault(Return(disable_with_mouse?
468+ LIBINPUT_CONFIG_SEND_EVENTS_DISABLED_ON_EXTERNAL_MOUSE:
469+ LIBINPUT_CONFIG_SEND_EVENTS_ENABLED));
470+ ON_CALL(mock_libinput, libinput_device_config_middle_emulation_get_enabled(dev))
471+ .WillByDefault(Return(middle_button_emulation?
472+ LIBINPUT_CONFIG_MIDDLE_EMULATION_ENABLED:
473+ LIBINPUT_CONFIG_MIDDLE_EMULATION_DISABLED));
474+
475 }
476
477 void setup_key_event(libinput_event* event, uint64_t event_time, uint32_t key, libinput_key_state state)
478 {
479 auto key_event = reinterpret_cast<libinput_event_keyboard*>(event);
480
481- EXPECT_CALL(mock_libinput, libinput_event_get_type(event))
482- .WillRepeatedly(Return(LIBINPUT_EVENT_KEYBOARD_KEY));
483- EXPECT_CALL(mock_libinput, libinput_event_get_keyboard_event(event))
484- .WillRepeatedly(Return(key_event));
485- EXPECT_CALL(mock_libinput, libinput_event_keyboard_get_time_usec(key_event))
486- .WillRepeatedly(Return(event_time));
487- EXPECT_CALL(mock_libinput, libinput_event_keyboard_get_key(key_event))
488- .WillRepeatedly(Return(key));
489- EXPECT_CALL(mock_libinput, libinput_event_keyboard_get_key_state(key_event))
490- .WillRepeatedly(Return(state));
491+ ON_CALL(mock_libinput, libinput_event_get_type(event))
492+ .WillByDefault(Return(LIBINPUT_EVENT_KEYBOARD_KEY));
493+ ON_CALL(mock_libinput, libinput_event_get_keyboard_event(event))
494+ .WillByDefault(Return(key_event));
495+ ON_CALL(mock_libinput, libinput_event_keyboard_get_time_usec(key_event))
496+ .WillByDefault(Return(event_time));
497+ ON_CALL(mock_libinput, libinput_event_keyboard_get_key(key_event))
498+ .WillByDefault(Return(key));
499+ ON_CALL(mock_libinput, libinput_event_keyboard_get_key_state(key_event))
500+ .WillByDefault(Return(state));
501 }
502
503 void setup_pointer_event(libinput_event* event, uint64_t event_time, float relatve_x, float relatve_y)
504 {
505 auto pointer_event = reinterpret_cast<libinput_event_pointer*>(event);
506
507- EXPECT_CALL(mock_libinput, libinput_event_get_type(event))
508- .WillRepeatedly(Return(LIBINPUT_EVENT_POINTER_MOTION));
509- EXPECT_CALL(mock_libinput, libinput_event_get_pointer_event(event))
510- .WillRepeatedly(Return(pointer_event));
511- EXPECT_CALL(mock_libinput, libinput_event_pointer_get_time_usec(pointer_event))
512- .WillRepeatedly(Return(event_time));
513- EXPECT_CALL(mock_libinput, libinput_event_pointer_get_dx(pointer_event))
514- .WillRepeatedly(Return(relatve_x));
515- EXPECT_CALL(mock_libinput, libinput_event_pointer_get_dy(pointer_event))
516- .WillRepeatedly(Return(relatve_y));
517+ ON_CALL(mock_libinput, libinput_event_get_type(event))
518+ .WillByDefault(Return(LIBINPUT_EVENT_POINTER_MOTION));
519+ ON_CALL(mock_libinput, libinput_event_get_pointer_event(event))
520+ .WillByDefault(Return(pointer_event));
521+ ON_CALL(mock_libinput, libinput_event_pointer_get_time_usec(pointer_event))
522+ .WillByDefault(Return(event_time));
523+ ON_CALL(mock_libinput, libinput_event_pointer_get_dx(pointer_event))
524+ .WillByDefault(Return(relatve_x));
525+ ON_CALL(mock_libinput, libinput_event_pointer_get_dy(pointer_event))
526+ .WillByDefault(Return(relatve_y));
527 }
528
529 void setup_button_event(libinput_event* event, uint64_t event_time, int button, libinput_button_state state)
530 {
531 auto pointer_event = reinterpret_cast<libinput_event_pointer*>(event);
532
533- EXPECT_CALL(mock_libinput, libinput_event_get_type(event))
534- .WillRepeatedly(Return(LIBINPUT_EVENT_POINTER_BUTTON));
535- EXPECT_CALL(mock_libinput, libinput_event_get_pointer_event(event))
536- .WillRepeatedly(Return(pointer_event));
537- EXPECT_CALL(mock_libinput, libinput_event_pointer_get_time_usec(pointer_event))
538- .WillRepeatedly(Return(event_time));
539- EXPECT_CALL(mock_libinput, libinput_event_pointer_get_button(pointer_event))
540- .WillRepeatedly(Return(button));
541- EXPECT_CALL(mock_libinput, libinput_event_pointer_get_button_state(pointer_event))
542- .WillRepeatedly(Return(state));
543+ ON_CALL(mock_libinput, libinput_event_get_type(event))
544+ .WillByDefault(Return(LIBINPUT_EVENT_POINTER_BUTTON));
545+ ON_CALL(mock_libinput, libinput_event_get_pointer_event(event))
546+ .WillByDefault(Return(pointer_event));
547+ ON_CALL(mock_libinput, libinput_event_pointer_get_time_usec(pointer_event))
548+ .WillByDefault(Return(event_time));
549+ ON_CALL(mock_libinput, libinput_event_pointer_get_button(pointer_event))
550+ .WillByDefault(Return(button));
551+ ON_CALL(mock_libinput, libinput_event_pointer_get_button_state(pointer_event))
552+ .WillByDefault(Return(state));
553 }
554
555 void setup_axis_event(libinput_event* event, uint64_t event_time, double horizontal, double vertical)
556 {
557 auto pointer_event = reinterpret_cast<libinput_event_pointer*>(event);
558
559- EXPECT_CALL(mock_libinput, libinput_event_get_type(event))
560- .WillRepeatedly(Return(LIBINPUT_EVENT_POINTER_AXIS));
561- EXPECT_CALL(mock_libinput, libinput_event_get_pointer_event(event))
562- .WillRepeatedly(Return(pointer_event));
563- EXPECT_CALL(mock_libinput, libinput_event_pointer_get_time_usec(pointer_event))
564- .WillRepeatedly(Return(event_time));
565- EXPECT_CALL(mock_libinput, libinput_event_pointer_has_axis(pointer_event, LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL))
566- .WillRepeatedly(Return(horizontal!=0.0));
567- EXPECT_CALL(mock_libinput, libinput_event_pointer_has_axis(pointer_event, LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL))
568- .WillRepeatedly(Return(vertical!=0.0));
569- EXPECT_CALL(mock_libinput, libinput_event_pointer_get_axis_value(pointer_event, LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL))
570- .WillRepeatedly(Return(vertical));
571- EXPECT_CALL(mock_libinput, libinput_event_pointer_get_axis_value(pointer_event, LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL))
572- .WillRepeatedly(Return(horizontal));
573+ ON_CALL(mock_libinput, libinput_event_get_type(event))
574+ .WillByDefault(Return(LIBINPUT_EVENT_POINTER_AXIS));
575+ ON_CALL(mock_libinput, libinput_event_get_pointer_event(event))
576+ .WillByDefault(Return(pointer_event));
577+ ON_CALL(mock_libinput, libinput_event_pointer_get_time_usec(pointer_event))
578+ .WillByDefault(Return(event_time));
579+ ON_CALL(mock_libinput, libinput_event_pointer_has_axis(pointer_event, LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL))
580+ .WillByDefault(Return(horizontal!=0.0));
581+ ON_CALL(mock_libinput, libinput_event_pointer_has_axis(pointer_event, LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL))
582+ .WillByDefault(Return(vertical!=0.0));
583+ ON_CALL(mock_libinput, libinput_event_pointer_get_axis_value(pointer_event, LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL))
584+ .WillByDefault(Return(vertical));
585+ ON_CALL(mock_libinput, libinput_event_pointer_get_axis_value(pointer_event, LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL))
586+ .WillByDefault(Return(horizontal));
587 }
588
589 void setup_touch_event(libinput_event* event, libinput_event_type type, uint64_t event_time, int slot, float x,
590@@ -241,73 +336,91 @@
591 {
592 auto touch_event = reinterpret_cast<libinput_event_touch*>(event);
593
594- EXPECT_CALL(mock_libinput, libinput_event_get_type(event))
595- .WillRepeatedly(Return(type));
596- EXPECT_CALL(mock_libinput, libinput_event_get_touch_event(event))
597- .WillRepeatedly(Return(touch_event));
598- EXPECT_CALL(mock_libinput, libinput_event_touch_get_slot(touch_event))
599- .WillRepeatedly(Return(slot));
600- EXPECT_CALL(mock_libinput, libinput_event_touch_get_x_transformed(touch_event, _))
601- .WillRepeatedly(Return(x));
602- EXPECT_CALL(mock_libinput, libinput_event_touch_get_y_transformed(touch_event, _))
603- .WillRepeatedly(Return(y));
604- EXPECT_CALL(mock_libinput, libinput_event_touch_get_time_usec(touch_event))
605- .WillRepeatedly(Return(event_time));
606- EXPECT_CALL(mock_libinput, libinput_event_touch_get_major_transformed(touch_event, _, _))
607- .WillRepeatedly(Return(major));
608- EXPECT_CALL(mock_libinput, libinput_event_touch_get_minor_transformed(touch_event, _, _))
609- .WillRepeatedly(Return(minor));
610- EXPECT_CALL(mock_libinput, libinput_event_touch_get_pressure(touch_event))
611- .WillRepeatedly(Return(pressure));
612+ ON_CALL(mock_libinput, libinput_event_get_type(event))
613+ .WillByDefault(Return(type));
614+ ON_CALL(mock_libinput, libinput_event_get_touch_event(event))
615+ .WillByDefault(Return(touch_event));
616+ ON_CALL(mock_libinput, libinput_event_touch_get_slot(touch_event))
617+ .WillByDefault(Return(slot));
618+ ON_CALL(mock_libinput, libinput_event_touch_get_x_transformed(touch_event, _))
619+ .WillByDefault(Return(x));
620+ ON_CALL(mock_libinput, libinput_event_touch_get_y_transformed(touch_event, _))
621+ .WillByDefault(Return(y));
622+ ON_CALL(mock_libinput, libinput_event_touch_get_time_usec(touch_event))
623+ .WillByDefault(Return(event_time));
624+ ON_CALL(mock_libinput, libinput_event_touch_get_major_transformed(touch_event, _, _))
625+ .WillByDefault(Return(major));
626+ ON_CALL(mock_libinput, libinput_event_touch_get_minor_transformed(touch_event, _, _))
627+ .WillByDefault(Return(minor));
628+ ON_CALL(mock_libinput, libinput_event_touch_get_pressure(touch_event))
629+ .WillByDefault(Return(pressure));
630 }
631
632 void setup_touch_up_event(libinput_event* event, uint64_t event_time, int slot)
633 {
634 auto touch_event = reinterpret_cast<libinput_event_touch*>(event);
635
636- EXPECT_CALL(mock_libinput, libinput_event_get_type(event))
637- .WillRepeatedly(Return(LIBINPUT_EVENT_TOUCH_UP));
638- EXPECT_CALL(mock_libinput, libinput_event_get_touch_event(event))
639- .WillRepeatedly(Return(touch_event));
640- EXPECT_CALL(mock_libinput, libinput_event_touch_get_slot(touch_event))
641- .WillRepeatedly(Return(slot));
642- EXPECT_CALL(mock_libinput, libinput_event_touch_get_x_transformed(touch_event, _))
643- .Times(0);
644- EXPECT_CALL(mock_libinput, libinput_event_touch_get_y_transformed(touch_event, _))
645- .Times(0);
646- EXPECT_CALL(mock_libinput, libinput_event_touch_get_x(touch_event))
647- .Times(0);
648- EXPECT_CALL(mock_libinput, libinput_event_touch_get_y(touch_event))
649- .Times(0);
650- EXPECT_CALL(mock_libinput, libinput_event_touch_get_time_usec(touch_event))
651- .WillRepeatedly(Return(event_time));
652- EXPECT_CALL(mock_libinput, libinput_event_touch_get_major_transformed(touch_event, _, _))
653- .Times(0);
654- EXPECT_CALL(mock_libinput, libinput_event_touch_get_minor_transformed(touch_event, _, _))
655- .Times(0);
656- EXPECT_CALL(mock_libinput, libinput_event_touch_get_pressure(touch_event))
657- .Times(0);
658-
659+ ON_CALL(mock_libinput, libinput_event_get_type(event))
660+ .WillByDefault(Return(LIBINPUT_EVENT_TOUCH_UP));
661+ ON_CALL(mock_libinput, libinput_event_get_touch_event(event))
662+ .WillByDefault(Return(touch_event));
663+ ON_CALL(mock_libinput, libinput_event_touch_get_slot(touch_event))
664+ .WillByDefault(Return(slot));
665+ ON_CALL(mock_libinput, libinput_event_touch_get_time_usec(touch_event))
666+ .WillByDefault(Return(event_time));
667 }
668
669 void setup_touch_frame(libinput_event* event)
670 {
671- EXPECT_CALL(mock_libinput, libinput_event_get_type(event))
672- .WillRepeatedly(Return(LIBINPUT_EVENT_TOUCH_FRAME));
673+ ON_CALL(mock_libinput, libinput_event_get_type(event))
674+ .WillByDefault(Return(LIBINPUT_EVENT_TOUCH_FRAME));
675 }
676 };
677
678+struct LibInputDeviceOnLaptopKeyboard : public LibInputDevice
679+{
680+ char const* keyboard_path = setup_laptop_keyboard(fake_device);
681+ mie::LibInputDevice keyboard{mir::report::null_input_report(), keyboard_path, mie::make_libinput_device(lib.get(), keyboard_path)};
682+};
683+
684+struct LibInputDeviceOnMouse : public LibInputDevice
685+{
686+ char const* mouse_path = setup_mouse(fake_device);
687+ mie::LibInputDevice mouse{mir::report::null_input_report(), mouse_path, mie::make_libinput_device(lib.get(), mouse_path)};
688+};
689+
690+struct LibInputDeviceOnLaptopKeyboardAndMouse : public LibInputDevice
691+{
692+ char const* mouse_path = setup_mouse(fake_device);
693+ char const* keyboard_path = setup_laptop_keyboard(fake_device);
694+ mie::LibInputDevice keyboard{mir::report::null_input_report(), keyboard_path, mie::make_libinput_device(lib.get(), keyboard_path)};
695+ mie::LibInputDevice mouse{mir::report::null_input_report(), mouse_path, mie::make_libinput_device(lib.get(), mouse_path)};
696+};
697+
698+struct LibInputDeviceOnTouchScreen : public LibInputDevice
699+{
700+ char const* touch_screen_path = setup_touch_screen(fake_device);
701+ mie::LibInputDevice touch_screen{mir::report::null_input_report(), touch_screen_path, mie::make_libinput_device(lib.get(), touch_screen_path)};
702+};
703+
704+struct LibInputDeviceOnTouchpad : public LibInputDevice
705+{
706+ char const* touchpad_path = setup_touchpad(fake_device);
707+ mie::LibInputDevice touchpad{mir::report::null_input_report(), touchpad_path, mie::make_libinput_device(lib.get(), touchpad_path)};
708+};
709 }
710
711 TEST_F(LibInputDevice, start_creates_and_unrefs_libinput_device_from_path)
712 {
713+ char const * path = setup_laptop_keyboard(fake_device);
714+
715 EXPECT_CALL(mock_libinput, libinput_path_add_device(fake_input,StrEq(path)))
716 .Times(1);
717 // according to manual libinput_path_add_device creates a temporary device with a ref count 0.
718 // hence it needs a manual ref call
719 EXPECT_CALL(mock_libinput, libinput_device_ref(fake_device))
720 .Times(1);
721- std::shared_ptr<libinput> lib = mie::make_libinput();
722+
723 mie::LibInputDevice dev(mir::report::null_input_report(),
724 path,
725 std::move(mie::make_libinput_device(lib.get(), path)));
726@@ -316,38 +429,32 @@
727
728 TEST_F(LibInputDevice, open_device_of_group)
729 {
730- std::shared_ptr<libinput> lib = mie::make_libinput();
731- char const* second_dev = "/dev/input/event13";
732- char const* second_umock_dev_name = "bluetooth-magic-trackpad";
733-
734- setup_device(second_fake_device, second_dev, second_umock_dev_name, 9663, 1234);
735+ char const* first_path = setup_laptop_keyboard(fake_device);
736+ char const* second_path = setup_trackpad(second_fake_device);
737
738 InSequence seq;
739- EXPECT_CALL(mock_libinput, libinput_path_add_device(fake_input,StrEq(path))).Times(1);
740+ EXPECT_CALL(mock_libinput, libinput_path_add_device(fake_input,StrEq(first_path))).Times(1);
741 // according to manual libinput_path_add_device creates a temporary device with a ref count 0.
742 // hence it needs a manual ref call
743 EXPECT_CALL(mock_libinput, libinput_device_ref(fake_device)).Times(1);
744- EXPECT_CALL(mock_libinput, libinput_path_add_device(fake_input,StrEq(second_dev))).Times(1);
745+ EXPECT_CALL(mock_libinput, libinput_path_add_device(fake_input,StrEq(second_path))).Times(1);
746 EXPECT_CALL(mock_libinput, libinput_device_ref(second_fake_device)).Times(1);
747
748 mie::LibInputDevice dev(mir::report::null_input_report(),
749- path,
750- std::move(mie::make_libinput_device(lib.get(), path)));
751- dev.add_device_of_group(second_dev, mie::make_libinput_device(lib.get(), second_dev));
752+ first_path,
753+ std::move(mie::make_libinput_device(lib.get(), first_path)));
754+ dev.add_device_of_group(second_path, mie::make_libinput_device(lib.get(), second_path));
755 dev.start(&mock_sink, &mock_builder);
756 }
757
758 TEST_F(LibInputDevice, input_info_combines_capabilities)
759 {
760- std::shared_ptr<libinput> lib = mie::make_libinput();
761- char const* second_dev = "/dev/input/event13";
762- char const* second_umock_dev_name = "bluetooth-magic-trackpad";
763-
764- setup_device(second_fake_device, second_dev, second_umock_dev_name, 9663, 1234);
765+ char const* first_dev = setup_laptop_keyboard(fake_device);
766+ char const* second_dev = setup_trackpad(second_fake_device);
767
768 mie::LibInputDevice dev(mir::report::null_input_report(),
769- path,
770- mie::make_libinput_device(lib.get(), path));
771+ first_dev,
772+ mie::make_libinput_device(lib.get(), first_dev));
773 dev.add_device_of_group(second_dev, mie::make_libinput_device(lib.get(), second_dev));
774 auto info = dev.get_device_info();
775
776@@ -358,7 +465,7 @@
777
778 TEST_F(LibInputDevice, removal_unrefs_libinput_device)
779 {
780- std::shared_ptr<libinput> lib = mie::make_libinput();
781+ char const* path = setup_laptop_keyboard(fake_device);
782
783 EXPECT_CALL(mock_libinput, libinput_device_unref(fake_device))
784 .Times(1);
785@@ -366,12 +473,8 @@
786 mie::LibInputDevice dev(mir::report::null_input_report(), path, mie::make_libinput_device(lib.get(), path));
787 }
788
789-
790-TEST_F(LibInputDevice, process_event_converts_key_event)
791+TEST_F(LibInputDeviceOnLaptopKeyboard, process_event_converts_key_event)
792 {
793- std::shared_ptr<libinput> lib = mie::make_libinput();
794- mie::LibInputDevice dev(mir::report::null_input_report(), path, mie::make_libinput_device(lib.get(), path));
795-
796 setup_key_event(fake_event_1, event_time_1, KEY_A, LIBINPUT_KEY_STATE_PRESSED);
797 setup_key_event(fake_event_2, event_time_2, KEY_A, LIBINPUT_KEY_STATE_RELEASED);
798
799@@ -380,17 +483,13 @@
800 EXPECT_CALL(mock_builder, key_event(time_stamp_2, mir_keyboard_action_up, _, KEY_A, mir_input_event_modifier_none));
801 EXPECT_CALL(mock_sink, handle_input(AllOf(mt::KeyOfScanCode(KEY_A),mt::KeyUpEvent())));
802
803- dev.start(&mock_sink, &mock_builder);
804- dev.process_event(fake_event_1);
805- dev.process_event(fake_event_2);
806+ keyboard.start(&mock_sink, &mock_builder);
807+ keyboard.process_event(fake_event_1);
808+ keyboard.process_event(fake_event_2);
809 }
810
811-TEST_F(LibInputDevice, process_event_accumulates_key_state)
812+TEST_F(LibInputDeviceOnLaptopKeyboard, process_event_accumulates_key_state)
813 {
814- std::shared_ptr<libinput> lib = mie::make_libinput();
815- mie::LibInputDevice dev(mir::report::null_input_report(), path, mie::make_libinput_device(lib.get(), path));
816-
817-
818 setup_key_event(fake_event_1, event_time_1, KEY_C, LIBINPUT_KEY_STATE_PRESSED);
819 setup_key_event(fake_event_2, event_time_2, KEY_LEFTALT, LIBINPUT_KEY_STATE_PRESSED);
820 setup_key_event(fake_event_3, event_time_3, KEY_C, LIBINPUT_KEY_STATE_RELEASED);
821@@ -400,56 +499,45 @@
822 EXPECT_CALL(mock_sink, handle_input(AllOf(mt::KeyOfScanCode(KEY_C),mt::KeyDownEvent())));
823 EXPECT_CALL(mock_builder, key_event(time_stamp_2, mir_keyboard_action_down, _, KEY_LEFTALT, mir_input_event_modifier_none));
824 EXPECT_CALL(mock_sink, handle_input(AllOf(mt::KeyOfScanCode(KEY_LEFTALT),mt::KeyDownEvent())));
825- EXPECT_CALL(mock_builder, key_event(time_stamp_3, mir_keyboard_action_up, _, KEY_C, mir_input_event_modifier_alt|mir_input_event_modifier_alt_left));
826+ EXPECT_CALL(mock_builder, key_event(time_stamp_3, mir_keyboard_action_up, _, KEY_C,
827+ mir_input_event_modifier_alt | mir_input_event_modifier_alt_left));
828 EXPECT_CALL(mock_sink, handle_input(AllOf(mt::KeyOfScanCode(KEY_C),
829- mt::KeyWithModifiers(
830- MirInputEventModifiers{
831- mir_input_event_modifier_alt|
832- mir_input_event_modifier_alt_left
833- }),
834+ mt::KeyWithModifiers(MirInputEventModifiers{
835+ mir_input_event_modifier_alt | mir_input_event_modifier_alt_left}),
836 mt::KeyUpEvent())));
837
838- dev.start(&mock_sink, &mock_builder);
839- dev.process_event(fake_event_1);
840- dev.process_event(fake_event_2);
841- dev.process_event(fake_event_3);
842+ keyboard.start(&mock_sink, &mock_builder);
843+ keyboard.process_event(fake_event_1);
844+ keyboard.process_event(fake_event_2);
845+ keyboard.process_event(fake_event_3);
846 }
847
848-TEST_F(LibInputDevice, process_event_converts_pointer_event)
849+TEST_F(LibInputDeviceOnMouse, process_event_converts_pointer_event)
850 {
851- std::shared_ptr<libinput> lib = mie::make_libinput();
852- mie::LibInputDevice dev(mir::report::null_input_report(), path, mie::make_libinput_device(lib.get(), path));
853-
854 float x = 15;
855 float y = 17;
856 setup_pointer_event(fake_event_1, event_time_1, x, y);
857
858 EXPECT_CALL(mock_sink, handle_input(mt::PointerEventWithPosition(x,y)));
859
860- dev.start(&mock_sink, &mock_builder);
861- dev.process_event(fake_event_1);
862+ mouse.start(&mock_sink, &mock_builder);
863+ mouse.process_event(fake_event_1);
864 }
865
866-TEST_F(LibInputDevice, process_event_provides_relative_coordinates)
867+TEST_F(LibInputDeviceOnMouse, process_event_provides_relative_coordinates)
868 {
869- std::shared_ptr<libinput> lib = mie::make_libinput();
870- mie::LibInputDevice dev(mir::report::null_input_report(), path, mie::make_libinput_device(lib.get(), path));
871-
872 float x = -5;
873 float y = 20;
874 setup_pointer_event(fake_event_1, event_time_1, x, y);
875
876 EXPECT_CALL(mock_sink, handle_input(mt::PointerEventWithDiff(x,y)));
877
878- dev.start(&mock_sink, &mock_builder);
879- dev.process_event(fake_event_1);
880+ mouse.start(&mock_sink, &mock_builder);
881+ mouse.process_event(fake_event_1);
882 }
883
884-TEST_F(LibInputDevice, process_event_accumulates_pointer_movement)
885+TEST_F(LibInputDeviceOnMouse, process_event_accumulates_pointer_movement)
886 {
887- std::shared_ptr<libinput> lib = mie::make_libinput();
888- mie::LibInputDevice dev(mir::report::null_input_report(), path, mie::make_libinput_device(lib.get(), path));
889-
890 float x1 = 15, x2 = 23;
891 float y1 = 17, y2 = 21;
892
893@@ -459,18 +547,16 @@
894 EXPECT_CALL(mock_sink, handle_input(mt::PointerEventWithPosition(x1,y1)));
895 EXPECT_CALL(mock_sink, handle_input(mt::PointerEventWithPosition(x1+x2,y1+y2)));
896
897- dev.start(&mock_sink, &mock_builder);
898- dev.process_event(fake_event_1);
899- dev.process_event(fake_event_2);
900+ mouse.start(&mock_sink, &mock_builder);
901+ mouse.process_event(fake_event_1);
902+ mouse.process_event(fake_event_2);
903 }
904
905-TEST_F(LibInputDevice, process_event_handles_press_and_release)
906+TEST_F(LibInputDeviceOnMouse, process_event_handles_press_and_release)
907 {
908- std::shared_ptr<libinput> lib = mie::make_libinput();
909- mie::LibInputDevice dev(mir::report::null_input_report(), path, mie::make_libinput_device(lib.get(), path));
910 float const x = 0;
911 float const y = 0;
912- geom::Point const pos{x,y};
913+ geom::Point const pos{x, y};
914
915 setup_button_event(fake_event_1, event_time_1, BTN_LEFT, LIBINPUT_BUTTON_STATE_PRESSED);
916 setup_button_event(fake_event_2, event_time_2, BTN_RIGHT, LIBINPUT_BUTTON_STATE_PRESSED);
917@@ -483,38 +569,34 @@
918 EXPECT_CALL(mock_sink, handle_input(mt::ButtonUpEventWithButton(pos, mir_pointer_button_secondary)));
919 EXPECT_CALL(mock_sink, handle_input(mt::ButtonUpEventWithButton(pos, mir_pointer_button_primary)));
920
921- dev.start(&mock_sink, &mock_builder);
922- dev.process_event(fake_event_1);
923- dev.process_event(fake_event_2);
924- dev.process_event(fake_event_3);
925- dev.process_event(fake_event_4);
926+ mouse.start(&mock_sink, &mock_builder);
927+ mouse.process_event(fake_event_1);
928+ mouse.process_event(fake_event_2);
929+ mouse.process_event(fake_event_3);
930+ mouse.process_event(fake_event_4);
931 }
932
933-TEST_F(LibInputDevice, process_event_handles_scroll)
934+TEST_F(LibInputDeviceOnMouse, process_event_handles_scroll)
935 {
936- std::shared_ptr<libinput> lib = mie::make_libinput();
937- mie::LibInputDevice dev(mir::report::null_input_report(), path, mie::make_libinput_device(lib.get(), path));
938-
939 setup_axis_event(fake_event_1, event_time_1, 0.0, 20.0);
940 setup_axis_event(fake_event_2, event_time_2, 5.0, 0.0);
941
942 InSequence seq;
943 // expect two scroll events..
944- EXPECT_CALL(mock_builder, pointer_event(time_stamp_1, mir_input_event_modifier_none, mir_pointer_action_motion, 0, 0.0f, 0.0f, 0.0f, 20.0f, 0.0f, 0.0f));
945+ EXPECT_CALL(mock_builder, pointer_event(time_stamp_1, mir_input_event_modifier_none, mir_pointer_action_motion, 0,
946+ 0.0f, 0.0f, 0.0f, 20.0f, 0.0f, 0.0f));
947 EXPECT_CALL(mock_sink, handle_input(mt::PointerAxisChange(mir_pointer_axis_vscroll, 20.0f)));
948- EXPECT_CALL(mock_builder, pointer_event(time_stamp_2, mir_input_event_modifier_none, mir_pointer_action_motion, 0, 0.0f, 0.0f, 5.0f, 0.0f, 0.0f, 0.0f));
949+ EXPECT_CALL(mock_builder, pointer_event(time_stamp_2, mir_input_event_modifier_none, mir_pointer_action_motion, 0,
950+ 0.0f, 0.0f, 5.0f, 0.0f, 0.0f, 0.0f));
951 EXPECT_CALL(mock_sink, handle_input(mt::PointerAxisChange(mir_pointer_axis_hscroll, 5.0f)));
952
953- dev.start(&mock_sink, &mock_builder);
954- dev.process_event(fake_event_1);
955- dev.process_event(fake_event_2);
956+ mouse.start(&mock_sink, &mock_builder);
957+ mouse.process_event(fake_event_1);
958+ mouse.process_event(fake_event_2);
959 }
960
961-TEST_F(LibInputDevice, process_event_handles_touch_down_events)
962+TEST_F(LibInputDeviceOnTouchScreen, process_event_handles_touch_down_events)
963 {
964- std::shared_ptr<libinput> lib = mie::make_libinput();
965- mie::LibInputDevice dev(mir::report::null_input_report(), path, mie::make_libinput_device(lib.get(), path));
966-
967 int slot = 0;
968 float major = 6;
969 float minor = 5;
970@@ -529,18 +611,15 @@
971 EXPECT_CALL(mock_builder, touch_event(time_stamp_1, mir_input_event_modifier_none));
972 EXPECT_CALL(mock_builder, add_touch(_, MirTouchId{0}, mir_touch_action_down, mir_touch_tooltype_finger, x, y,
973 pressure, major, minor, major));
974- EXPECT_CALL(mock_sink, handle_input(mt::TouchEvent(x,y)));
975+ EXPECT_CALL(mock_sink, handle_input(mt::TouchEvent(x, y)));
976
977- dev.start(&mock_sink, &mock_builder);
978- dev.process_event(fake_event_1);
979- dev.process_event(fake_event_2);
980+ touch_screen.start(&mock_sink, &mock_builder);
981+ touch_screen.process_event(fake_event_1);
982+ touch_screen.process_event(fake_event_2);
983 }
984
985-TEST_F(LibInputDevice, process_event_handles_touch_move_events)
986+TEST_F(LibInputDeviceOnTouchScreen, process_event_handles_touch_move_events)
987 {
988- std::shared_ptr<libinput> lib = mie::make_libinput();
989- mie::LibInputDevice dev(mir::report::null_input_report(), path, mie::make_libinput_device(lib.get(), path));
990-
991 int slot = 0;
992 float major = 6;
993 float minor = 5;
994@@ -557,16 +636,13 @@
995 pressure, major, minor, major));
996 EXPECT_CALL(mock_sink, handle_input(mt::TouchMovementEvent()));
997
998- dev.start(&mock_sink, &mock_builder);
999- dev.process_event(fake_event_1);
1000- dev.process_event(fake_event_2);
1001+ touch_screen.start(&mock_sink, &mock_builder);
1002+ touch_screen.process_event(fake_event_1);
1003+ touch_screen.process_event(fake_event_2);
1004 }
1005
1006-TEST_F(LibInputDevice, process_event_handles_touch_up_events_without_querying_properties)
1007+TEST_F(LibInputDeviceOnTouchScreen, process_event_handles_touch_up_events_without_querying_properties)
1008 {
1009- std::shared_ptr<libinput> lib = mie::make_libinput();
1010- mie::LibInputDevice dev(mir::report::null_input_report(), path, mie::make_libinput_device(lib.get(), path));
1011-
1012 int slot = 3;
1013 float major = 6;
1014 float minor = 5;
1015@@ -583,44 +659,30 @@
1016 EXPECT_CALL(mock_builder, touch_event(time_stamp_1, mir_input_event_modifier_none));
1017 EXPECT_CALL(mock_builder, add_touch(_, MirTouchId{slot}, mir_touch_action_down, mir_touch_tooltype_finger, x, y,
1018 pressure, major, minor, major));
1019- EXPECT_CALL(mock_sink, handle_input(mt::TouchEvent(x,y)));
1020+ EXPECT_CALL(mock_sink, handle_input(mt::TouchEvent(x, y)));
1021
1022 EXPECT_CALL(mock_builder, touch_event(time_stamp_2, mir_input_event_modifier_none));
1023 EXPECT_CALL(mock_builder, add_touch(_, MirTouchId{slot}, mir_touch_action_up, mir_touch_tooltype_finger, x, y,
1024 pressure, major, minor, major));
1025- EXPECT_CALL(mock_sink, handle_input(mt::TouchUpEvent(x,y)));
1026-
1027- dev.start(&mock_sink, &mock_builder);
1028- dev.process_event(fake_event_1);
1029- dev.process_event(fake_event_2);
1030- dev.process_event(fake_event_3);
1031- dev.process_event(fake_event_4);
1032-}
1033-
1034-TEST_F(LibInputDevice, provides_no_pointer_settings_for_non_pointing_devices)
1035-{
1036- char const keyboard_name[] = "usb-keyboard";
1037- char const keyboard_device_path[] = "/dev/input/event14";
1038- setup_device(second_fake_device, keyboard_device_path, keyboard_name, 1231, 4124);
1039-
1040- std::shared_ptr<libinput> lib = mie::make_libinput();
1041- mie::LibInputDevice dev(mir::report::null_input_report(), keyboard_device_path, mie::make_libinput_device(lib.get(), keyboard_device_path));
1042-
1043- auto ptr = dev.get_pointer_settings();
1044- EXPECT_THAT(ptr.is_set(), Eq(false));
1045-}
1046-
1047-TEST_F(LibInputDevice, reads_pointer_settings_from_libinput)
1048-{
1049- char const mouse_device_path[] = "/dev/input/event13";
1050- char const mouse_name[] = "usb-mouse";
1051- setup_device(second_fake_device, mouse_device_path, mouse_name, 1231, 4124);
1052-
1053- std::shared_ptr<libinput> lib = mie::make_libinput();
1054- mie::LibInputDevice dev(mir::report::null_input_report(), mouse_device_path, mie::make_libinput_device(lib.get(), mouse_device_path));
1055-
1056- setup_pointer_configuration(dev.device(), 1, mir_pointer_handedness_right);
1057- auto optional_settings = dev.get_pointer_settings();
1058+ EXPECT_CALL(mock_sink, handle_input(mt::TouchUpEvent(x, y)));
1059+
1060+ touch_screen.start(&mock_sink, &mock_builder);
1061+ touch_screen.process_event(fake_event_1);
1062+ touch_screen.process_event(fake_event_2);
1063+ touch_screen.process_event(fake_event_3);
1064+ touch_screen.process_event(fake_event_4);
1065+}
1066+
1067+TEST_F(LibInputDeviceOnLaptopKeyboard, provides_no_pointer_settings_for_non_pointing_devices)
1068+{
1069+ auto settings = keyboard.get_pointer_settings();
1070+ EXPECT_THAT(settings.is_set(), Eq(false));
1071+}
1072+
1073+TEST_F(LibInputDeviceOnMouse, reads_pointer_settings_from_libinput)
1074+{
1075+ setup_pointer_configuration(mouse.device(), 1, mir_pointer_handedness_right);
1076+ auto optional_settings = mouse.get_pointer_settings();
1077
1078 EXPECT_THAT(optional_settings.is_set(), Eq(true));
1079
1080@@ -630,8 +692,8 @@
1081 EXPECT_THAT(ptr_settings.horizontal_scroll_scale, Eq(1.0));
1082 EXPECT_THAT(ptr_settings.vertical_scroll_scale, Eq(1.0));
1083
1084- setup_pointer_configuration(dev.device(), 0.0, mir_pointer_handedness_left);
1085- optional_settings = dev.get_pointer_settings();
1086+ setup_pointer_configuration(mouse.device(), 0.0, mir_pointer_handedness_left);
1087+ optional_settings = mouse.get_pointer_settings();
1088
1089 EXPECT_THAT(optional_settings.is_set(), Eq(true));
1090
1091@@ -642,53 +704,31 @@
1092 EXPECT_THAT(ptr_settings.vertical_scroll_scale, Eq(1.0));
1093 }
1094
1095-TEST_F(LibInputDevice, applies_pointer_settings)
1096+TEST_F(LibInputDeviceOnMouse, applies_pointer_settings)
1097 {
1098- char const mouse_device_path[] = "/dev/input/event13";
1099- char const mouse_name[] = "usb-mouse";
1100- setup_device(second_fake_device, mouse_device_path, mouse_name, 1231, 4124);
1101-
1102- std::shared_ptr<libinput> lib = mie::make_libinput();
1103- mie::LibInputDevice dev(mir::report::null_input_report(), mouse_device_path, mie::make_libinput_device(lib.get(), path));
1104-
1105- setup_pointer_configuration(dev.device(), 1, mir_pointer_handedness_right);
1106- mi::PointerSettings settings(dev.get_pointer_settings().value());
1107+ setup_pointer_configuration(mouse.device(), 1, mir_pointer_handedness_right);
1108+ mi::PointerSettings settings(mouse.get_pointer_settings().value());
1109 settings.cursor_acceleration_bias = 1.1;
1110 settings.handedness = mir_pointer_handedness_left;
1111
1112- EXPECT_CALL(mock_libinput,libinput_device_config_accel_set_speed(dev.device(), 1.1)).Times(1);
1113- EXPECT_CALL(mock_libinput,libinput_device_config_left_handed_set(dev.device(), true)).Times(1);
1114+ EXPECT_CALL(mock_libinput,libinput_device_config_accel_set_speed(mouse.device(), 1.1)).Times(1);
1115+ EXPECT_CALL(mock_libinput,libinput_device_config_left_handed_set(mouse.device(), true)).Times(1);
1116
1117- dev.apply_settings(settings);
1118+ mouse.apply_settings(settings);
1119 }
1120
1121-TEST_F(LibInputDevice, denies_pointer_settings_on_keyboards)
1122+TEST_F(LibInputDeviceOnLaptopKeyboardAndMouse, denies_pointer_settings_on_keyboards)
1123 {
1124- char const mouse_device_path[] = "/dev/input/event13";
1125- char const mouse_name[] = "usb-mouse";
1126- setup_device(second_fake_device, mouse_device_path, mouse_name, 1231, 4124);
1127-
1128- std::shared_ptr<libinput> lib = mie::make_libinput();
1129- mie::LibInputDevice keyboard_dev(mir::report::null_input_report(), path, mie::make_libinput_device(lib.get(), path));
1130- mie::LibInputDevice mouse_dev(mir::report::null_input_report(), mouse_device_path, mie::make_libinput_device(lib.get(), path));
1131-
1132- auto settings_from_mouse = mouse_dev.get_pointer_settings();
1133+ auto settings_from_mouse = mouse.get_pointer_settings();
1134
1135 EXPECT_CALL(mock_libinput,libinput_device_config_accel_set_speed(_, _)).Times(0);
1136 EXPECT_CALL(mock_libinput,libinput_device_config_left_handed_set(_, _)).Times(0);
1137
1138- keyboard_dev.apply_settings(settings_from_mouse.value());
1139+ keyboard.apply_settings(settings_from_mouse.value());
1140 }
1141
1142-TEST_F(LibInputDevice, scroll_speed_scales_scroll_events)
1143+TEST_F(LibInputDeviceOnMouse, scroll_speed_scales_scroll_events)
1144 {
1145- char const mouse_device_path[] = "/dev/input/event13";
1146- char const mouse_name[] = "usb-mouse";
1147- setup_device(second_fake_device, mouse_device_path, mouse_name, 1231, 4124);
1148-
1149- std::shared_ptr<libinput> lib = mie::make_libinput();
1150- mie::LibInputDevice dev(mir::report::null_input_report(), mouse_device_path, mie::make_libinput_device(lib.get(), mouse_device_path));
1151-
1152 setup_axis_event(fake_event_1, event_time_1, 0.0, 3.0);
1153 setup_axis_event(fake_event_2, event_time_2, -2.0, 0.0);
1154
1155@@ -696,13 +736,65 @@
1156 EXPECT_CALL(mock_sink, handle_input(mt::PointerAxisChange(mir_pointer_axis_vscroll, -3.0f)));
1157 EXPECT_CALL(mock_sink, handle_input(mt::PointerAxisChange(mir_pointer_axis_hscroll, -10.0f)));
1158
1159- setup_pointer_configuration(dev.device(), 1, mir_pointer_handedness_right);
1160- mi::PointerSettings settings(dev.get_pointer_settings().value());
1161+ setup_pointer_configuration(mouse.device(), 1, mir_pointer_handedness_right);
1162+ mi::PointerSettings settings(mouse.get_pointer_settings().value());
1163 settings.vertical_scroll_scale = -1.0;
1164 settings.horizontal_scroll_scale = 5.0;
1165- dev.apply_settings(settings);
1166-
1167- dev.start(&mock_sink, &mock_builder);
1168- dev.process_event(fake_event_1);
1169- dev.process_event(fake_event_2);
1170+ mouse.apply_settings(settings);
1171+
1172+ mouse.start(&mock_sink, &mock_builder);
1173+ mouse.process_event(fake_event_1);
1174+ mouse.process_event(fake_event_2);
1175+}
1176+
1177+TEST_F(LibInputDeviceOnLaptopKeyboardAndMouse, provides_no_touchpad_settings_for_non_touchpad_devices)
1178+{
1179+ auto val = keyboard.get_touchpad_settings();
1180+ EXPECT_THAT(val.is_set(), Eq(false));
1181+ val = mouse.get_touchpad_settings();
1182+ EXPECT_THAT(val.is_set(), Eq(false));
1183+}
1184+
1185+TEST_F(LibInputDeviceOnTouchpad, reads_touchpad_settings_from_libinput)
1186+{
1187+ setup_touchpad_configuration(fake_device, mir_touchpad_click_mode_finger_count,
1188+ mir_touchpad_scroll_mode_edge_scroll, 0, true, false, true, false);
1189+
1190+ auto settings = touchpad.get_touchpad_settings().value();
1191+ EXPECT_THAT(settings.click_mode, Eq(mir_touchpad_click_mode_finger_count));
1192+ EXPECT_THAT(settings.scroll_mode, Eq(mir_touchpad_scroll_mode_edge_scroll));
1193+ EXPECT_THAT(settings.tap_to_click, Eq(true));
1194+ EXPECT_THAT(settings.disable_while_typing, Eq(false));
1195+ EXPECT_THAT(settings.disable_with_mouse, Eq(true));
1196+ EXPECT_THAT(settings.middle_mouse_button_emulation, Eq(false));
1197+}
1198+
1199+TEST_F(LibInputDeviceOnTouchpad, applies_touchpad_settings)
1200+{
1201+ setup_touchpad_configuration(fake_device, mir_touchpad_click_mode_finger_count,
1202+ mir_touchpad_scroll_mode_two_finger_scroll, 0, true, false, true, false);
1203+
1204+ mi::TouchpadSettings settings(touchpad.get_touchpad_settings().value());
1205+ settings.scroll_mode = mir_touchpad_scroll_mode_button_down_scroll;
1206+ settings.click_mode = mir_touchpad_click_mode_finger_count;
1207+ settings.button_down_scroll_button = KEY_A;
1208+ settings.tap_to_click = true;
1209+ settings.disable_while_typing = false;
1210+ settings.disable_with_mouse = true;
1211+ settings.middle_mouse_button_emulation = true;
1212+
1213+ EXPECT_CALL(mock_libinput,
1214+ libinput_device_config_scroll_set_method(touchpad.device(), LIBINPUT_CONFIG_SCROLL_ON_BUTTON_DOWN));
1215+ EXPECT_CALL(mock_libinput,
1216+ libinput_device_config_click_set_method(touchpad.device(), LIBINPUT_CONFIG_CLICK_METHOD_CLICKFINGER));
1217+ EXPECT_CALL(mock_libinput, libinput_device_config_scroll_set_button(touchpad.device(), KEY_A));
1218+ EXPECT_CALL(mock_libinput, libinput_device_config_tap_set_enabled(touchpad.device(), LIBINPUT_CONFIG_TAP_ENABLED));
1219+ EXPECT_CALL(mock_libinput,
1220+ libinput_device_config_dwt_set_enabled(touchpad.device(), LIBINPUT_CONFIG_DWT_DISABLED));
1221+ EXPECT_CALL(mock_libinput, libinput_device_config_send_events_set_mode(
1222+ touchpad.device(), LIBINPUT_CONFIG_SEND_EVENTS_DISABLED_ON_EXTERNAL_MOUSE));
1223+ EXPECT_CALL(mock_libinput, libinput_device_config_middle_emulation_set_enabled(
1224+ touchpad.device(), LIBINPUT_CONFIG_MIDDLE_EMULATION_ENABLED));
1225+
1226+ touchpad.apply_settings(settings);
1227 }
1228
1229=== modified file 'tests/unit-tests/input/test_default_input_device_hub.cpp'
1230--- tests/unit-tests/input/test_default_input_device_hub.cpp 2015-10-20 03:30:00 +0000
1231+++ tests/unit-tests/input/test_default_input_device_hub.cpp 2015-10-23 10:50:47 +0000
1232@@ -26,6 +26,7 @@
1233
1234 #include "mir/input/input_device.h"
1235 #include "mir/input/pointer_settings.h"
1236+#include "mir/input/touchpad_settings.h"
1237 #include "mir/input/device.h"
1238 #include "mir/input/touch_visualizer.h"
1239 #include "mir/input/input_device_observer.h"
1240@@ -88,6 +89,8 @@
1241 MOCK_METHOD0(get_device_info, mi::InputDeviceInfo());
1242 MOCK_CONST_METHOD0(get_pointer_settings, mir::optional_value<mi::PointerSettings>());
1243 MOCK_METHOD1(apply_settings, void(mi::PointerSettings const&));
1244+ MOCK_CONST_METHOD0(get_touchpad_settings, mir::optional_value<mi::TouchpadSettings>());
1245+ MOCK_METHOD1(apply_settings, void(mi::TouchpadSettings const&));
1246 };
1247
1248 template<typename Type>

Subscribers

People subscribed via source and target branches