Merge lp:~brandontschaefer/mir/add-client-confine-pointer-spec into lp:mir
- add-client-confine-pointer-spec
- Merge into development-branch
Status: | Merged |
---|---|
Approved by: | Andreas Pokorny |
Approved revision: | no longer in the source branch. |
Merged at revision: | 3536 |
Proposed branch: | lp:~brandontschaefer/mir/add-client-confine-pointer-spec |
Merge into: | lp:mir |
Diff against target: |
349 lines (+125/-13) 13 files modified
include/client/mir_toolkit/mir_surface.h (+10/-0) include/common/mir_toolkit/common.h (+10/-0) include/server/mir/shell/surface_specification.h (+1/-0) src/client/mir_surface.cpp (+1/-0) src/client/mir_surface.h (+1/-0) src/client/mir_surface_api.cpp (+10/-0) src/client/symbols.map (+1/-0) src/include/server/mir/shell/window_management_info.h (+1/-0) src/protobuf/mir_protobuf.proto (+1/-0) src/server/frontend/session_mediator.cpp (+1/-0) src/server/shell/canonical_window_manager.cpp (+1/-0) tests/acceptance-tests/test_client_library.cpp (+18/-0) tests/acceptance-tests/test_system_compositor_window_manager.cpp (+69/-13) |
To merge this branch: | bzr merge lp:~brandontschaefer/mir/add-client-confine-pointer-spec |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Andreas Pokorny (community) | Approve | ||
Mir CI Bot | continuous-integration | Approve | |
Cemil Azizoglu (community) | Approve | ||
Kevin DuBois (community) | Approve | ||
Review via email: mp+296724@code.launchpad.net |
Commit message
Adds a new surface spec that allows confine_pointer bool to be set for a surface specification. This will get to the WM which will then do the confinement work. This is merely a way for a client API to tell the WM that we need to confine a pointer on the surface.
Description of the change
Adds a new surface spec that allows confine_pointer bool to be set for a surface specification. This will get to the WM which will then do the confinement work. This is merely a way for a client API to tell the WM that we need to confine a pointer on the surface.
Mir CI Bot (mir-ci-bot) wrote : | # |
Mir CI Bot (mir-ci-bot) wrote : | # |
FAILED: Continuous integration, rev:3533
https:/
Executed test runs:
FAILURE: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
Click here to trigger a rebuild:
https:/
Mir CI Bot (mir-ci-bot) wrote : | # |
FAILED: Continuous integration, rev:3534
https:/
Executed test runs:
FAILURE: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
FAILURE: https:/
Click here to trigger a rebuild:
https:/
Mir CI Bot (mir-ci-bot) wrote : | # |
PASSED: Continuous integration, rev:3534
https:/
Executed test runs:
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
Click here to trigger a rebuild:
https:/
Kevin DuBois (kdub) wrote : | # |
seems reasonable, lgtm
Cemil Azizoglu (cemil-azizoglu) wrote : | # |
Would be better if 'mir_pointer_
33 +typedef enum MirPointerConfi
34 +{
35 + mir_pointer_
36 + mir_pointer_
37 +} MirPointerConfi
-------
s/can_set_
165 +TEST_F(
Mir CI Bot (mir-ci-bot) wrote : | # |
FAILED: Continuous integration, rev:3535
https:/
Executed test runs:
FAILURE: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
Click here to trigger a rebuild:
https:/
Andreas Pokorny (andreas-pokorny) wrote : | # |
looks reasonable..
Mir CI Bot (mir-ci-bot) wrote : | # |
PASSED: Continuous integration, rev:3536
https:/
Executed test runs:
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
Click here to trigger a rebuild:
https:/
Andreas Pokorny (andreas-pokorny) wrote : | # |
looks reasonable..
Preview Diff
1 | === modified file 'include/client/mir_toolkit/mir_surface.h' |
2 | --- include/client/mir_toolkit/mir_surface.h 2016-06-08 12:30:14 +0000 |
3 | +++ include/client/mir_toolkit/mir_surface.h 2016-06-08 21:17:20 +0000 |
4 | @@ -521,6 +521,16 @@ |
5 | void mir_surface_spec_set_shell_chrome(MirSurfaceSpec* spec, MirShellChrome style); |
6 | |
7 | /** |
8 | + * Attempts to set the pointer confinement spec for this surface |
9 | + * |
10 | + * This will request the window manager to confine the pointer to the surfaces region. |
11 | + * |
12 | + * \param [in] spec The spec to accumulate the request in. |
13 | + * \param [in] state The state you would like the pointer confinement to be in. |
14 | + */ |
15 | +void mir_surface_spec_set_pointer_confinement(MirSurfaceSpec* spec, MirPointerConfinementState state); |
16 | + |
17 | +/** |
18 | * Set the event handler to be called when events arrive for a surface. |
19 | * \warning event_handler could be called from another thread. You must do |
20 | * any locking appropriate to protect your data accessed in the |
21 | |
22 | === modified file 'include/common/mir_toolkit/common.h' |
23 | --- include/common/mir_toolkit/common.h 2016-05-03 06:55:25 +0000 |
24 | +++ include/common/mir_toolkit/common.h 2016-06-08 21:17:20 +0000 |
25 | @@ -221,6 +221,16 @@ |
26 | mir_shell_chrome_low, |
27 | } MirShellChrome; |
28 | |
29 | +/** |
30 | + * Pointer Confinement |
31 | + */ |
32 | + |
33 | +typedef enum MirPointerConfinementState |
34 | +{ |
35 | + mir_pointer_unconfined, |
36 | + mir_pointer_confined_to_surface, |
37 | +} MirPointerConfinementState; |
38 | + |
39 | /**@}*/ |
40 | |
41 | #endif |
42 | |
43 | === modified file 'include/server/mir/shell/surface_specification.h' |
44 | --- include/server/mir/shell/surface_specification.h 2016-05-03 06:55:25 +0000 |
45 | +++ include/server/mir/shell/surface_specification.h 2016-06-08 21:17:20 +0000 |
46 | @@ -83,6 +83,7 @@ |
47 | // it also has size instead of width + height |
48 | // Maybe SurfaceCreationParameters /HasA/ SurfaceSpecification? |
49 | mir::optional_value<MirShellChrome> shell_chrome; |
50 | + optional_value<MirPointerConfinementState> confine_pointer; |
51 | }; |
52 | } |
53 | } |
54 | |
55 | === modified file 'src/client/mir_surface.cpp' |
56 | --- src/client/mir_surface.cpp 2016-06-08 12:30:14 +0000 |
57 | +++ src/client/mir_surface.cpp 2016-06-08 21:17:20 +0000 |
58 | @@ -557,6 +557,7 @@ |
59 | COPY_IF_SET(width_inc); |
60 | COPY_IF_SET(height_inc); |
61 | COPY_IF_SET(shell_chrome); |
62 | + COPY_IF_SET(confine_pointer); |
63 | // min_aspect is a special case (below) |
64 | // max_aspect is a special case (below) |
65 | #undef COPY_IF_SET |
66 | |
67 | === modified file 'src/client/mir_surface.h' |
68 | --- src/client/mir_surface.h 2016-06-08 12:30:14 +0000 |
69 | +++ src/client/mir_surface.h 2016-06-08 21:17:20 +0000 |
70 | @@ -122,6 +122,7 @@ |
71 | mir::optional_value<AspectRatio> max_aspect; |
72 | mir::optional_value<std::vector<ContentInfo>> streams; |
73 | mir::optional_value<std::vector<MirRectangle>> input_shape; |
74 | + mir::optional_value<bool> confine_pointer; |
75 | |
76 | struct EventHandler |
77 | { |
78 | |
79 | === modified file 'src/client/mir_surface_api.cpp' |
80 | --- src/client/mir_surface_api.cpp 2016-05-03 06:55:25 +0000 |
81 | +++ src/client/mir_surface_api.cpp 2016-06-08 21:17:20 +0000 |
82 | @@ -693,6 +693,16 @@ |
83 | MIR_LOG_UNCAUGHT_EXCEPTION(ex); |
84 | } |
85 | |
86 | +void mir_surface_spec_set_pointer_confinement(MirSurfaceSpec* spec, MirPointerConfinementState state) |
87 | +try |
88 | +{ |
89 | + spec->confine_pointer = state; |
90 | +} |
91 | +catch (std::exception const& ex) |
92 | +{ |
93 | + MIR_LOG_UNCAUGHT_EXCEPTION(ex); |
94 | +} |
95 | + |
96 | MirWaitHandle* mir_surface_request_persistent_id(MirSurface* surface, mir_surface_id_callback callback, void* context) |
97 | { |
98 | mir::require(mir_surface_is_valid(surface)); |
99 | |
100 | === modified file 'src/client/symbols.map' |
101 | --- src/client/symbols.map 2016-06-06 11:51:31 +0000 |
102 | +++ src/client/symbols.map 2016-06-08 21:17:20 +0000 |
103 | @@ -396,4 +396,5 @@ |
104 | mir_input_device_state_event_pointer_buttons; |
105 | mir_input_device_state_event_time; |
106 | mir_input_device_state_event_device_pointer_buttons; |
107 | + mir_surface_spec_set_pointer_confinement; |
108 | } MIR_CLIENT_0.22; |
109 | |
110 | === modified file 'src/include/server/mir/shell/window_management_info.h' |
111 | --- src/include/server/mir/shell/window_management_info.h 2016-02-29 15:25:14 +0000 |
112 | +++ src/include/server/mir/shell/window_management_info.h 2016-06-08 21:17:20 +0000 |
113 | @@ -75,6 +75,7 @@ |
114 | mir::optional_value<shell::SurfaceAspectRatio> min_aspect; |
115 | mir::optional_value<shell::SurfaceAspectRatio> max_aspect; |
116 | mir::optional_value<graphics::DisplayConfigurationOutputId> output_id; |
117 | + mir::optional_value<bool> confine_pointer; |
118 | |
119 | void init_titlebar(std::shared_ptr <scene::Surface> const& surface); |
120 | |
121 | |
122 | === modified file 'src/protobuf/mir_protobuf.proto' |
123 | --- src/protobuf/mir_protobuf.proto 2016-05-04 01:48:16 +0000 |
124 | +++ src/protobuf/mir_protobuf.proto 2016-06-08 21:17:20 +0000 |
125 | @@ -84,6 +84,7 @@ |
126 | optional PersistentSurfaceId parent_persistent_id = 22; |
127 | repeated Rectangle input_shape = 23; |
128 | optional int32 shell_chrome = 24; |
129 | + optional int32 confine_pointer = 25; |
130 | } |
131 | |
132 | message StreamConfiguration { |
133 | |
134 | === modified file 'src/server/frontend/session_mediator.cpp' |
135 | --- src/server/frontend/session_mediator.cpp 2016-06-02 05:33:50 +0000 |
136 | +++ src/server/frontend/session_mediator.cpp 2016-06-08 21:17:20 +0000 |
137 | @@ -615,6 +615,7 @@ |
138 | COPY_IF_SET(width_inc); |
139 | COPY_IF_SET(height_inc); |
140 | COPY_IF_SET(shell_chrome); |
141 | + COPY_IF_SET(confine_pointer); |
142 | // min_aspect is a special case (below) |
143 | // max_aspect is a special case (below) |
144 | |
145 | |
146 | === modified file 'src/server/shell/canonical_window_manager.cpp' |
147 | --- src/server/shell/canonical_window_manager.cpp 2016-05-04 01:48:16 +0000 |
148 | +++ src/server/shell/canonical_window_manager.cpp 2016-06-08 21:17:20 +0000 |
149 | @@ -351,6 +351,7 @@ |
150 | COPY_IF_SET(min_aspect); |
151 | COPY_IF_SET(max_aspect); |
152 | COPY_IF_SET(output_id); |
153 | + COPY_IF_SET(confine_pointer); |
154 | |
155 | #undef COPY_IF_SET |
156 | |
157 | |
158 | === modified file 'tests/acceptance-tests/test_client_library.cpp' |
159 | --- tests/acceptance-tests/test_client_library.cpp 2016-01-29 08:18:22 +0000 |
160 | +++ tests/acceptance-tests/test_client_library.cpp 2016-06-08 21:17:20 +0000 |
161 | @@ -292,6 +292,24 @@ |
162 | mir_connection_release(connection); |
163 | } |
164 | |
165 | +TEST_F(ClientLibrary, can_set_pointer_confinement) |
166 | +{ |
167 | + connection = mir_connect_sync(new_connection().c_str(), __PRETTY_FUNCTION__); |
168 | + int const width = 640; |
169 | + int const height = 480; |
170 | + auto const format = mir_pixel_format_abgr_8888; |
171 | + auto const spec = |
172 | + mir_connection_create_spec_for_normal_surface(connection, width, height, format); |
173 | + mir_surface_spec_set_pointer_confinement(spec, mir_pointer_confined_to_surface); |
174 | + surface = mir_surface_create_sync(spec); |
175 | + mir_surface_spec_release(spec); |
176 | + |
177 | + EXPECT_THAT(surface, IsValid()); |
178 | + |
179 | + mir_surface_release_sync(surface); |
180 | + mir_connection_release(connection); |
181 | +} |
182 | + |
183 | TEST_F(ClientLibrary, can_set_surface_min_width) |
184 | { |
185 | connection = mir_connect_sync(new_connection().c_str(), __PRETTY_FUNCTION__); |
186 | |
187 | === modified file 'tests/acceptance-tests/test_system_compositor_window_manager.cpp' |
188 | --- tests/acceptance-tests/test_system_compositor_window_manager.cpp 2016-01-29 08:18:22 +0000 |
189 | +++ tests/acceptance-tests/test_system_compositor_window_manager.cpp 2016-06-08 21:17:20 +0000 |
190 | @@ -17,14 +17,18 @@ |
191 | */ |
192 | |
193 | #include "mir/shell/system_compositor_window_manager.h" |
194 | +#include "mir/shell/surface_specification.h" |
195 | #include "mir_toolkit/mir_client_library.h" |
196 | |
197 | #include "mir/geometry/rectangle.h" |
198 | #include "mir_test_framework/headless_test.h" |
199 | #include "mir/test/signal.h" |
200 | +#include "mir/test/spin_wait.h" |
201 | |
202 | #include "gmock/gmock.h" |
203 | |
204 | +#include <mutex> |
205 | + |
206 | namespace msh = mir::shell; |
207 | namespace mt = mir::test; |
208 | namespace mtf = mir_test_framework; |
209 | @@ -34,6 +38,8 @@ |
210 | |
211 | namespace |
212 | { |
213 | +std::chrono::seconds const max_wait{4}; |
214 | + |
215 | class SurfaceHandle |
216 | { |
217 | public: |
218 | @@ -56,20 +62,20 @@ |
219 | struct MockClient |
220 | { |
221 | explicit MockClient(char const* connect_string) : |
222 | - connection{mir_connect_sync(connect_string, __PRETTY_FUNCTION__)} |
223 | + connection_{mir_connect_sync(connect_string, __PRETTY_FUNCTION__)} |
224 | { |
225 | } |
226 | |
227 | MockClient(MockClient&& source) : |
228 | - connection{nullptr} |
229 | + connection_{nullptr} |
230 | { |
231 | - std::swap(connection, source.connection); |
232 | + std::swap(connection_, source.connection_); |
233 | } |
234 | |
235 | auto create_surface(int output_id) -> SurfaceHandle |
236 | { |
237 | auto const spec = mir_connection_create_spec_for_normal_surface( |
238 | - connection, 800, 600, mir_pixel_format_bgr_888); |
239 | + connection_, 800, 600, mir_pixel_format_bgr_888); |
240 | |
241 | mir_surface_spec_set_fullscreen_on_output(spec, output_id); |
242 | auto const surface = mir_surface_create_sync(spec); |
243 | @@ -82,10 +88,15 @@ |
244 | |
245 | void disconnect() |
246 | { |
247 | - if (connection) |
248 | - mir_connection_release(connection); |
249 | - |
250 | - connection = nullptr; |
251 | + if (connection_) |
252 | + mir_connection_release(connection_); |
253 | + |
254 | + connection_ = nullptr; |
255 | + } |
256 | + |
257 | + MirConnection* connection() |
258 | + { |
259 | + return connection_; |
260 | } |
261 | |
262 | ~MockClient() noexcept |
263 | @@ -96,7 +107,7 @@ |
264 | MOCK_METHOD2(surface_event, void(MirSurface* surface, const MirEvent* event)); |
265 | |
266 | private: |
267 | - MirConnection* connection{nullptr}; |
268 | + MirConnection* connection_{nullptr}; |
269 | |
270 | static void on_surface_event(MirSurface* surface, const MirEvent* event, void* client_ptr) |
271 | { |
272 | @@ -104,6 +115,28 @@ |
273 | } |
274 | }; |
275 | |
276 | +struct OverridenSystemCompositorWindowManager : msh::SystemCompositorWindowManager |
277 | +{ |
278 | + OverridenSystemCompositorWindowManager(msh::FocusController* focus_controller, |
279 | + std::shared_ptr<msh::DisplayLayout> const& display_layout, |
280 | + std::shared_ptr<mir::scene::SessionCoordinator> const& session_coordinator) : |
281 | + SystemCompositorWindowManager(focus_controller, display_layout, session_coordinator) |
282 | + { |
283 | + } |
284 | + |
285 | + void modify_surface( |
286 | + std::shared_ptr<mir::scene::Session> const& /*session*/, |
287 | + std::shared_ptr<mir::scene::Surface> const& /*surface*/, |
288 | + mir::shell::SurfaceSpecification const& modifications) override |
289 | + { |
290 | + std::unique_lock<decltype(mutex)> lock(mutex); |
291 | + last_mod = modifications; |
292 | + } |
293 | + |
294 | + std::mutex mutex; |
295 | + mir::shell::SurfaceSpecification last_mod; |
296 | +}; |
297 | + |
298 | struct SystemCompositorWindowManager : mtf::HeadlessTest |
299 | { |
300 | void SetUp() override |
301 | @@ -115,10 +148,12 @@ |
302 | server.override_the_window_manager_builder( |
303 | [this](msh::FocusController* focus_controller) |
304 | { |
305 | - return std::make_shared<msh::SystemCompositorWindowManager>( |
306 | - focus_controller, |
307 | - server.the_shell_display_layout(), |
308 | - server.the_session_coordinator()); |
309 | + wm = std::make_shared<OverridenSystemCompositorWindowManager>( |
310 | + focus_controller, |
311 | + server.the_shell_display_layout(), |
312 | + server.the_session_coordinator()); |
313 | + |
314 | + return wm; |
315 | }); |
316 | |
317 | start_server(); |
318 | @@ -133,6 +168,8 @@ |
319 | { |
320 | return MockClient(new_connection().c_str()); |
321 | } |
322 | + |
323 | + std::shared_ptr<OverridenSystemCompositorWindowManager> wm; |
324 | }; |
325 | |
326 | MATCHER_P(MirFocusEvent, expected, "") |
327 | @@ -204,3 +241,22 @@ |
328 | |
329 | EXPECT_FALSE(signal.wait_for(100ms)) << "Unexpected surface_focused event received"; |
330 | } |
331 | + |
332 | +TEST_F(SystemCompositorWindowManager, surface_gets_confine_pointer_set) |
333 | +{ |
334 | + auto client = connect_client(); |
335 | + |
336 | + auto surface = client.create_surface(1); |
337 | + |
338 | + MirSurfaceSpec* spec = mir_connection_create_spec_for_changes(client.connection()); |
339 | + mir_surface_spec_set_pointer_confinement(spec, mir_pointer_confined_to_surface); |
340 | + |
341 | + mir_surface_apply_spec(surface, spec); |
342 | + mir_surface_spec_release(spec); |
343 | + |
344 | + mt::spin_wait_for_condition_or_timeout([this] |
345 | + { |
346 | + std::unique_lock<decltype(wm->mutex)> lock(wm->mutex); |
347 | + return wm->last_mod.confine_pointer.is_set(); |
348 | + }, std::chrono::seconds{max_wait}); |
349 | +} |
FAILED: Continuous integration, rev:3532 /mir-jenkins. ubuntu. com/job/ mir-ci/ 1100/ /mir-jenkins. ubuntu. com/job/ build-mir/ 1219/console /mir-jenkins. ubuntu. com/job/ build-0- fetch/1269 /mir-jenkins. ubuntu. com/job/ build-1- sourcepkg/ release= vivid+overlay/ 1260 /mir-jenkins. ubuntu. com/job/ build-1- sourcepkg/ release= xenial/ 1260 /mir-jenkins. ubuntu. com/job/ build-2- binpkg- mir/arch= amd64,compiler= clang,platform= mesa,release= vivid+overlay/ 1229 /mir-jenkins. ubuntu. com/job/ build-2- binpkg- mir/arch= amd64,compiler= clang,platform= mesa,release= vivid+overlay/ 1229/artifact/ output/ *zip*/output. zip /mir-jenkins. ubuntu. com/job/ build-2- binpkg- mir/arch= amd64,compiler= gcc,platform= mesa,release= xenial/ 1229 /mir-jenkins. ubuntu. com/job/ build-2- binpkg- mir/arch= amd64,compiler= gcc,platform= mesa,release= xenial/ 1229/artifact/ output/ *zip*/output. zip /mir-jenkins. ubuntu. com/job/ build-2- binpkg- mir/arch= cross-armhf, compiler= gcc,platform= android, release= vivid+overlay/ 1229/console /mir-jenkins. ubuntu. com/job/ build-2- binpkg- mir/arch= cross-armhf, compiler= gcc,platform= android, release= vivid+overlay/ 1229/artifact/ output/ *zip*/output. zip /mir-jenkins. ubuntu. com/job/ build-2- binpkg- mir/arch= i386,compiler= gcc,platform= android, release= vivid+overlay/ 1229 /mir-jenkins. ubuntu. com/job/ build-2- binpkg- mir/arch= i386,compiler= gcc,platform= android, release= vivid+overlay/ 1229/artifact/ output/ *zip*/output. zip /mir-jenkins. ubuntu. com/job/ build-2- binpkg- mir/arch= i386,compiler= gcc,platform= mesa,release= xenial/ 1229 /mir-jenkins. ubuntu. com/job/ build-2- binpkg- mir/arch= i386,compiler= gcc,platform= mesa,release= xenial/ 1229/artifact/ output/ *zip*/output. zip
https:/
Executed test runs:
FAILURE: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
FAILURE: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
Click here to trigger a rebuild: /mir-jenkins. ubuntu. com/job/ mir-ci/ 1100/rebuild
https:/