Mir

Merge lp:~andreas-pokorny/mir/fix-1538632 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: 3288
Proposed branch: lp:~andreas-pokorny/mir/fix-1538632
Merge into: lp:mir
Diff against target: 462 lines (+96/-57)
12 files modified
src/include/server/mir/input/input_region.h (+2/-0)
src/server/input/default_configuration.cpp (+1/-1)
src/server/input/display_input_region.cpp (+4/-27)
src/server/input/display_input_region.h (+8/-8)
src/server/scene/default_configuration.cpp (+2/-1)
src/server/scene/mediating_display_changer.cpp (+20/-2)
src/server/scene/mediating_display_changer.h (+9/-1)
tests/include/mir/test/doubles/mock_input_region.h (+1/-0)
tests/integration-tests/input/test_single_seat_setup.cpp (+1/-0)
tests/unit-tests/input/test_default_input_device_hub.cpp (+1/-0)
tests/unit-tests/input/test_display_input_region.cpp (+8/-14)
tests/unit-tests/scene/test_mediating_display_changer.cpp (+39/-3)
To merge this branch: bzr merge lp:~andreas-pokorny/mir/fix-1538632
Reviewer Review Type Date Requested Status
Kevin DuBois (community) Approve
Alan Griffiths Approve
PS Jenkins bot (community) continuous-integration Approve
Mir CI Bot continuous-integration Approve
Alberto Aguirre (community) Needs Fixing
Review via email: mp+284186@code.launchpad.net

Commit message

input: Copy output rectangles when configuration changes

DisplayInputRegion used to calculate a set of rectangles on every mouse event, even when the set of outputs rarely changes. This change keeps a mir::geometry::Rectangles as cache. The actual dead lock of lp:1538632 was caused by the fact that DisplauInputRegion would use - to calculate the mir::geometry::Rectangles - the following locks in the given order:
  * mir::graphics::Display::configuration_mutex via for_each_display_sync_group()
  * mir::graphics::DisplayGroup::guard via for_each_display_buffer()

Simultaneously the SystemWindowManager::add_display method is called by the CompositingFunctor, which uses DisplaySyncGroup::for_each_display_buffer, and deeper in the call tree GraphicsDisplayLayout would request a copy of the DisplayConfiguration during place_in_output, which results in the reverse lock ordering:
  * mir::graphics::DisplayGroup::guard via for_each_display_buffer()
  * mir::graphics::Display::configuration_mutex via configration()

This change makes sure that the DisplayInputRegion does not touch any locks used by the graphics platform during input event handling.

Description of the change

The dead lock is resolved by caching the geom::Rectangles and updating the Rectangles of the DisplayInputRegion through the MediatingDisplayChanger... So the ugly-ish part of this MP is that MediatingDisplayChanger gets that extra knowledge of InputRegion and pushing updates to it. I do plan to resolve that in later steps by introducing the Seat concept for input and output devices. With that a connection between input device or output device changes would look more natuarl..

To post a comment you must log in.
Revision history for this message
Mir CI Bot (mir-ci-bot) wrote :

PASSED: Continuous integration, rev:3267
https://mir-jenkins.ubuntu.com/job/mir-ci/173/
Executed test runs:
    None: https://mir-jenkins.ubuntu.com/job/generic-update-mp/173/console

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

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

PASSED: Continuous integration, rev:3267
http://jenkins.qa.ubuntu.com/job/mir-ci/6143/
Executed test runs:
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-android-vivid-i386-build/5713
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-clang-vivid-amd64-build/4620
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-mediumtests-vivid-touch/5669
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-mediumtests-xenial-touch/346
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-xenial-amd64-ci/467
        deb: http://jenkins.qa.ubuntu.com/job/mir-xenial-amd64-ci/467/artifact/work/output/*zip*/output.zip
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-xenial-i386-ci/467
        deb: http://jenkins.qa.ubuntu.com/job/mir-xenial-i386-ci/467/artifact/work/output/*zip*/output.zip
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-mediumtests-builder-vivid-armhf/5666
        deb: http://jenkins.qa.ubuntu.com/job/mir-mediumtests-builder-vivid-armhf/5666/artifact/work/output/*zip*/output.zip
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-mediumtests-runner-touch/8096
    SUCCESS: http://s-jenkins.ubuntu-ci:8080/job/touch-flash-device/27098
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-mediumtests-builder-xenial-armhf/342
        deb: http://jenkins.qa.ubuntu.com/job/mir-mediumtests-builder-xenial-armhf/342/artifact/work/output/*zip*/output.zip
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-mediumtests-runner-xenial-touch/198
    SUCCESS: http://s-jenkins.ubuntu-ci:8080/job/touch-flash-device/27102

