Mir

Merge lp:~robertcarr/mir/fix-input-obscurance into lp:~mir-team/mir/trunk

Proposed by Robert Carr on 2013-07-08
Status: Merged
Approved by: Alan Griffiths on 2013-07-10
Approved revision: 827
Merged at revision: 835
Proposed branch: lp:~robertcarr/mir/fix-input-obscurance
Merge into: lp:~mir-team/mir/trunk
Diff against target: 153 lines (+126/-2)
2 files modified
3rd_party/android-input/android/frameworks/base/services/input/InputDispatcher.cpp (+0/-2)
tests/acceptance-tests/test_client_input.cpp (+126/-0)
To merge this branch: bzr merge lp:~robertcarr/mir/fix-input-obscurance
Reviewer Review Type Date Requested Status
PS Jenkins bot (community) continuous-integration Approve on 2013-07-10
Kevin DuBois (community) Approve on 2013-07-09
Alan Griffiths 2013-07-08 Approve on 2013-07-09
Review via email: mp+173586@code.launchpad.net

Commit message

Fix obscurance of touch events according to stacking.

Description of the change

The refactoring of InputDispatcher to use the InputTargetEnumerator interface resulted in an error on my part breaking obscurance of touch events by surfaces. This branch introduces an acceptance test to cover the case and contains a fix.

To post a comment you must log in.
Alan Griffiths (alan-griffiths) wrote :

LGTM

review: Approve
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Kevin DuBois (kdub) wrote :

looks good to me too

