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
=== modified file 'src/server/scene/mediating_display_changer.cpp'
--- src/server/scene/mediating_display_changer.cpp 2016-03-29 07:30:50 +0000
+++ src/server/scene/mediating_display_changer.cpp 2016-05-16 07:49:33 +0000
@@ -353,11 +353,10 @@
353void ms::MediatingDisplayChanger::update_input_rectangles(mg::DisplayConfiguration const& config)353void ms::MediatingDisplayChanger::update_input_rectangles(mg::DisplayConfiguration const& config)
354{354{
355 geometry::Rectangles rectangles;355 geometry::Rectangles rectangles;
356 config.for_each_output(356 config.for_each_output([&rectangles](mg::DisplayConfigurationOutput const& output) {
357 [&rectangles](mg::DisplayConfigurationOutput const& output)357 if (output.used && output.connected && output.power_mode == mir_power_mode_on &&
358 {358 output.current_mode_index < output.modes.size())
359 if (output.power_mode == mir_power_mode_on && output.current_mode_index < output.modes.size())359 rectangles.add(geometry::Rectangle(output.top_left, output.modes[output.current_mode_index].size));
360 rectangles.add(geometry::Rectangle(output.top_left, output.modes[output.current_mode_index].size));360 });
361 });
362 region->set_input_rectangles(rectangles);361 region->set_input_rectangles(rectangles);
363}362}
364363
=== modified file 'tests/unit-tests/scene/test_mediating_display_changer.cpp'
--- tests/unit-tests/scene/test_mediating_display_changer.cpp 2016-03-29 07:30:50 +0000
+++ tests/unit-tests/scene/test_mediating_display_changer.cpp 2016-05-16 07:49:33 +0000
@@ -45,12 +45,52 @@
45namespace mf = mir::frontend;45namespace mf = mir::frontend;
46namespace ms = mir::scene;46namespace ms = mir::scene;
47namespace mg = mir::graphics;47namespace mg = mir::graphics;
48namespace geom = mir::geometry;
4849
49using namespace testing;50using namespace testing;
5051
51namespace52namespace
52{53{
5354
55auto display_output(
56 mg::DisplayConfigurationOutputId id, geom::Point pos, geom::Size size, bool connected, bool used, MirPowerMode mode)
57 -> mg::DisplayConfigurationOutput
58{
59 return mg::DisplayConfigurationOutput{id,
60 mg::DisplayConfigurationCardId{0},
61 mg::DisplayConfigurationOutputType::lvds,
62 std::vector<MirPixelFormat>{mir_pixel_format_abgr_8888},
63 {mg::DisplayConfigurationMode{size, 60}},
64 0,
65 geom::Size{40, 40},
66 connected,
67 used,
68 pos,
69 0,
70 mir_pixel_format_abgr_8888,
71 mode,
72 mir_orientation_normal,
73 1.0f,
74 mir_form_factor_phone
75 };
76}
77
78struct TestDisplayConfiguration : mtd::NullDisplayConfiguration
79{
80 std::vector<mg::DisplayConfigurationOutput> const outputs;
81 TestDisplayConfiguration(std::vector<mg::DisplayConfigurationOutput> const& items)
82 : outputs{items} {}
83 void for_each_output(std::function<void(mg::DisplayConfigurationOutput const&)> fun) const override
84 {
85 for (auto const& output : outputs)
86 fun(output);
87 }
88 std::unique_ptr<mg::DisplayConfiguration> clone() const override
89 {
90 return std::make_unique<TestDisplayConfiguration>(outputs);
91 }
92};
93
54class MockDisplayConfigurationPolicy : public mg::DisplayConfigurationPolicy94class MockDisplayConfigurationPolicy : public mg::DisplayConfigurationPolicy
55{95{
56public:96public:
@@ -806,3 +846,104 @@
806 ASSERT_THAT(received_configuration, Not(Eq(nullptr)));846 ASSERT_THAT(received_configuration, Not(Eq(nullptr)));
807 EXPECT_THAT(*received_configuration, mt::DisplayConfigMatches(std::cref(*new_config)));847 EXPECT_THAT(*received_configuration, mt::DisplayConfigMatches(std::cref(*new_config)));
808}848}
849
850TEST_F(MediatingDisplayChangerTest, input_region_skipps_not_connected_displays)
851{
852 using namespace testing;
853
854 auto const connected = true;
855 auto const disconnected = false;
856 auto const used = true;
857 mir::geometry::Rectangles expected_rectangles;
858 expected_rectangles.add(geom::Rectangle{geom::Point{0,0}, geom::Size{100,100}});
859
860 TestDisplayConfiguration conf{{display_output(mg::DisplayConfigurationOutputId{0},
861 geom::Point{0, 0},
862 geom::Size{100, 100},
863 connected,
864 used,
865 mir_power_mode_on),
866 display_output(mg::DisplayConfigurationOutputId{1},
867 geom::Point{100, 0},
868 geom::Size{100, 100},
869 disconnected,
870 used,
871 mir_power_mode_on)}};
872
873 EXPECT_CALL(mock_input_region, set_input_rectangles(expected_rectangles));
874
875 auto session = std::make_shared<mtd::StubSession>();
876
877 session_event_sink.handle_focus_change(session);
878 changer->configure(session,
879 mt::fake_shared(conf));
880}
881
882TEST_F(MediatingDisplayChangerTest, input_region_accumulates_powered_and_connected_displays)
883{
884 using namespace testing;
885
886 auto const connected = true;
887 auto const first_monitor = geom::Rectangle{geom::Point{0, 0}, geom::Size{ 40, 40 }};
888 auto const second_monitor = geom::Rectangle{geom::Point{40, 0}, geom::Size{ 10, 10}};
889 auto const used = true;
890 mir::geometry::Rectangles expected_rectangles;
891 expected_rectangles.add(first_monitor);
892 expected_rectangles.add(second_monitor);
893
894 TestDisplayConfiguration conf{{display_output(mg::DisplayConfigurationOutputId{0},
895 first_monitor.top_left,
896 first_monitor.size,
897 connected,
898 used,
899 mir_power_mode_on),
900 display_output(mg::DisplayConfigurationOutputId{1},
901 second_monitor.top_left,
902 second_monitor.size,
903 connected,
904 used,
905 mir_power_mode_on)}};
906
907 EXPECT_CALL(mock_input_region, set_input_rectangles(expected_rectangles));
908
909 auto session = std::make_shared<mtd::StubSession>();
910
911 session_event_sink.handle_focus_change(session);
912 changer->configure(session,
913 mt::fake_shared(conf));
914}
915
916
917TEST_F(MediatingDisplayChangerTest, input_region_accumulates_powered_connected_skips_unused_displays)
918{
919 using namespace testing;
920
921 auto const connected = true;
922 auto const first_monitor = geom::Rectangle{geom::Point{0, 0}, geom::Size{ 40, 40 }};
923 auto const second_monitor = geom::Rectangle{geom::Point{40, 0}, geom::Size{ 10, 10}};
924 auto const not_used = false;
925 auto const used = true;
926 mir::geometry::Rectangles expected_rectangles;
927 expected_rectangles.add(second_monitor);
928
929 TestDisplayConfiguration conf{{display_output(mg::DisplayConfigurationOutputId{0},
930 first_monitor.top_left,
931 first_monitor.size,
932 connected,
933 not_used,
934 mir_power_mode_on),
935 display_output(mg::DisplayConfigurationOutputId{1},
936 second_monitor.top_left,
937 second_monitor.size,
938 connected,
939 used,
940 mir_power_mode_on)}};
941
942 EXPECT_CALL(mock_input_region, set_input_rectangles(expected_rectangles));
943
944 auto session = std::make_shared<mtd::StubSession>();
945
946 session_event_sink.handle_focus_change(session);
947 changer->configure(session,
948 mt::fake_shared(conf));
949}

Subscribers

People subscribed via source and target branches