Click here to trigger a rebuild:
http://s-jenkins.ubuntu-ci:8080/job/mir-ci/6143/rebuild

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

+ virtual void set_display_configuration(mir::graphics::DisplayConfiguration const& config) = 0;

It seems odd that InputRegion "understands" DisplayConfiguration - I would expect it to only know about geometry (i.e. Point and Rectangle).

Did you consider a design with:

virtual void set_display_configuration(mir::geometry::Rectangles const& geometry) = 0;

I.e. building the display rects at the call site instead? (As MediatingDisplayChanger already uses the complete type.)

~~~~

PS I'd be tempted to add "auto geometry() -> Rectangles" to DisplayConfiguration

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

PASSED: Continuous integration, rev:3268
https://mir-jenkins.ubuntu.com/job/mir-ci/179/
Executed test runs:
    None: https://mir-jenkins.ubuntu.com/job/generic-update-mp/179/console

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

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

PASSED: Continuous integration, rev:3268
http://jenkins.qa.ubuntu.com/job/mir-ci/6150/
Executed test runs:
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-android-vivid-i386-build/5721
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-clang-vivid-amd64-build/4628
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-mediumtests-vivid-touch/5677
    FAILURE: http://jenkins.qa.ubuntu.com/job/mir-mediumtests-xenial-touch/353/console
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-xenial-amd64-ci/474
        deb: http://jenkins.qa.ubuntu.com/job/mir-xenial-amd64-ci/474/artifact/work/output/*zip*/output.zip
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-xenial-i386-ci/474
        deb: http://jenkins.qa.ubuntu.com/job/mir-xenial-i386-ci/474/artifact/work/output/*zip*/output.zip
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-mediumtests-builder-vivid-armhf/5674
        deb: http://jenkins.qa.ubuntu.com/job/mir-mediumtests-builder-vivid-armhf/5674/artifact/work/output/*zip*/output.zip
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-mediumtests-runner-touch/8104
    SUCCESS: http://s-jenkins.ubuntu-ci:8080/job/touch-flash-device/27133
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-mediumtests-builder-xenial-armhf/349
        deb: http://jenkins.qa.ubuntu.com/job/mir-mediumtests-builder-xenial-armhf/349/artifact/work/output/*zip*/output.zip
    FAILURE: http://jenkins.qa.ubuntu.com/job/mir-mediumtests-runner-xenial-touch/205/console
    SUCCESS: http://s-jenkins.ubuntu-ci:8080/job/touch-flash-device/27140

Click here to trigger a rebuild:
http://s-jenkins.ubuntu-ci:8080/job/mir-ci/6150/rebuild

review: Approve (continuous-integration)
Revision history for this message
Alberto Aguirre (albaguirre) wrote :

215 + if (output.power_mode == mir_power_mode_on && -output.current_mode_index < output.modes.size())

-output.current_mode_index

Why turn it negative?

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

PASSED: Continuous integration, rev:3269
https://mir-jenkins.ubuntu.com/job/mir-ci/183/
Executed test runs:
    None: https://mir-jenkins.ubuntu.com/job/generic-update-mp/183/console

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

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

PASSED: Continuous integration, rev:3269
http://jenkins.qa.ubuntu.com/job/mir-ci/6157/
Executed test runs:
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-android-vivid-i386-build/5730
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-clang-vivid-amd64-build/4637
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-mediumtests-vivid-touch/5686
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-mediumtests-xenial-touch/357
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-xenial-amd64-ci/481
        deb: http://jenkins.qa.ubuntu.com/job/mir-xenial-amd64-ci/481/artifact/work/output/*zip*/output.zip
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-xenial-i386-ci/481
        deb: http://jenkins.qa.ubuntu.com/job/mir-xenial-i386-ci/481/artifact/work/output/*zip*/output.zip
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-mediumtests-builder-vivid-armhf/5683
        deb: http://jenkins.qa.ubuntu.com/job/mir-mediumtests-builder-vivid-armhf/5683/artifact/work/output/*zip*/output.zip
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-mediumtests-runner-touch/8110
    SUCCESS: http://s-jenkins.ubuntu-ci:8080/job/touch-flash-device/27154
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-mediumtests-builder-xenial-armhf/353
        deb: http://jenkins.qa.ubuntu.com/job/mir-mediumtests-builder-xenial-armhf/353/artifact/work/output/*zip*/output.zip
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-mediumtests-runner-xenial-touch/209
    SUCCESS: http://s-jenkins.ubuntu-ci:8080/job/touch-flash-device/27155

