Mir

Merge lp:~andreas-pokorny/mir/fix-1580774 into lp:mir

Proposed by Andreas Pokorny
Status: Merged
Approved by: Daniel van Vugt
Approved revision: no longer in the source branch.
Merged at revision: 3511
Proposed branch: lp:~andreas-pokorny/mir/fix-1580774
Merge into: lp:mir
Diff against target: 182 lines (+146/-6)
2 files modified
src/server/scene/mediating_display_changer.cpp (+5/-6)
tests/unit-tests/scene/test_mediating_display_changer.cpp (+141/-0)
To merge this branch: bzr merge lp:~andreas-pokorny/mir/fix-1580774
Reviewer Review Type Date Requested Status
Daniel van Vugt Abstain
Cemil Azizoglu (community) Approve
Mir CI Bot continuous-integration Approve
Kevin DuBois (community) Approve
Andreas Pokorny (community) Needs Information
Review via email: mp+294729@code.launchpad.net

Commit message

Use the connected status of the display output to configure pointer confinement

The virtual display is powered and available but not connected on startup, hence it would be accounted as reachable display area. And the mouse would be allowed to leave the first output, which leads to a termination of input events being sent to the nested session..

Description of the change

This is the hotfix that will probably be released within 0.22.1. and maybe also integrated into 0.23.

The virtual display is created 'on' has a valid mode but is not connected on startup. On M10 the screen is 1200x1920, and the virtual display is 1920x1080. As a result the allowed input area was calculated to be 1920x1920. In the coordinate system of usc, the surface of unity8 ends at x = 1200 moving beyond that point makes the cursor leave unity8. No more mouse events reach unity8. Unity8 maps that movement along the other axis, so there is a phantom border on the right that you cannot cross..

To post a comment you must log in.
Revision history for this message
Daniel van Vugt (vanvugt) wrote :