review: Approve
review: Approve (continuous-integration)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file '3rd_party/android-input/android/frameworks/base/services/input/InputDispatcher.cpp'
2--- 3rd_party/android-input/android/frameworks/base/services/input/InputDispatcher.cpp 2013-05-30 19:24:29 +0000
3+++ 3rd_party/android-input/android/frameworks/base/services/input/InputDispatcher.cpp 2013-07-08 20:03:25 +0000
4@@ -1151,8 +1151,6 @@
5
6 // Traverse windows from front to back to find touched window and outside targets.
7 mEnumerator->for_each([&](sp<InputWindowHandle> const& windowHandle){
8- if (newTouchedWindowHandle != NULL)
9- return;
10 const InputWindowInfo* windowInfo = windowHandle->getInfo();
11 int32_t flags = windowInfo->layoutParamsFlags;
12
13
14=== modified file 'tests/acceptance-tests/test_client_input.cpp'
15--- tests/acceptance-tests/test_client_input.cpp 2013-07-02 20:25:39 +0000
16+++ tests/acceptance-tests/test_client_input.cpp 2013-07-08 20:03:25 +0000
17@@ -23,6 +23,8 @@
18 #include "mir/shell/placement_strategy.h"
19 #include "mir/shell/surface_factory.h"
20 #include "mir/shell/surface.h"
21+#include "mir/surfaces/surface_controller.h"
22+#include "mir/surfaces/surface_stack_model.h"
23
24 #include "src/server/input/android/android_input_manager.h"
25 #include "src/server/input/android/android_input_targeter.h"
26@@ -643,3 +645,127 @@
27 } client_config;
28 launch_client_process(client_config);
29 }
30+
31+namespace
32+{
33+typedef std::map<std::string, ms::DepthId> DepthList;
34+
35+struct StackingSurfaceController : public ms::SurfaceController
36+{
37+ StackingSurfaceController(std::shared_ptr<ms::SurfaceStackModel> const& surface_stack_model, DepthList const& depths)
38+ : SurfaceController(surface_stack_model),
39+ surface_depths_by_name(depths)
40+ {
41+ }
42+
43+ std::weak_ptr<ms::Surface> create_surface(msh::SurfaceCreationParameters const& params) override
44+ {
45+ return surface_stack->create_surface(params, surface_depths_by_name[params.name]);
46+ }
47+
48+ DepthList surface_depths_by_name;
49+};
50+}
51+
52+TEST_F(TestClientInput, surfaces_obscure_motion_events_by_stacking)
53+{
54+ using namespace ::testing;
55+
56+ static std::string const test_client_name_1 = "1";
57+ static std::string const test_client_name_2 = "2";
58+
59+ static int const screen_width = 100;
60+ static int const screen_height = 100;
61+
62+ static geom::Rectangle const screen_geometry{geom::Point{geom::X{0}, geom::Y{0}},
63+ geom::Size{geom::Width{screen_width}, geom::Height{screen_height}}};
64+
65+ struct ServerConiguration : mtf::InputTestingServerConfiguration
66+ {
67+ std::shared_ptr<msh::PlacementStrategy> the_shell_placement_strategy() override
68+ {
69+ static GeometryList positions;
70+ positions[test_client_name_1] = screen_geometry;
71+
72+ auto smaller_geometry = screen_geometry;
73+ smaller_geometry.size.width = geom::Width{screen_width/2};
74+ positions[test_client_name_2] = smaller_geometry;
75+
76+ return std::make_shared<StaticPlacementStrategy>(positions);
77+ }
78+
79+ std::shared_ptr<msh::SurfaceBuilder> the_surface_builder() override
80+ {
81+ static DepthList depths;
82+ depths[test_client_name_1] = ms::DepthId{0};
83+ depths[test_client_name_2] = ms::DepthId{1};
84+
85+ return std::make_shared<StackingSurfaceController>(the_surface_stack_model(), depths);
86+ }
87+
88+ void inject_input() override
89+ {
90+ wait_until_client_appears(test_client_name_1);
91+ wait_until_client_appears(test_client_name_2);
92+
93+ // First we will move the cursor in to the region where client 2 obscures client 1
94+ fake_event_hub->synthesize_event(mis::a_motion_event().with_movement(1, 1));
95+ fake_event_hub->synthesize_event(mis::a_button_down_event().of_button(BTN_LEFT).with_action(mis::EventAction::Down));
96+ fake_event_hub->synthesize_event(mis::a_button_up_event().of_button(BTN_LEFT));
97+ // Now we move to the unobscured region of client 1
98+ fake_event_hub->synthesize_event(mis::a_motion_event().with_movement(50, 0));
99+ fake_event_hub->synthesize_event(mis::a_button_down_event().of_button(BTN_LEFT).with_action(mis::EventAction::Down));
100+ fake_event_hub->synthesize_event(mis::a_button_up_event().of_button(BTN_LEFT));
101+ }
102+ } server_config;
103+
104+ launch_server_process(server_config);
105+
106+ struct ClientConfigOne : InputClient
107+ {
108+ ClientConfigOne()
109+ : InputClient(test_client_name_1)
110+ {
111+ }
112+
113+ void expect_input(mt::WaitCondition& events_received) override
114+ {
115+ EXPECT_CALL(*handler, handle_input(HoverEnterEvent())).Times(AnyNumber());
116+ EXPECT_CALL(*handler, handle_input(HoverExitEvent())).Times(AnyNumber());
117+ EXPECT_CALL(*handler, handle_input(MovementEvent())).Times(AnyNumber());
118+
119+ {
120+ // We should only see one button event sequence.
121+ InSequence seq;
122+ EXPECT_CALL(*handler, handle_input(ButtonDownEvent(51, 1))).Times(1);
123+ EXPECT_CALL(*handler, handle_input(ButtonUpEvent(51, 1))).Times(1)
124+ .WillOnce(mt::WakeUp(&events_received));
125+ }
126+ }
127+ } client_config_1;
128+ launch_client_process(client_config_1);
129+
130+ struct ClientConfigTwo : InputClient
131+ {
132+ ClientConfigTwo()
133+ : InputClient(test_client_name_2)
134+ {
135+ }
136+
137+ void expect_input(mt::WaitCondition& events_received) override
138+ {
139+ EXPECT_CALL(*handler, handle_input(HoverEnterEvent())).Times(AnyNumber());
140+ EXPECT_CALL(*handler, handle_input(HoverExitEvent())).Times(AnyNumber());
141+ EXPECT_CALL(*handler, handle_input(MovementEvent())).Times(AnyNumber());
142+
143+ {
144+ // Likewise we should only see one button sequence.
145+ InSequence seq;
146+ EXPECT_CALL(*handler, handle_input(ButtonDownEvent(1, 1))).Times(1);
147+ EXPECT_CALL(*handler, handle_input(ButtonUpEvent(1, 1))).Times(1)
148+ .WillOnce(mt::WakeUp(&events_received));
149+ }
150+ }
151+ } client_config_2;
152+ launch_client_process(client_config_2);
153+}

Subscribers

People subscribed via source and target branches