Click here to trigger a rebuild:
http://s-jenkins.ubuntu-ci:8080/job/mir-ci/6157/rebuild

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

LGTM

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

looks good to me too

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

Alright. The only Needs Fixing was already resolved a few days ago. Top approving.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'src/include/server/mir/input/input_region.h'
--- src/include/server/mir/input/input_region.h 2015-02-22 07:46:25 +0000
+++ src/include/server/mir/input/input_region.h 2016-01-29 00:24:28 +0000
@@ -24,6 +24,7 @@
24namespace geometry24namespace geometry
25{25{
26struct Rectangle;26struct Rectangle;
27struct Rectangles;
27struct Point;28struct Point;
28}29}
29namespace input30namespace input
@@ -50,6 +51,7 @@
50 * @param [in,out] point the point to confine51 * @param [in,out] point the point to confine
51 */52 */
52 virtual void confine(geometry::Point& point) = 0;53 virtual void confine(geometry::Point& point) = 0;
54 virtual void set_input_rectangles(geometry::Rectangles const& rectangles) = 0;
5355
54protected:56protected:
55 InputRegion() = default;57 InputRegion() = default;
5658
=== modified file 'src/server/input/default_configuration.cpp'
--- src/server/input/default_configuration.cpp 2016-01-22 06:01:36 +0000
+++ src/server/input/default_configuration.cpp 2016-01-29 00:24:28 +0000
@@ -62,7 +62,7 @@
62 return input_region(62 return input_region(
63 [this]()63 [this]()
64 {64 {
65 return std::make_shared<mi::DisplayInputRegion>(the_display());65 return std::make_shared<mi::DisplayInputRegion>();
66 });66 });
67}67}
6868
6969
=== modified file 'src/server/input/display_input_region.cpp'
--- src/server/input/display_input_region.cpp 2016-01-20 23:59:18 +0000
+++ src/server/input/display_input_region.cpp 2016-01-29 00:24:28 +0000
@@ -17,8 +17,7 @@
17 */17 */
1818
19#include "display_input_region.h"19#include "display_input_region.h"
20#include "mir/graphics/display.h"20#include "mir/graphics/display_configuration.h"
21#include "mir/graphics/display_buffer.h"
2221
23#include "mir/geometry/rectangle.h"22#include "mir/geometry/rectangle.h"
24#include "mir/geometry/rectangles.h"23#include "mir/geometry/rectangles.h"
@@ -27,25 +26,14 @@
27namespace mg = mir::graphics;26namespace mg = mir::graphics;
28namespace geom = mir::geometry;27namespace geom = mir::geometry;
2928
30mi::DisplayInputRegion::DisplayInputRegion(29void mi::DisplayInputRegion::set_input_rectangles(geometry::Rectangles const& config)
31 std::shared_ptr<mg::Display> const& display)
32 : display{display}
33{30{
31 std::unique_lock<std::mutex> lock(rectangle_guard);
32 rectangles = config;
34}33}
3534
36geom::Rectangle mi::DisplayInputRegion::bounding_rectangle()35geom::Rectangle mi::DisplayInputRegion::bounding_rectangle()
37{36{
38 geom::Rectangles rectangles;
39
40 display->for_each_display_sync_group([&rectangles](mg::DisplaySyncGroup& group)
41 {
42 group.for_each_display_buffer(
43 [&rectangles](mg::DisplayBuffer const& buffer)
44 {
45 rectangles.add(buffer.view_area());
46 });
47 });
48
49 //TODO: This region is mainly used for scaling touchscreen coordinates, so the caller37 //TODO: This region is mainly used for scaling touchscreen coordinates, so the caller
50 // probably wants the full list of rectangles. Additional work is needed38 // probably wants the full list of rectangles. Additional work is needed
51 // to group a touchscreen with a display. So for now, just return the view area39 // to group a touchscreen with a display. So for now, just return the view area
@@ -59,16 +47,5 @@
5947
60void mi::DisplayInputRegion::confine(geom::Point& point)48void mi::DisplayInputRegion::confine(geom::Point& point)
61{49{
62 geom::Rectangles rectangles;
63
64 display->for_each_display_sync_group([&rectangles](mg::DisplaySyncGroup& group)
65 {
66 group.for_each_display_buffer(
67 [&rectangles](mg::DisplayBuffer const& buffer)
68 {
69 rectangles.add(buffer.view_area());
70 });
71 });
72
73 rectangles.confine(point);50 rectangles.confine(point);
74}51}
7552
=== modified file 'src/server/input/display_input_region.h'
--- src/server/input/display_input_region.h 2014-03-06 06:05:17 +0000
+++ src/server/input/display_input_region.h 2016-01-29 00:24:28 +0000
@@ -20,28 +20,28 @@
20#define MIR_INPUT_DISPLAY_INPUT_REGION_H_20#define MIR_INPUT_DISPLAY_INPUT_REGION_H_
2121
22#include "mir/input/input_region.h"22#include "mir/input/input_region.h"
23#include "mir/geometry/rectangles.h"
2324
24#include <memory>25#include <memory>
26#include <mutex>
2527
26namespace mir28namespace mir
27{29{
28namespace graphics
29{
30class Display;
31}
32namespace input30namespace input
33{31{
3432
35class DisplayInputRegion : public InputRegion33class DisplayInputRegion : public InputRegion
36{34{
37public:35public:
38 DisplayInputRegion(std::shared_ptr<graphics::Display> const& display);36 DisplayInputRegion() = default;
3937
40 geometry::Rectangle bounding_rectangle();38 geometry::Rectangle bounding_rectangle() override;
41 void confine(geometry::Point& point);39 void confine(geometry::Point& point) override;
40 void set_input_rectangles(geometry::Rectangles const& rectangles) override;
4241
43private:42private:
44 std::shared_ptr<graphics::Display> const display;43 std::mutex rectangle_guard;
44 geometry::Rectangles rectangles;
45};45};
4646
47}47}
4848
=== modified file 'src/server/scene/default_configuration.cpp'
--- src/server/scene/default_configuration.cpp 2016-01-20 23:59:18 +0000
+++ src/server/scene/default_configuration.cpp 2016-01-29 00:24:28 +0000
@@ -140,7 +140,8 @@
140 the_session_container(),140 the_session_container(),
141 the_session_event_handler_register(),141 the_session_event_handler_register(),
142 the_server_action_queue(),142 the_server_action_queue(),
143 the_display_configuration_report());143 the_display_configuration_report(),
144 the_input_region());
144 });145 });
145146
146}147}
147148
=== modified file 'src/server/scene/mediating_display_changer.cpp'
--- src/server/scene/mediating_display_changer.cpp 2016-01-20 23:59:18 +0000
+++ src/server/scene/mediating_display_changer.cpp 2016-01-29 00:24:28 +0000
@@ -23,6 +23,7 @@
23#include "session_event_handler_register.h"23#include "session_event_handler_register.h"
24#include "mir/graphics/display.h"24#include "mir/graphics/display.h"
25#include "mir/compositor/compositor.h"25#include "mir/compositor/compositor.h"
26#include "mir/geometry/rectangles.h"
26#include "mir/graphics/display_configuration_policy.h"27#include "mir/graphics/display_configuration_policy.h"
27#include "mir/graphics/display_configuration.h"28#include "mir/graphics/display_configuration.h"
28#include "mir/graphics/display_configuration_report.h"29#include "mir/graphics/display_configuration_report.h"
@@ -32,6 +33,7 @@
32namespace ms = mir::scene;33namespace ms = mir::scene;
33namespace mg = mir::graphics;34namespace mg = mir::graphics;
34namespace mc = mir::compositor;35namespace mc = mir::compositor;
36namespace mi = mir::input;
3537
36namespace38namespace
37{39{
@@ -66,7 +68,8 @@
66 std::shared_ptr<SessionContainer> const& session_container,68 std::shared_ptr<SessionContainer> const& session_container,
67 std::shared_ptr<SessionEventHandlerRegister> const& session_event_handler_register,69 std::shared_ptr<SessionEventHandlerRegister> const& session_event_handler_register,
68 std::shared_ptr<ServerActionQueue> const& server_action_queue,70 std::shared_ptr<ServerActionQueue> const& server_action_queue,
69 std::shared_ptr<mg::DisplayConfigurationReport> const& report)71 std::shared_ptr<mg::DisplayConfigurationReport> const& report,
72 std::shared_ptr<mi::InputRegion> const& region)
70 : display{display},73 : display{display},
71 compositor{compositor},74 compositor{compositor},
72 display_configuration_policy{display_configuration_policy},75 display_configuration_policy{display_configuration_policy},
@@ -75,7 +78,8 @@
75 server_action_queue{server_action_queue},78 server_action_queue{server_action_queue},
76 report{report},79 report{report},
77 base_configuration_{display->configuration()},80 base_configuration_{display->configuration()},
78 base_configuration_applied{true}81 base_configuration_applied{true},
82 region{region}
79{83{
80 session_event_handler_register->register_focus_change_handler(84 session_event_handler_register->register_focus_change_handler(
81 [this](std::shared_ptr<ms::Session> const& session)85 [this](std::shared_ptr<ms::Session> const& session)
@@ -112,6 +116,7 @@
112 });116 });
113117
114 report->initial_configuration(*base_configuration_);118 report->initial_configuration(*base_configuration_);
119 update_input_rectangles(*base_configuration_);
115}120}
116121
117void ms::MediatingDisplayChanger::configure(122void ms::MediatingDisplayChanger::configure(
@@ -204,6 +209,7 @@
204 {209 {
205 display->configure(*conf);210 display->configure(*conf);
206 }211 }
212 update_input_rectangles(*conf);
207213
208 base_configuration_applied = false;214 base_configuration_applied = false;
209}215}
@@ -282,3 +288,15 @@
282 send_config_to_all_sessions(conf);288 send_config_to_all_sessions(conf);
283 });289 });
284}290}
291
292void ms::MediatingDisplayChanger::update_input_rectangles(mg::DisplayConfiguration const& config)
293{
294 geometry::Rectangles rectangles;
295 config.for_each_output(
296 [&rectangles](mg::DisplayConfigurationOutput const& output)
297 {
298 if (output.power_mode == mir_power_mode_on && output.current_mode_index < output.modes.size())
299 rectangles.add(geometry::Rectangle(output.top_left, output.modes[output.current_mode_index].size));
300 });
301 region->set_input_rectangles(rectangles);
302}
285303
=== modified file 'src/server/scene/mediating_display_changer.h'
--- src/server/scene/mediating_display_changer.h 2016-01-20 23:59:18 +0000
+++ src/server/scene/mediating_display_changer.h 2016-01-29 00:24:28 +0000
@@ -22,6 +22,7 @@
22#include "mir/frontend/display_changer.h"22#include "mir/frontend/display_changer.h"
23#include "mir/display_changer.h"23#include "mir/display_changer.h"
24#include "mir/shell/display_configuration_controller.h"24#include "mir/shell/display_configuration_controller.h"
25#include "mir/input/input_region.h"
2526
26#include <mutex>27#include <mutex>
27#include <map>28#include <map>
@@ -37,6 +38,10 @@
37 class DisplayConfigurationReport;38 class DisplayConfigurationReport;
38}39}
39namespace compositor { class Compositor; }40namespace compositor { class Compositor; }
41namespace input
42{
43class InputRegion;
44}
40namespace scene45namespace scene
41{46{
42class SessionEventHandlerRegister;47class SessionEventHandlerRegister;
@@ -55,7 +60,8 @@
55 std::shared_ptr<SessionContainer> const& session_container,60 std::shared_ptr<SessionContainer> const& session_container,
56 std::shared_ptr<SessionEventHandlerRegister> const& session_event_handler_register,61 std::shared_ptr<SessionEventHandlerRegister> const& session_event_handler_register,
57 std::shared_ptr<ServerActionQueue> const& server_action_queue,62 std::shared_ptr<ServerActionQueue> const& server_action_queue,
58 std::shared_ptr<graphics::DisplayConfigurationReport> const& report);63 std::shared_ptr<graphics::DisplayConfigurationReport> const& report,
64 std::shared_ptr<input::InputRegion> const& region);
5965
60 /* From mir::frontend::DisplayChanger */66 /* From mir::frontend::DisplayChanger */
61 std::shared_ptr<graphics::DisplayConfiguration> base_configuration() override;67 std::shared_ptr<graphics::DisplayConfiguration> base_configuration() override;
@@ -83,6 +89,7 @@
83 void apply_base_config(SystemStateHandling pause_resume_system);89 void apply_base_config(SystemStateHandling pause_resume_system);
84 void send_config_to_all_sessions(90 void send_config_to_all_sessions(
85 std::shared_ptr<graphics::DisplayConfiguration> const& conf);91 std::shared_ptr<graphics::DisplayConfiguration> const& conf);
92 void update_input_rectangles(graphics::DisplayConfiguration const& conf);
8693
87 std::shared_ptr<graphics::Display> const display;94 std::shared_ptr<graphics::Display> const display;
88 std::shared_ptr<compositor::Compositor> const compositor;95 std::shared_ptr<compositor::Compositor> const compositor;
@@ -98,6 +105,7 @@
98 std::weak_ptr<frontend::Session> focused_session;105 std::weak_ptr<frontend::Session> focused_session;
99 std::shared_ptr<graphics::DisplayConfiguration> base_configuration_;106 std::shared_ptr<graphics::DisplayConfiguration> base_configuration_;
100 bool base_configuration_applied;107 bool base_configuration_applied;
108 std::shared_ptr<input::InputRegion> const region;
101};109};
102110
103}111}
104112
=== modified file 'tests/include/mir/test/doubles/mock_input_region.h'
--- tests/include/mir/test/doubles/mock_input_region.h 2013-07-19 14:12:57 +0000
+++ tests/include/mir/test/doubles/mock_input_region.h 2016-01-29 00:24:28 +0000
@@ -36,6 +36,7 @@
36{36{
37public:37public:
38 MOCK_METHOD0(bounding_rectangle, geometry::Rectangle());38 MOCK_METHOD0(bounding_rectangle, geometry::Rectangle());
39 MOCK_METHOD1(set_input_rectangles, void(geometry::Rectangles const&));
39 MOCK_METHOD1(confine, void(geometry::Point&));40 MOCK_METHOD1(confine, void(geometry::Point&));
40};41};
4142
4243
=== modified file 'tests/integration-tests/input/test_single_seat_setup.cpp'
--- tests/integration-tests/input/test_single_seat_setup.cpp 2016-01-22 04:38:07 +0000
+++ tests/integration-tests/input/test_single_seat_setup.cpp 2016-01-29 00:24:28 +0000
@@ -34,6 +34,7 @@
34#include "mir/input/device_capability.h"34#include "mir/input/device_capability.h"
35#include "mir/input/pointer_configuration.h"35#include "mir/input/pointer_configuration.h"
36#include "mir/input/touchpad_configuration.h"36#include "mir/input/touchpad_configuration.h"
37#include "mir/geometry/rectangles.h"
3738
38#include <gmock/gmock.h>39#include <gmock/gmock.h>
39#include <gtest/gtest.h>40#include <gtest/gtest.h>
4041
=== modified file 'tests/unit-tests/input/test_default_input_device_hub.cpp'
--- tests/unit-tests/input/test_default_input_device_hub.cpp 2016-01-22 06:01:36 +0000
+++ tests/unit-tests/input/test_default_input_device_hub.cpp 2016-01-29 00:24:28 +0000
@@ -29,6 +29,7 @@
29#include "mir/test/fake_shared.h"29#include "mir/test/fake_shared.h"
3030
31#include "mir/dispatch/action_queue.h"31#include "mir/dispatch/action_queue.h"
32#include "mir/geometry/rectangles.h"
32#include "mir/dispatch/multiplexing_dispatchable.h"33#include "mir/dispatch/multiplexing_dispatchable.h"
33#include "mir/events/event_builders.h"34#include "mir/events/event_builders.h"
34#include "mir/input/cursor_listener.h"35#include "mir/input/cursor_listener.h"
3536
=== modified file 'tests/unit-tests/input/test_display_input_region.cpp'
--- tests/unit-tests/input/test_display_input_region.cpp 2016-01-20 23:59:18 +0000
+++ tests/unit-tests/input/test_display_input_region.cpp 2016-01-29 00:24:28 +0000
@@ -18,22 +18,16 @@
1818
19#include "src/server/input/display_input_region.h"19#include "src/server/input/display_input_region.h"
2020
21#include "mir/test/doubles/null_display.h"
22#include "mir/test/doubles/stub_display.h"
23
24#include <vector>
25#include <tuple>21#include <tuple>
2622
27#include <gtest/gtest.h>23#include <gtest/gtest.h>
2824
29namespace mi = mir::input;25namespace mi = mir::input;
30namespace mg = mir::graphics;
31namespace mtd = mir::test::doubles;
32namespace geom = mir::geometry;26namespace geom = mir::geometry;
3327
34namespace28namespace
35{29{
36std::vector<geom::Rectangle> const rects{30geom::Rectangles const rects{
37 geom::Rectangle{{0,0}, {800,600}},31 geom::Rectangle{{0,0}, {800,600}},
38 geom::Rectangle{{0,600}, {100,100}},32 geom::Rectangle{{0,600}, {100,100}},
39 geom::Rectangle{{800,0}, {100,100}}33 geom::Rectangle{{800,0}, {100,100}}
@@ -43,9 +37,9 @@
43TEST(DisplayInputRegionTest, returns_correct_bounding_rectangle)37TEST(DisplayInputRegionTest, returns_correct_bounding_rectangle)
44{38{
45 geom::Rectangle const expected_bounding_rect{geom::Point{0,0}, geom::Size{800,600}};39 geom::Rectangle const expected_bounding_rect{geom::Point{0,0}, geom::Size{800,600}};
46 auto stub_display = std::make_shared<mtd::StubDisplay>(rects);
4740
48 mi::DisplayInputRegion input_region{stub_display};41 mi::DisplayInputRegion input_region;
42 input_region.set_input_rectangles(rects);
4943
50 auto rect = input_region.bounding_rectangle();44 auto rect = input_region.bounding_rectangle();
51 EXPECT_EQ(expected_bounding_rect, rect);45 EXPECT_EQ(expected_bounding_rect, rect);
@@ -53,9 +47,8 @@
5347
54TEST(DisplayInputRegionTest, confines_point_to_closest_valid_position)48TEST(DisplayInputRegionTest, confines_point_to_closest_valid_position)
55{49{
56 auto stub_display = std::make_shared<mtd::StubDisplay>(rects);50 mi::DisplayInputRegion input_region;
5751 input_region.set_input_rectangles(rects);
58 mi::DisplayInputRegion input_region{stub_display};
5952
60 std::vector<std::tuple<geom::Point,geom::Point>> point_tuples{53 std::vector<std::tuple<geom::Point,geom::Point>> point_tuples{
61 std::make_tuple(geom::Point{0,0}, geom::Point{0,0}),54 std::make_tuple(geom::Point{0,0}, geom::Point{0,0}),
@@ -83,10 +76,11 @@
8376
84TEST(DisplayInputRegionTest, returns_empty_bounding_rectangle_when_there_are_no_outputs)77TEST(DisplayInputRegionTest, returns_empty_bounding_rectangle_when_there_are_no_outputs)
85{78{
79 geom::Rectangles const empty_rects{};
86 geom::Rectangle const empty_rect{};80 geom::Rectangle const empty_rect{};
87 auto const stub_display = std::make_shared<mtd::StubDisplay>(0);
8881
89 mi::DisplayInputRegion input_region{stub_display};82 mi::DisplayInputRegion input_region;
83 input_region.set_input_rectangles(empty_rects);
9084
91 auto const bounding_rect = input_region.bounding_rectangle();85 auto const bounding_rect = input_region.bounding_rectangle();
92 EXPECT_EQ(empty_rect, bounding_rect);86 EXPECT_EQ(empty_rect, bounding_rect);
9387
=== modified file 'tests/unit-tests/scene/test_mediating_display_changer.cpp'
--- tests/unit-tests/scene/test_mediating_display_changer.cpp 2016-01-20 23:59:18 +0000
+++ tests/unit-tests/scene/test_mediating_display_changer.cpp 2016-01-29 00:24:28 +0000
@@ -20,6 +20,7 @@
20#include "src/server/scene/session_container.h"20#include "src/server/scene/session_container.h"
21#include "mir/graphics/display_configuration_policy.h"21#include "mir/graphics/display_configuration_policy.h"
22#include "mir/graphics/display_configuration_report.h"22#include "mir/graphics/display_configuration_report.h"
23#include "mir/geometry/rectangles.h"
23#include "src/server/scene/broadcasting_session_event_sink.h"24#include "src/server/scene/broadcasting_session_event_sink.h"
24#include "mir/server_action_queue.h"25#include "mir/server_action_queue.h"
2526
@@ -28,6 +29,7 @@
28#include "mir/test/doubles/null_display_configuration.h"29#include "mir/test/doubles/null_display_configuration.h"
29#include "mir/test/doubles/stub_display_configuration.h"30#include "mir/test/doubles/stub_display_configuration.h"
30#include "mir/test/doubles/mock_scene_session.h"31#include "mir/test/doubles/mock_scene_session.h"
32#include "mir/test/doubles/mock_input_region.h"
31#include "mir/test/doubles/stub_session.h"33#include "mir/test/doubles/stub_session.h"
32#include "mir/test/fake_shared.h"34#include "mir/test/fake_shared.h"
33#include "mir/test/display_config_matchers.h"35#include "mir/test/display_config_matchers.h"
@@ -135,7 +137,8 @@
135 mt::fake_shared(stub_session_container),137 mt::fake_shared(stub_session_container),
136 mt::fake_shared(session_event_sink),138 mt::fake_shared(session_event_sink),
137 mt::fake_shared(server_action_queue),139 mt::fake_shared(server_action_queue),
138 mt::fake_shared(display_configuration_report));140 mt::fake_shared(display_configuration_report),
141 mt::fake_shared(mock_input_region));
139 }142 }
140143
141 testing::NiceMock<MockDisplay> mock_display;144 testing::NiceMock<MockDisplay> mock_display;
@@ -146,6 +149,7 @@
146 mtd::StubDisplayConfig base_config;149 mtd::StubDisplayConfig base_config;
147 StubServerActionQueue server_action_queue;150 StubServerActionQueue server_action_queue;
148 StubDisplayConfigurationReport display_configuration_report;151 StubDisplayConfigurationReport display_configuration_report;
152 testing::NiceMock<mtd::MockInputRegion> mock_input_region;
149 std::shared_ptr<ms::MediatingDisplayChanger> changer;153 std::shared_ptr<ms::MediatingDisplayChanger> changer;
150};154};
151155
@@ -428,7 +432,8 @@
428 mt::fake_shared(stub_session_container),432 mt::fake_shared(stub_session_container),
429 mt::fake_shared(session_event_sink),433 mt::fake_shared(session_event_sink),
430 mt::fake_shared(mock_server_action_queue),434 mt::fake_shared(mock_server_action_queue),
431 mt::fake_shared(display_configuration_report));435 mt::fake_shared(display_configuration_report),
436 mt::fake_shared(mock_input_region));
432437
433 void const* owner{nullptr};438 void const* owner{nullptr};
434439
@@ -483,7 +488,8 @@
483 mt::fake_shared(stub_session_container),488 mt::fake_shared(stub_session_container),
484 mt::fake_shared(session_event_sink),489 mt::fake_shared(session_event_sink),
485 mt::fake_shared(mock_server_action_queue),490 mt::fake_shared(mock_server_action_queue),
486 mt::fake_shared(display_configuration_report));491 mt::fake_shared(display_configuration_report),
492 mt::fake_shared(mock_input_region));
487493
488 EXPECT_CALL(mock_server_action_queue, enqueue(_, _));494 EXPECT_CALL(mock_server_action_queue, enqueue(_, _));
489 session_event_sink.handle_focus_change(active_session);495 session_event_sink.handle_focus_change(active_session);
@@ -594,3 +600,33 @@
594600
595 changer->set_base_configuration(mt::fake_shared(conf));601 changer->set_base_configuration(mt::fake_shared(conf));
596}602}
603
604TEST_F(MediatingDisplayChangerTest, input_region_receives_display_configuration_on_start)
605{
606 using namespace testing;
607 EXPECT_CALL(mock_input_region, set_input_rectangles(_));
608
609 ms::MediatingDisplayChanger display_changer(
610 mt::fake_shared(mock_display),
611 mt::fake_shared(mock_compositor),
612 mt::fake_shared(mock_conf_policy),
613 mt::fake_shared(stub_session_container),
614 mt::fake_shared(session_event_sink),
615 mt::fake_shared(server_action_queue),
616 mt::fake_shared(display_configuration_report),
617 mt::fake_shared(mock_input_region));
618}
619
620TEST_F(MediatingDisplayChangerTest, notifies_input_region_on_new_configuration)
621{
622 using namespace testing;
623 mtd::NullDisplayConfiguration conf;
624 mir::geometry::Rectangles expected_rectangles;
625 EXPECT_CALL(mock_input_region, set_input_rectangles(expected_rectangles));
626
627 auto session = std::make_shared<mtd::StubSession>();
628
629 session_event_sink.handle_focus_change(session);
630 changer->configure(session,
631 mt::fake_shared(conf));
632}

Subscribers

People subscribed via source and target branches