+ if (output.connected && output.power_mode == mir_power_mode_on &&

Should be just 'if (output.used &&'. Because we don't want to include unused but connected outputs, and we DO want to include used but sleeping outputs (they should turn on when the cursor moves anyway).

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

Same fix needs applying to lp:mir/0.22

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

I still think power_mode needs to be ignored. 'used' is the only field that matters. If you're moving the mouse then your used displays should be already on or turning on as a result of the mouse movement.

A monitor that is 'used' but also 'off' (which probably never exists anyway) should not in theory disallow the cursor moving to that monitor. In fact, you need the cursor to be able to reach it to ensure it turns on.

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

> I still think power_mode needs to be ignored. 'used' is the only field that
> matters. If you're moving the mouse then your used displays should be already
> on or turning on as a result of the mouse movement.
>
> A monitor that is 'used' but also 'off' (which probably never exists anyway)
> should not in theory disallow the cursor moving to that monitor. In fact, you
> need the cursor to be able to reach it to ensure it turns on.

Hmm I fully agree. But I am unsure if that works out - especially since unity8 and usc may have a different sense of cursor placement. Unity8 only extracts the relative motion, and may have a different resulting location.. Yes this is wrong we should have a better way to express that. So I think we should only do that change on lp:mir and let 0.22 and 0.23 use the logic as is.

* Needs discussion * Who would turn on the screen in that scenario?

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

^ discussion topic above ..

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

fix probably has to be ported to lp:mir/0.23 release as well

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

If the logic should just be to check for 'used' IMO, we may as well change it for 0.22/0.23.
If its prohibitively difficult to test the change for the fix (maybe its on a device we dont have?), then I'd be onboard with landing the existing code. So I guess my question is: Is it prohibitively tricky to quickly test the fix to unblock OTA11? If yes, then approve, else needs-fixing

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

From quick irc chat, seems that making usc more aware of the poitner might take some time, so +1.

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

PASSED: Continuous integration, rev:3508
https://mir-jenkins.ubuntu.com/job/mir-ci/981/
Executed test runs:
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-mir/1063
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-0-fetch/1110
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=vivid+overlay/1101
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=xenial/1101
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=clang,platform=mesa,release=vivid+overlay/1073
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=clang,platform=mesa,release=vivid+overlay/1073/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=xenial/1073
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=xenial/1073/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=cross-armhf,compiler=gcc,platform=android,release=vivid+overlay/1073
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=cross-armhf,compiler=gcc,platform=android,release=vivid+overlay/1073/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=android,release=vivid+overlay/1073
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=android,release=vivid+overlay/1073/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=mesa,release=xenial/1073
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=mesa,release=xenial/1073/artifact/output/*zip*/output.zip

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

review: Approve (continuous-integration)
Revision history for this message
Cemil Azizoglu (cemil-azizoglu) wrote :

Ok.

kdub, is it too late to cherry pick this into 0.23?

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

If you assume your shell turns on all monitors whenever the cursor moves at all, then this new version will work. I was only pushing for a simpler version with fewer preconditions because it's possible, and always desirable.

review: Abstain

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/server/scene/mediating_display_changer.cpp'
2--- src/server/scene/mediating_display_changer.cpp 2016-03-29 07:30:50 +0000
3+++ src/server/scene/mediating_display_changer.cpp 2016-05-16 07:49:33 +0000
4@@ -353,11 +353,10 @@
5 void ms::MediatingDisplayChanger::update_input_rectangles(mg::DisplayConfiguration const& config)
6 {
7 geometry::Rectangles rectangles;
8- config.for_each_output(
9- [&rectangles](mg::DisplayConfigurationOutput const& output)
10- {
11- if (output.power_mode == mir_power_mode_on && output.current_mode_index < output.modes.size())
12- rectangles.add(geometry::Rectangle(output.top_left, output.modes[output.current_mode_index].size));
13- });
14+ config.for_each_output([&rectangles](mg::DisplayConfigurationOutput const& output) {
15+ if (output.used && output.connected && output.power_mode == mir_power_mode_on &&
16+ output.current_mode_index < output.modes.size())
17+ rectangles.add(geometry::Rectangle(output.top_left, output.modes[output.current_mode_index].size));
18+ });
19 region->set_input_rectangles(rectangles);
20 }
21
22=== modified file 'tests/unit-tests/scene/test_mediating_display_changer.cpp'
23--- tests/unit-tests/scene/test_mediating_display_changer.cpp 2016-03-29 07:30:50 +0000
24+++ tests/unit-tests/scene/test_mediating_display_changer.cpp 2016-05-16 07:49:33 +0000
25@@ -45,12 +45,52 @@
26 namespace mf = mir::frontend;
27 namespace ms = mir::scene;
28 namespace mg = mir::graphics;
29+namespace geom = mir::geometry;
30
31 using namespace testing;
32
33 namespace
34 {
35
36+auto display_output(
37+ mg::DisplayConfigurationOutputId id, geom::Point pos, geom::Size size, bool connected, bool used, MirPowerMode mode)
38+ -> mg::DisplayConfigurationOutput
39+{
40+ return mg::DisplayConfigurationOutput{id,
41+ mg::DisplayConfigurationCardId{0},
42+ mg::DisplayConfigurationOutputType::lvds,
43+ std::vector<MirPixelFormat>{mir_pixel_format_abgr_8888},
44+ {mg::DisplayConfigurationMode{size, 60}},
45+ 0,
46+ geom::Size{40, 40},
47+ connected,
48+ used,
49+ pos,
50+ 0,
51+ mir_pixel_format_abgr_8888,
52+ mode,
53+ mir_orientation_normal,
54+ 1.0f,
55+ mir_form_factor_phone
56+ };
57+}
58+
59+struct TestDisplayConfiguration : mtd::NullDisplayConfiguration
60+{
61+ std::vector<mg::DisplayConfigurationOutput> const outputs;
62+ TestDisplayConfiguration(std::vector<mg::DisplayConfigurationOutput> const& items)
63+ : outputs{items} {}
64+ void for_each_output(std::function<void(mg::DisplayConfigurationOutput const&)> fun) const override
65+ {
66+ for (auto const& output : outputs)
67+ fun(output);
68+ }
69+ std::unique_ptr<mg::DisplayConfiguration> clone() const override
70+ {
71+ return std::make_unique<TestDisplayConfiguration>(outputs);
72+ }
73+};
74+
75 class MockDisplayConfigurationPolicy : public mg::DisplayConfigurationPolicy
76 {
77 public:
78@@ -806,3 +846,104 @@
79 ASSERT_THAT(received_configuration, Not(Eq(nullptr)));
80 EXPECT_THAT(*received_configuration, mt::DisplayConfigMatches(std::cref(*new_config)));
81 }
82+
83+TEST_F(MediatingDisplayChangerTest, input_region_skipps_not_connected_displays)
84+{
85+ using namespace testing;
86+
87+ auto const connected = true;
88+ auto const disconnected = false;
89+ auto const used = true;
90+ mir::geometry::Rectangles expected_rectangles;
91+ expected_rectangles.add(geom::Rectangle{geom::Point{0,0}, geom::Size{100,100}});
92+
93+ TestDisplayConfiguration conf{{display_output(mg::DisplayConfigurationOutputId{0},
94+ geom::Point{0, 0},
95+ geom::Size{100, 100},
96+ connected,
97+ used,
98+ mir_power_mode_on),
99+ display_output(mg::DisplayConfigurationOutputId{1},
100+ geom::Point{100, 0},
101+ geom::Size{100, 100},
102+ disconnected,
103+ used,
104+ mir_power_mode_on)}};
105+
106+ EXPECT_CALL(mock_input_region, set_input_rectangles(expected_rectangles));
107+
108+ auto session = std::make_shared<mtd::StubSession>();
109+
110+ session_event_sink.handle_focus_change(session);
111+ changer->configure(session,
112+ mt::fake_shared(conf));
113+}
114+
115+TEST_F(MediatingDisplayChangerTest, input_region_accumulates_powered_and_connected_displays)
116+{
117+ using namespace testing;
118+
119+ auto const connected = true;
120+ auto const first_monitor = geom::Rectangle{geom::Point{0, 0}, geom::Size{ 40, 40 }};
121+ auto const second_monitor = geom::Rectangle{geom::Point{40, 0}, geom::Size{ 10, 10}};
122+ auto const used = true;
123+ mir::geometry::Rectangles expected_rectangles;
124+ expected_rectangles.add(first_monitor);
125+ expected_rectangles.add(second_monitor);
126+
127+ TestDisplayConfiguration conf{{display_output(mg::DisplayConfigurationOutputId{0},
128+ first_monitor.top_left,
129+ first_monitor.size,
130+ connected,
131+ used,
132+ mir_power_mode_on),
133+ display_output(mg::DisplayConfigurationOutputId{1},
134+ second_monitor.top_left,
135+ second_monitor.size,
136+ connected,
137+ used,
138+ mir_power_mode_on)}};
139+
140+ EXPECT_CALL(mock_input_region, set_input_rectangles(expected_rectangles));
141+
142+ auto session = std::make_shared<mtd::StubSession>();
143+
144+ session_event_sink.handle_focus_change(session);
145+ changer->configure(session,
146+ mt::fake_shared(conf));
147+}
148+
149+
150+TEST_F(MediatingDisplayChangerTest, input_region_accumulates_powered_connected_skips_unused_displays)
151+{
152+ using namespace testing;
153+
154+ auto const connected = true;
155+ auto const first_monitor = geom::Rectangle{geom::Point{0, 0}, geom::Size{ 40, 40 }};
156+ auto const second_monitor = geom::Rectangle{geom::Point{40, 0}, geom::Size{ 10, 10}};
157+ auto const not_used = false;
158+ auto const used = true;
159+ mir::geometry::Rectangles expected_rectangles;
160+ expected_rectangles.add(second_monitor);
161+
162+ TestDisplayConfiguration conf{{display_output(mg::DisplayConfigurationOutputId{0},
163+ first_monitor.top_left,
164+ first_monitor.size,
165+ connected,
166+ not_used,
167+ mir_power_mode_on),
168+ display_output(mg::DisplayConfigurationOutputId{1},
169+ second_monitor.top_left,
170+ second_monitor.size,
171+ connected,
172+ used,
173+ mir_power_mode_on)}};
174+
175+ EXPECT_CALL(mock_input_region, set_input_rectangles(expected_rectangles));
176+
177+ auto session = std::make_shared<mtd::StubSession>();
178+
179+ session_event_sink.handle_focus_change(session);
180+ changer->configure(session,
181+ mt::fake_shared(conf));
182+}

Subscribers

People subscribed via source and target branches