Merge lp:~alan-griffiths/mir/drag-and-drop into lp:mir
- drag-and-drop
- Merge into development-branch
Status: | Merged |
---|---|
Merged at revision: | 4100 |
Proposed branch: | lp:~alan-griffiths/mir/drag-and-drop |
Merge into: | lp:mir |
Diff against target: |
2159 lines (+1040/-26) 77 files modified
examples/server_example_basic_window_manager.cpp (+8/-0) examples/server_example_basic_window_manager.h (+5/-0) include/client/mir/events/event_builders.h (+2/-0) include/client/mir_toolkit/extensions/drag_and_drop.h (+68/-0) include/core/mir_toolkit/common.h (+2/-0) include/server/mir/scene/null_surface_observer.h (+1/-0) include/server/mir/scene/surface.h (+1/-0) include/server/mir/scene/surface_observer.h (+2/-0) include/server/mir/shell/abstract_shell.h (+8/-0) include/server/mir/shell/focus_controller.h (+5/-0) include/server/mir/shell/input_targeter.h (+5/-0) include/server/mir/shell/shell.h (+4/-0) include/server/mir/shell/shell_wrapper.h (+8/-0) include/server/mir/shell/system_compositor_window_manager.h (+5/-0) include/server/mir/shell/window_manager.h (+5/-0) include/test/mir/test/doubles/mock_window_manager.h (+1/-0) include/test/mir/test/doubles/stub_surface.h (+1/-0) include/test/mir_test_framework/observant_shell.h (+8/-0) src/capnproto/mir_event.capnp (+5/-1) src/client/CMakeLists.txt (+2/-0) src/client/drag_and_drop.cpp (+67/-0) src/client/drag_and_drop.h (+32/-0) src/client/events/event_builders.cpp (+25/-0) src/client/mir_blob.cpp (+1/-8) src/client/mir_connection.cpp (+4/-0) src/client/mir_surface.cpp (+17/-0) src/client/mir_surface.h (+1/-0) src/client/rpc/mir_display_server.cpp (+9/-0) src/client/rpc/mir_display_server.h (+4/-0) src/client/symbols.map (+2/-0) src/common/events/pointer_event.cpp (+41/-3) src/common/events/surface_event.cpp (+39/-1) src/common/symbols.map (+4/-0) src/include/common/mir/events/pointer_event.h (+6/-1) src/include/common/mir/events/surface_event.h (+6/-1) src/include/common/mir/protobuf/display_server.h (+4/-0) src/include/common/mir_blob.h (+32/-0) src/include/server/mir/frontend/shell.h (+5/-0) src/include/server/mir/scene/surface_event_source.h (+1/-0) src/include/server/mir/scene/surface_observers.h (+1/-0) src/include/server/mir/shell/basic_window_manager.h (+15/-0) src/include/server/mir/shell/canonical_window_manager.h (+4/-0) src/protobuf/mir_protobuf.proto (+5/-0) src/protobuf/symbols.map (+26/-0) src/server/frontend/protobuf_message_processor.cpp (+4/-0) src/server/frontend/session_mediator.cpp (+20/-1) src/server/frontend/session_mediator.h (+4/-0) src/server/frontend/shell_wrapper.cpp (+8/-0) src/server/frontend/shell_wrapper.h (+5/-0) src/server/input/null_input_targeter.h (+3/-0) src/server/input/surface_input_dispatcher.cpp (+32/-6) src/server/input/surface_input_dispatcher.h (+5/-1) src/server/scene/basic_surface.cpp (+12/-0) src/server/scene/basic_surface.h (+1/-0) src/server/scene/legacy_surface_change_notification.cpp (+4/-0) src/server/scene/legacy_surface_change_notification.h (+1/-0) src/server/scene/null_surface_observer.cpp (+1/-0) src/server/scene/surface_event_source.cpp (+5/-0) src/server/shell/abstract_shell.cpp (+17/-0) src/server/shell/basic_window_manager.cpp (+21/-0) src/server/shell/canonical_window_manager.cpp (+13/-0) src/server/shell/frontend_shell.cpp (+10/-0) src/server/shell/frontend_shell.h (+5/-0) src/server/shell/shell_wrapper.cpp (+18/-0) src/server/shell/system_compositor_window_manager.cpp (+7/-0) src/server/symbols.map (+10/-0) tests/acceptance-tests/CMakeLists.txt (+2/-0) tests/acceptance-tests/drag_and_drop.cpp (+293/-0) tests/acceptance-tests/test_client_cursor_api.cpp (+1/-0) tests/include/mir/test/doubles/mock_input_targeter.h (+3/-0) tests/include/mir/test/doubles/mock_shell.h (+3/-0) tests/include/mir/test/doubles/stub_display_server.h (+4/-0) tests/include/mir/test/doubles/stub_input_targeter.h (+3/-0) tests/include/mir/test/doubles/stub_scene_surface.h (+1/-0) tests/mir_test_framework/observant_shell.cpp (+21/-2) tests/mir_test_framework/stub_surface.cpp (+4/-0) tests/unit-tests/client/test_client_mir_surface.cpp (+2/-1) |
To merge this branch: | bzr merge lp:~alan-griffiths/mir/drag-and-drop |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Alan Griffiths | Abstain | ||
Mir CI Bot | continuous-integration | Needs Fixing | |
Kevin DuBois (community) | Approve | ||
Review via email: mp+319581@code.launchpad.net |
Commit message
Initial support for Drag and Drop: tests (and implementation for) starting drag
Description of the change
Initial support for Drag and Drop: tests (and implementation for) starting drag
This covers the first few interactions of https:/
More to come...
Mir CI Bot (mir-ci-bot) wrote : | # |
Alan Griffiths (alan-griffiths) wrote : | # |
Oh! This one seems new...
15:13:59 [ RUN ] MirClientSurfac
15:13:59
15:13:59 GMOCK WARNING:
15:13:59 Uninteresting mock function call - returning directly.
15:13:59 Function call: adopted_
15:13:59 NOTE: You can safely ignore the above warning unless this call should not happen. Do not suppress it by blindly adding an EXPECT_CALL() if you don't mean to enforce the call. See https:/
15:13:59
15:13:59 GMOCK WARNING:
15:13:59 Uninteresting mock function call - taking default action specified at:
15:13:59 /<<BUILDDIR>
15:13:59 Function call: swap_interval()
15:13:59 Returns: 1
15:13:59 NOTE: You can safely ignore the above warning unless this call should not happen. Do not suppress it by blindly adding an EXPECT_CALL() if you don't mean to enforce the call. See https:/
15:13:59 ==11697== Conditional jump or move depends on uninitialised value(s)
15:13:59 ==11697== at 0x1CDDEB1: testing:
15:13:59 ==11697== by 0x1CD3C33: testing:
15:13:59 ==11697== by 0x1E8F58F: MirClientSurfac
15:13:59 ==11697== by 0x2D929FD: void testing:
15:13:59 ==11697== by 0x2D7EF8A: void testing:
15:13:59 ==11697== by 0x2D64405: testing:
15:13:59 ==11697== by 0x2D65372: testing:
15:13:59 ==11697== by 0x2D65B7B: testing:
15:13:59 ==11697== by 0x2D6DD20: testing:
15:13:59 ==11697== by 0x2D95F2D: bool testing:
15:13:59 ==11697== by 0x2D8111A: bool testin...
Alan Griffiths (alan-griffiths) wrote : | # |
> Oh! This one seems new...
>
> 15:13:59 [ RUN ] MirClientSurfac
Fixed
Mir CI Bot (mir-ci-bot) wrote : | # |
FAILED: Continuous integration, rev:4105
https:/
Executed test runs:
FAILURE: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
FAILURE: https:/
FAILURE: https:/
SUCCESS: https:/
deb: https:/
Click here to trigger a rebuild:
https:/
Alan Griffiths (alan-griffiths) wrote : | # |
I had almost forgotten about g++-4.9 - and I don't have a system with it to experiment on any longer.
Mir CI Bot (mir-ci-bot) wrote : | # |
PASSED: Continuous integration, rev:4106
https:/
Executed test runs:
SUCCESS: https:/
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:/
SUCCESS: https:/
deb: https:/
Click here to trigger a rebuild:
https:/
Kevin DuBois (kdub) wrote : | # |
nits:
+struct MyMirBlob : MirBlob
DnDBlob?
+ //std::
why commented out?
lgtm otherwise
Alan Griffiths (alan-griffiths) wrote : | # |
> nits:
> +struct MyMirBlob : MirBlob
> DnDBlob?
Is that clearer?
> + //std::
> why commented out?
Because that's what I would write if capnp would let it compile. ;)
I guess I can delete it, the code is clear enough without.
Mir CI Bot (mir-ci-bot) wrote : | # |
FAILED: Continuous integration, rev:4108
https:/
Executed test runs:
FAILURE: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
deb: https:/
FAILURE: https:/
FAILURE: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
Click here to trigger a rebuild:
https:/
Alan Griffiths (alan-griffiths) wrote : | # |
18:37:58 11: [ RUN ] DragAndDrop.
...
18:39:30 11: /<<BUILDDIR>
18:39:30 11: Value of: have_cookie.
18:39:30 11: Expected: is equal to true
18:39:30 11: Actual: false (of type bool)
18:39:30 11: ==27856== Invalid read of size 8
The memory errors and FD leaks that follow result from following the resulting nullptr.
~~~~
18:20:22 12: [ FAILED ] ClientLatency.
18:20:22 12: [ FAILED ] ClientLatency.
Mir CI Bot (mir-ci-bot) wrote : | # |
FAILED: Continuous integration, rev:4109
https:/
Executed test runs:
FAILURE: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
FAILURE: 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:/
Alan Griffiths (alan-griffiths) wrote : | # |
OK, that's a better failure mode.
I'm hoping the follow-up fixes the race that causes this, in which case I'll merge the MPs and resubmit.
11:34:50 9: [ RUN ] DragAndDrop.
11:34:50 9: [2017-03-14 11:34:50.894056] mirserver: Starting
11:34:50 9: [2017-03-14 11:34:50.897709] mirserver: Selected driver: mir:stub-graphics (version 0.27.0)
11:34:50 9: [2017-03-14 11:34:50.919402] mirserver: Using software cursor
11:34:51 9: [2017-03-14 11:34:51.080386] mirserver: Selected input driver: mir:stub-input (version: 0.27.0)
11:34:51 9: [2017-03-14 11:34:51.096963] mirserver: Mir version 0.27.0
11:34:51 9: [2017-03-14 11:34:51.103497] mirserver: Initial display configuration:
11:34:51 9: [2017-03-14 11:34:51.103792] mirserver: Output 1: VGA connected, used
11:34:51 9: [2017-03-14 11:34:51.104124] mirserver: Physical size 0.0" 0x0mm
11:34:51 9: [2017-03-14 11:34:51.104267] mirserver: Power is on
11:34:51 9: [2017-03-14 11:34:51.104432] mirserver: Current mode 800x600 60.00Hz
11:34:51 9: [2017-03-14 11:34:51.104592] mirserver: Preferred mode 800x600 60.00Hz
11:34:51 9: [2017-03-14 11:34:51.104726] mirserver: Orientation normal
11:34:51 9: [2017-03-14 11:34:51.104871] mirserver: Logical size 800x600
11:34:51 9: [2017-03-14 11:34:51.105010] mirserver: Logical position +0+0
11:34:51 9: [2017-03-14 11:34:51.105154] mirserver: Scaling factor: 1.00
11:36:21 9: /<<BUILDDIR>
11:36:21 9: Value of: have_cookie.
11:36:21 9: Expected: is equal to true
11:36:21 9: Actual: false (of type bool)
11:36:21 9: /<<BUILDDIR>
11:36:21 9: Value of: cookie.get()
11:36:21 9: Expected: isn't NULL
11:36:21 9: Actual: NULL (of type MirCookie const*)
11:36:21 9: [2017-03-14 11:36:21.680766] mirserver: Stopping
11:36:21 9: [ FAILED ] DragAndDrop.
Preview Diff
1 | === modified file 'examples/server_example_basic_window_manager.cpp' | |||
2 | --- examples/server_example_basic_window_manager.cpp 2017-01-18 02:29:37 +0000 | |||
3 | +++ examples/server_example_basic_window_manager.cpp 2017-03-14 11:00:58 +0000 | |||
4 | @@ -136,6 +136,14 @@ | |||
5 | 136 | policy->handle_raise_surface(session, surface); | 136 | policy->handle_raise_surface(session, surface); |
6 | 137 | } | 137 | } |
7 | 138 | 138 | ||
8 | 139 | void me::BasicWindowManager::handle_request_drag_and_drop( | ||
9 | 140 | std::shared_ptr<scene::Session> const& /*session*/, | ||
10 | 141 | std::shared_ptr<scene::Surface> const& /*surface*/, | ||
11 | 142 | uint64_t /*timestamp*/) | ||
12 | 143 | { | ||
13 | 144 | // Not supported in example servers | ||
14 | 145 | } | ||
15 | 146 | |||
16 | 139 | int me::BasicWindowManager::set_surface_attribute( | 147 | int me::BasicWindowManager::set_surface_attribute( |
17 | 140 | std::shared_ptr<scene::Session> const& /*session*/, | 148 | std::shared_ptr<scene::Session> const& /*session*/, |
18 | 141 | std::shared_ptr<scene::Surface> const& surface, | 149 | std::shared_ptr<scene::Surface> const& surface, |
19 | 142 | 150 | ||
20 | === modified file 'examples/server_example_basic_window_manager.h' | |||
21 | --- examples/server_example_basic_window_manager.h 2017-01-18 02:29:37 +0000 | |||
22 | +++ examples/server_example_basic_window_manager.h 2017-03-14 11:00:58 +0000 | |||
23 | @@ -174,6 +174,11 @@ | |||
24 | 174 | std::shared_ptr<scene::Surface> const& surface, | 174 | std::shared_ptr<scene::Surface> const& surface, |
25 | 175 | uint64_t timestamp) override; | 175 | uint64_t timestamp) override; |
26 | 176 | 176 | ||
27 | 177 | void handle_request_drag_and_drop( | ||
28 | 178 | std::shared_ptr<scene::Session> const& session, | ||
29 | 179 | std::shared_ptr<scene::Surface> const& surface, | ||
30 | 180 | uint64_t timestamp) override; | ||
31 | 181 | |||
32 | 177 | int set_surface_attribute( | 182 | int set_surface_attribute( |
33 | 178 | std::shared_ptr<scene::Session> const& /*session*/, | 183 | std::shared_ptr<scene::Session> const& /*session*/, |
34 | 179 | std::shared_ptr<scene::Surface> const& surface, | 184 | std::shared_ptr<scene::Surface> const& surface, |
35 | 180 | 185 | ||
36 | === modified file 'include/client/mir/events/event_builders.h' | |||
37 | --- include/client/mir/events/event_builders.h 2017-02-15 13:36:35 +0000 | |||
38 | +++ include/client/mir/events/event_builders.h 2017-03-14 11:00:58 +0000 | |||
39 | @@ -161,6 +161,8 @@ | |||
40 | 161 | void transform_positions(MirEvent& event, mir::geometry::Displacement const& movement); | 161 | void transform_positions(MirEvent& event, mir::geometry::Displacement const& movement); |
41 | 162 | void set_window_id(MirEvent& event, int window_id); | 162 | void set_window_id(MirEvent& event, int window_id); |
42 | 163 | 163 | ||
43 | 164 | EventUPtr make_start_drag_and_drop_event(frontend::SurfaceId const& surface_id, std::vector<uint8_t> const& handle); | ||
44 | 165 | void set_drag_and_drop_handle(MirEvent& event, std::vector<uint8_t> const& handle); | ||
45 | 164 | } | 166 | } |
46 | 165 | } | 167 | } |
47 | 166 | 168 | ||
48 | 167 | 169 | ||
49 | === added file 'include/client/mir_toolkit/extensions/drag_and_drop.h' | |||
50 | --- include/client/mir_toolkit/extensions/drag_and_drop.h 1970-01-01 00:00:00 +0000 | |||
51 | +++ include/client/mir_toolkit/extensions/drag_and_drop.h 2017-03-14 11:00:58 +0000 | |||
52 | @@ -0,0 +1,68 @@ | |||
53 | 1 | /* | ||
54 | 2 | * Copyright © 2017 Canonical Ltd. | ||
55 | 3 | * | ||
56 | 4 | * This program is free software: you can redistribute it and/or modify it | ||
57 | 5 | * under the terms of the GNU Lesser General Public License version 3, | ||
58 | 6 | * as published by the Free Software Foundation. | ||
59 | 7 | * | ||
60 | 8 | * This program is distributed in the hope that it will be useful, | ||
61 | 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
62 | 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
63 | 11 | * GNU Lesser General Public License for more details. | ||
64 | 12 | * | ||
65 | 13 | * You should have received a copy of the GNU Lesser General Public License | ||
66 | 14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
67 | 15 | * | ||
68 | 16 | * Authored by: Alan Griffiths <alan@octopull.co.uk> | ||
69 | 17 | */ | ||
70 | 18 | |||
71 | 19 | #ifndef MIR_DRAG_AND_DROP_H | ||
72 | 20 | #define MIR_DRAG_AND_DROP_H | ||
73 | 21 | |||
74 | 22 | #include "mir_toolkit/mir_extension_core.h" | ||
75 | 23 | #include "mir_toolkit/client_types.h" | ||
76 | 24 | |||
77 | 25 | #ifdef __cplusplus | ||
78 | 26 | extern "C" { | ||
79 | 27 | #endif | ||
80 | 28 | |||
81 | 29 | typedef struct MirDragAndDropV1 | ||
82 | 30 | { | ||
83 | 31 | /** | ||
84 | 32 | * Request drag and drop. If the request succeeds a window event with a | ||
85 | 33 | * "start drag" handle will be received. | ||
86 | 34 | * | ||
87 | 35 | * \warning An invalid cookie will terminate the client connection. | ||
88 | 36 | * | ||
89 | 37 | * \param [in] window The source window | ||
90 | 38 | * \param [in] cookie A cookie instance obtained from an input event. | ||
91 | 39 | */ | ||
92 | 40 | void (*request_drag_and_drop)(MirWindow* window, MirCookie const* cookie); | ||
93 | 41 | |||
94 | 42 | /** | ||
95 | 43 | * Retrieve any "drag & drop" handle associated with the event | ||
96 | 44 | * | ||
97 | 45 | * \param [in] event The event | ||
98 | 46 | * \return The associated drag handle or NULL | ||
99 | 47 | */ | ||
100 | 48 | MirBlob* (*start_drag_and_drop)(MirWindowEvent const* event); | ||
101 | 49 | |||
102 | 50 | /** | ||
103 | 51 | * Retrieve any "drag & drop" handle associated with the event. | ||
104 | 52 | * | ||
105 | 53 | * \param [in] event The event | ||
106 | 54 | * \return The associated drag handle or NULL | ||
107 | 55 | */ | ||
108 | 56 | MirBlob* (*pointer_drag_and_drop)(MirPointerEvent const* event); | ||
109 | 57 | |||
110 | 58 | } MirDragAndDropV1; | ||
111 | 59 | |||
112 | 60 | static inline MirDragAndDropV1 const* mir_drag_and_drop_v1(MirConnection* connection) | ||
113 | 61 | { | ||
114 | 62 | return (MirDragAndDropV1 const*) mir_connection_request_extension(connection, "mir_drag_and_drop", 1); | ||
115 | 63 | } | ||
116 | 64 | |||
117 | 65 | #ifdef __cplusplus | ||
118 | 66 | } | ||
119 | 67 | #endif | ||
120 | 68 | #endif //MIR_DRAG_AND_DROP_H | ||
121 | 0 | \ No newline at end of file | 69 | \ No newline at end of file |
122 | 1 | 70 | ||
123 | === modified file 'include/core/mir_toolkit/common.h' | |||
124 | --- include/core/mir_toolkit/common.h 2017-01-23 22:29:00 +0000 | |||
125 | +++ include/core/mir_toolkit/common.h 2017-03-14 11:00:58 +0000 | |||
126 | @@ -63,6 +63,7 @@ | |||
127 | 63 | mir_surface_attrib_dpi, | 63 | mir_surface_attrib_dpi, |
128 | 64 | mir_surface_attrib_visibility, | 64 | mir_surface_attrib_visibility, |
129 | 65 | mir_surface_attrib_preferred_orientation, | 65 | mir_surface_attrib_preferred_orientation, |
130 | 66 | mir_surface_attrib_drag_and_drop_handle, | ||
131 | 66 | /* Must be last */ | 67 | /* Must be last */ |
132 | 67 | mir_surface_attribs | 68 | mir_surface_attribs |
133 | 68 | } MirSurfaceAttrib __attribute__ ((deprecated("use MirWindowAttrib"))); | 69 | } MirSurfaceAttrib __attribute__ ((deprecated("use MirWindowAttrib"))); |
134 | @@ -84,6 +85,7 @@ | |||
135 | 84 | mir_window_attrib_dpi, | 85 | mir_window_attrib_dpi, |
136 | 85 | mir_window_attrib_visibility, | 86 | mir_window_attrib_visibility, |
137 | 86 | mir_window_attrib_preferred_orientation, | 87 | mir_window_attrib_preferred_orientation, |
138 | 88 | mir_window_attrib_drag_and_drop_handle, | ||
139 | 87 | /* Must be last */ | 89 | /* Must be last */ |
140 | 88 | mir_window_attribs | 90 | mir_window_attribs |
141 | 89 | } MirWindowAttrib; | 91 | } MirWindowAttrib; |
142 | 90 | 92 | ||
143 | === modified file 'include/server/mir/scene/null_surface_observer.h' | |||
144 | --- include/server/mir/scene/null_surface_observer.h 2017-02-15 13:36:35 +0000 | |||
145 | +++ include/server/mir/scene/null_surface_observer.h 2017-03-14 11:00:58 +0000 | |||
146 | @@ -47,6 +47,7 @@ | |||
147 | 47 | void cursor_image_removed() override; | 47 | void cursor_image_removed() override; |
148 | 48 | void placed_relative(geometry::Rectangle const& placement) override; | 48 | void placed_relative(geometry::Rectangle const& placement) override; |
149 | 49 | void input_consumed(MirEvent const* event) override; | 49 | void input_consumed(MirEvent const* event) override; |
150 | 50 | void start_drag_and_drop(std::vector<uint8_t> const& handle) override; | ||
151 | 50 | 51 | ||
152 | 51 | protected: | 52 | protected: |
153 | 52 | NullSurfaceObserver(NullSurfaceObserver const&) = delete; | 53 | NullSurfaceObserver(NullSurfaceObserver const&) = delete; |
154 | 53 | 54 | ||
155 | === modified file 'include/server/mir/scene/surface.h' | |||
156 | --- include/server/mir/scene/surface.h 2017-02-15 14:45:41 +0000 | |||
157 | +++ include/server/mir/scene/surface.h 2017-03-14 11:00:58 +0000 | |||
158 | @@ -116,6 +116,7 @@ | |||
159 | 116 | virtual MirPointerConfinementState confine_pointer_state() const = 0; | 116 | virtual MirPointerConfinementState confine_pointer_state() const = 0; |
160 | 117 | 117 | ||
161 | 118 | virtual void placed_relative(geometry::Rectangle const& placement) = 0; | 118 | virtual void placed_relative(geometry::Rectangle const& placement) = 0; |
162 | 119 | virtual void start_drag_and_drop(std::vector<uint8_t> const& handle) = 0; | ||
163 | 119 | }; | 120 | }; |
164 | 120 | } | 121 | } |
165 | 121 | } | 122 | } |
166 | 122 | 123 | ||
167 | === modified file 'include/server/mir/scene/surface_observer.h' | |||
168 | --- include/server/mir/scene/surface_observer.h 2017-02-15 13:36:35 +0000 | |||
169 | +++ include/server/mir/scene/surface_observer.h 2017-03-14 11:00:58 +0000 | |||
170 | @@ -27,6 +27,7 @@ | |||
171 | 27 | 27 | ||
172 | 28 | #include <glm/glm.hpp> | 28 | #include <glm/glm.hpp> |
173 | 29 | #include <string> | 29 | #include <string> |
174 | 30 | #include <vector> | ||
175 | 30 | 31 | ||
176 | 31 | namespace mir | 32 | namespace mir |
177 | 32 | { | 33 | { |
178 | @@ -62,6 +63,7 @@ | |||
179 | 62 | virtual void cursor_image_removed() = 0; | 63 | virtual void cursor_image_removed() = 0; |
180 | 63 | virtual void placed_relative(geometry::Rectangle const& placement) = 0; | 64 | virtual void placed_relative(geometry::Rectangle const& placement) = 0; |
181 | 64 | virtual void input_consumed(MirEvent const* event) = 0; | 65 | virtual void input_consumed(MirEvent const* event) = 0; |
182 | 66 | virtual void start_drag_and_drop(std::vector<uint8_t> const& handle) = 0; | ||
183 | 65 | 67 | ||
184 | 66 | protected: | 68 | protected: |
185 | 67 | SurfaceObserver() = default; | 69 | SurfaceObserver() = default; |
186 | 68 | 70 | ||
187 | === modified file 'include/server/mir/shell/abstract_shell.h' | |||
188 | --- include/server/mir/shell/abstract_shell.h 2017-01-18 02:29:37 +0000 | |||
189 | +++ include/server/mir/shell/abstract_shell.h 2017-03-14 11:00:58 +0000 | |||
190 | @@ -82,6 +82,11 @@ | |||
191 | 82 | std::shared_ptr<scene::Surface> const& surface, | 82 | std::shared_ptr<scene::Surface> const& surface, |
192 | 83 | uint64_t timestamp) override; | 83 | uint64_t timestamp) override; |
193 | 84 | 84 | ||
194 | 85 | void request_drag_and_drop( | ||
195 | 86 | std::shared_ptr<scene::Session> const& session, | ||
196 | 87 | std::shared_ptr<scene::Surface> const& surface, | ||
197 | 88 | uint64_t timestamp) override; | ||
198 | 89 | |||
199 | 85 | std::shared_ptr<scene::PromptSession> start_prompt_session_for( | 90 | std::shared_ptr<scene::PromptSession> start_prompt_session_for( |
200 | 86 | std::shared_ptr<scene::Session> const& session, | 91 | std::shared_ptr<scene::Session> const& session, |
201 | 87 | scene::PromptSessionCreationParameters const& params) override; | 92 | scene::PromptSessionCreationParameters const& params) override; |
202 | @@ -124,6 +129,9 @@ | |||
203 | 124 | 129 | ||
204 | 125 | void update_focused_surface_confined_region(); | 130 | void update_focused_surface_confined_region(); |
205 | 126 | 131 | ||
206 | 132 | void set_drag_and_drop_handle(std::vector<uint8_t> const& handle) override; | ||
207 | 133 | void clear_drag_and_drop_handle() override; | ||
208 | 134 | |||
209 | 127 | protected: | 135 | protected: |
210 | 128 | std::shared_ptr<InputTargeter> const input_targeter; | 136 | std::shared_ptr<InputTargeter> const input_targeter; |
211 | 129 | std::shared_ptr<SurfaceStack> const surface_stack; | 137 | std::shared_ptr<SurfaceStack> const surface_stack; |
212 | 130 | 138 | ||
213 | === modified file 'include/server/mir/shell/focus_controller.h' | |||
214 | --- include/server/mir/shell/focus_controller.h 2016-01-29 08:18:22 +0000 | |||
215 | +++ include/server/mir/shell/focus_controller.h 2017-03-14 11:00:58 +0000 | |||
216 | @@ -19,8 +19,10 @@ | |||
217 | 19 | #ifndef MIR_SHELL_FOCUS_CONTROLLER_H_ | 19 | #ifndef MIR_SHELL_FOCUS_CONTROLLER_H_ |
218 | 20 | #define MIR_SHELL_FOCUS_CONTROLLER_H_ | 20 | #define MIR_SHELL_FOCUS_CONTROLLER_H_ |
219 | 21 | 21 | ||
220 | 22 | #include <stddef.h> | ||
221 | 22 | #include <memory> | 23 | #include <memory> |
222 | 23 | #include <set> | 24 | #include <set> |
223 | 25 | #include <vector> | ||
224 | 24 | 26 | ||
225 | 25 | namespace mir | 27 | namespace mir |
226 | 26 | { | 28 | { |
227 | @@ -54,6 +56,9 @@ | |||
228 | 54 | 56 | ||
229 | 55 | virtual void raise(SurfaceSet const& surfaces) = 0; | 57 | virtual void raise(SurfaceSet const& surfaces) = 0; |
230 | 56 | 58 | ||
231 | 59 | virtual void set_drag_and_drop_handle(std::vector<uint8_t> const& handle) = 0; | ||
232 | 60 | virtual void clear_drag_and_drop_handle() = 0; | ||
233 | 61 | |||
234 | 57 | protected: | 62 | protected: |
235 | 58 | FocusController() = default; | 63 | FocusController() = default; |
236 | 59 | FocusController(FocusController const&) = delete; | 64 | FocusController(FocusController const&) = delete; |
237 | 60 | 65 | ||
238 | === modified file 'include/server/mir/shell/input_targeter.h' | |||
239 | --- include/server/mir/shell/input_targeter.h 2015-06-18 02:46:16 +0000 | |||
240 | +++ include/server/mir/shell/input_targeter.h 2017-03-14 11:00:58 +0000 | |||
241 | @@ -19,7 +19,9 @@ | |||
242 | 19 | #ifndef MIR_SHELL_INPUT_TARGETER_H_ | 19 | #ifndef MIR_SHELL_INPUT_TARGETER_H_ |
243 | 20 | #define MIR_SHELL_INPUT_TARGETER_H_ | 20 | #define MIR_SHELL_INPUT_TARGETER_H_ |
244 | 21 | 21 | ||
245 | 22 | #include <stddef.h> | ||
246 | 22 | #include <memory> | 23 | #include <memory> |
247 | 24 | #include <vector> | ||
248 | 23 | 25 | ||
249 | 24 | namespace mir | 26 | namespace mir |
250 | 25 | { | 27 | { |
251 | @@ -40,6 +42,9 @@ | |||
252 | 40 | virtual void set_focus(std::shared_ptr<input::Surface> const& focus_surface) = 0; | 42 | virtual void set_focus(std::shared_ptr<input::Surface> const& focus_surface) = 0; |
253 | 41 | virtual void clear_focus() = 0; | 43 | virtual void clear_focus() = 0; |
254 | 42 | 44 | ||
255 | 45 | virtual void set_drag_and_drop_handle(std::vector<uint8_t> const& handle) = 0; | ||
256 | 46 | virtual void clear_drag_and_drop_handle() = 0; | ||
257 | 47 | |||
258 | 43 | protected: | 48 | protected: |
259 | 44 | InputTargeter() = default; | 49 | InputTargeter() = default; |
260 | 45 | InputTargeter(InputTargeter const&) = delete; | 50 | InputTargeter(InputTargeter const&) = delete; |
261 | 46 | 51 | ||
262 | === modified file 'include/server/mir/shell/shell.h' | |||
263 | --- include/server/mir/shell/shell.h 2017-01-19 00:27:55 +0000 | |||
264 | +++ include/server/mir/shell/shell.h 2017-03-14 11:00:58 +0000 | |||
265 | @@ -100,6 +100,10 @@ | |||
266 | 100 | std::shared_ptr<scene::Surface> const& surface, | 100 | std::shared_ptr<scene::Surface> const& surface, |
267 | 101 | uint64_t timestamp) = 0; | 101 | uint64_t timestamp) = 0; |
268 | 102 | 102 | ||
269 | 103 | virtual void request_drag_and_drop( | ||
270 | 104 | std::shared_ptr<scene::Session> const& session, | ||
271 | 105 | std::shared_ptr<scene::Surface> const& surface, | ||
272 | 106 | uint64_t timestamp) = 0; | ||
273 | 103 | /** @} */ | 107 | /** @} */ |
274 | 104 | }; | 108 | }; |
275 | 105 | } | 109 | } |
276 | 106 | 110 | ||
277 | === modified file 'include/server/mir/shell/shell_wrapper.h' | |||
278 | --- include/server/mir/shell/shell_wrapper.h 2017-01-18 02:29:37 +0000 | |||
279 | +++ include/server/mir/shell/shell_wrapper.h 2017-03-14 11:00:58 +0000 | |||
280 | @@ -85,11 +85,19 @@ | |||
281 | 85 | std::shared_ptr<scene::Surface> const& surface, | 85 | std::shared_ptr<scene::Surface> const& surface, |
282 | 86 | uint64_t timestamp) override; | 86 | uint64_t timestamp) override; |
283 | 87 | 87 | ||
284 | 88 | void request_drag_and_drop( | ||
285 | 89 | std::shared_ptr<scene::Session> const& session, | ||
286 | 90 | std::shared_ptr<scene::Surface> const& surface, | ||
287 | 91 | uint64_t timestamp) override; | ||
288 | 92 | |||
289 | 88 | void add_display(geometry::Rectangle const& area) override; | 93 | void add_display(geometry::Rectangle const& area) override; |
290 | 89 | void remove_display(geometry::Rectangle const& area) override; | 94 | void remove_display(geometry::Rectangle const& area) override; |
291 | 90 | 95 | ||
292 | 91 | bool handle(MirEvent const& event) override; | 96 | bool handle(MirEvent const& event) override; |
293 | 92 | 97 | ||
294 | 98 | void set_drag_and_drop_handle(std::vector<uint8_t> const& handle) override; | ||
295 | 99 | void clear_drag_and_drop_handle() override; | ||
296 | 100 | |||
297 | 93 | protected: | 101 | protected: |
298 | 94 | std::shared_ptr<Shell> const wrapped; | 102 | std::shared_ptr<Shell> const wrapped; |
299 | 95 | }; | 103 | }; |
300 | 96 | 104 | ||
301 | === modified file 'include/server/mir/shell/system_compositor_window_manager.h' | |||
302 | --- include/server/mir/shell/system_compositor_window_manager.h 2017-01-18 02:29:37 +0000 | |||
303 | +++ include/server/mir/shell/system_compositor_window_manager.h 2017-03-14 11:00:58 +0000 | |||
304 | @@ -95,6 +95,11 @@ | |||
305 | 95 | std::shared_ptr<scene::Surface> const& surface, | 95 | std::shared_ptr<scene::Surface> const& surface, |
306 | 96 | uint64_t timestamp) override; | 96 | uint64_t timestamp) override; |
307 | 97 | 97 | ||
308 | 98 | void handle_request_drag_and_drop( | ||
309 | 99 | std::shared_ptr<scene::Session> const& session, | ||
310 | 100 | std::shared_ptr<scene::Surface> const& surface, | ||
311 | 101 | uint64_t timestamp) override; | ||
312 | 102 | |||
313 | 98 | int set_surface_attribute( | 103 | int set_surface_attribute( |
314 | 99 | std::shared_ptr<scene::Session> const& session, | 104 | std::shared_ptr<scene::Session> const& session, |
315 | 100 | std::shared_ptr<scene::Surface> const& surface, | 105 | std::shared_ptr<scene::Surface> const& surface, |
316 | 101 | 106 | ||
317 | === modified file 'include/server/mir/shell/window_manager.h' | |||
318 | --- include/server/mir/shell/window_manager.h 2017-01-18 02:29:37 +0000 | |||
319 | +++ include/server/mir/shell/window_manager.h 2017-03-14 11:00:58 +0000 | |||
320 | @@ -76,6 +76,11 @@ | |||
321 | 76 | std::shared_ptr<scene::Surface> const& surface, | 76 | std::shared_ptr<scene::Surface> const& surface, |
322 | 77 | uint64_t timestamp) = 0; | 77 | uint64_t timestamp) = 0; |
323 | 78 | 78 | ||
324 | 79 | virtual void handle_request_drag_and_drop( | ||
325 | 80 | std::shared_ptr<scene::Session> const& session, | ||
326 | 81 | std::shared_ptr<scene::Surface> const& surface, | ||
327 | 82 | uint64_t timestamp) = 0; | ||
328 | 83 | |||
329 | 79 | virtual ~WindowManager() = default; | 84 | virtual ~WindowManager() = default; |
330 | 80 | WindowManager() = default; | 85 | WindowManager() = default; |
331 | 81 | WindowManager(WindowManager const&) = delete; | 86 | WindowManager(WindowManager const&) = delete; |
332 | 82 | 87 | ||
333 | === modified file 'include/test/mir/test/doubles/mock_window_manager.h' | |||
334 | --- include/test/mir/test/doubles/mock_window_manager.h 2017-01-18 02:29:37 +0000 | |||
335 | +++ include/test/mir/test/doubles/mock_window_manager.h 2017-03-14 11:00:58 +0000 | |||
336 | @@ -58,6 +58,7 @@ | |||
337 | 58 | MOCK_METHOD1(handle_pointer_event, bool(MirPointerEvent const*)); | 58 | MOCK_METHOD1(handle_pointer_event, bool(MirPointerEvent const*)); |
338 | 59 | 59 | ||
339 | 60 | MOCK_METHOD3(handle_raise_surface, void(std::shared_ptr<scene::Session> const&, std::shared_ptr<scene::Surface> const&, uint64_t)); | 60 | MOCK_METHOD3(handle_raise_surface, void(std::shared_ptr<scene::Session> const&, std::shared_ptr<scene::Surface> const&, uint64_t)); |
340 | 61 | MOCK_METHOD3(handle_request_drag_and_drop, void(std::shared_ptr<scene::Session> const&, std::shared_ptr<scene::Surface> const&, uint64_t)); | ||
341 | 61 | 62 | ||
342 | 62 | MOCK_METHOD4(set_surface_attribute, | 63 | MOCK_METHOD4(set_surface_attribute, |
343 | 63 | int(std::shared_ptr<scene::Session> const& session, | 64 | int(std::shared_ptr<scene::Session> const& session, |
344 | 64 | 65 | ||
345 | === modified file 'include/test/mir/test/doubles/stub_surface.h' | |||
346 | --- include/test/mir/test/doubles/stub_surface.h 2017-02-15 14:45:41 +0000 | |||
347 | +++ include/test/mir/test/doubles/stub_surface.h 2017-03-14 11:00:58 +0000 | |||
348 | @@ -70,6 +70,7 @@ | |||
349 | 70 | void set_confine_pointer_state(MirPointerConfinementState state) override; | 70 | void set_confine_pointer_state(MirPointerConfinementState state) override; |
350 | 71 | MirPointerConfinementState confine_pointer_state() const override; | 71 | MirPointerConfinementState confine_pointer_state() const override; |
351 | 72 | void placed_relative(geometry::Rectangle const& placement) override; | 72 | void placed_relative(geometry::Rectangle const& placement) override; |
352 | 73 | void start_drag_and_drop(std::vector<uint8_t> const& handle) override; | ||
353 | 73 | }; | 74 | }; |
354 | 74 | } | 75 | } |
355 | 75 | } | 76 | } |
356 | 76 | 77 | ||
357 | === modified file 'include/test/mir_test_framework/observant_shell.h' | |||
358 | --- include/test/mir_test_framework/observant_shell.h 2017-01-20 00:01:50 +0000 | |||
359 | +++ include/test/mir_test_framework/observant_shell.h 2017-03-14 11:00:58 +0000 | |||
360 | @@ -96,6 +96,14 @@ | |||
361 | 96 | std::shared_ptr<mir::scene::Surface> const& window, | 96 | std::shared_ptr<mir::scene::Surface> const& window, |
362 | 97 | uint64_t timestamp) override; | 97 | uint64_t timestamp) override; |
363 | 98 | 98 | ||
364 | 99 | void request_drag_and_drop( | ||
365 | 100 | std::shared_ptr<mir::scene::Session> const& session, | ||
366 | 101 | std::shared_ptr<mir::scene::Surface> const& window, | ||
367 | 102 | uint64_t timestamp) override; | ||
368 | 103 | |||
369 | 104 | void set_drag_and_drop_handle(std::vector<uint8_t> const& handle) override; | ||
370 | 105 | void clear_drag_and_drop_handle() override; | ||
371 | 106 | |||
372 | 99 | private: | 107 | private: |
373 | 100 | std::shared_ptr<mir::shell::Shell> const wrapped; | 108 | std::shared_ptr<mir::shell::Shell> const wrapped; |
374 | 101 | std::shared_ptr<mir::scene::SurfaceObserver> const surface_observer; | 109 | std::shared_ptr<mir::scene::SurfaceObserver> const surface_observer; |
375 | 102 | 110 | ||
376 | === modified file 'src/capnproto/mir_event.capnp' | |||
377 | --- src/capnproto/mir_event.capnp 2017-02-17 08:46:05 +0000 | |||
378 | +++ src/capnproto/mir_event.capnp 2017-03-14 11:00:58 +0000 | |||
379 | @@ -104,6 +104,8 @@ | |||
380 | 104 | 104 | ||
381 | 105 | buttons @7 :UInt32; | 105 | buttons @7 :UInt32; |
382 | 106 | 106 | ||
383 | 107 | dndHandle @8 :List(UInt8); | ||
384 | 108 | |||
385 | 107 | enum PointerAction | 109 | enum PointerAction |
386 | 108 | { | 110 | { |
387 | 109 | up @0; | 111 | up @0; |
388 | @@ -149,6 +151,7 @@ | |||
389 | 149 | id @0 :Int32; | 151 | id @0 :Int32; |
390 | 150 | attrib @1 :Attrib; | 152 | attrib @1 :Attrib; |
391 | 151 | value @2 :Int32; | 153 | value @2 :Int32; |
392 | 154 | dndHandle @3 :List(UInt8); | ||
393 | 152 | 155 | ||
394 | 153 | enum Attrib | 156 | enum Attrib |
395 | 154 | { | 157 | { |
396 | @@ -160,8 +163,9 @@ | |||
397 | 160 | dpi @4; | 163 | dpi @4; |
398 | 161 | visibility @5; | 164 | visibility @5; |
399 | 162 | preferredOrientation @6; | 165 | preferredOrientation @6; |
400 | 166 | startDragAndDrop @7; | ||
401 | 163 | # Must be last | 167 | # Must be last |
403 | 164 | surfaceAttrib @7; | 168 | surfaceAttrib @8; |
404 | 165 | } | 169 | } |
405 | 166 | } | 170 | } |
406 | 167 | 171 | ||
407 | 168 | 172 | ||
408 | === modified file 'src/client/CMakeLists.txt' | |||
409 | --- src/client/CMakeLists.txt 2017-01-24 13:43:12 +0000 | |||
410 | +++ src/client/CMakeLists.txt 2017-03-14 11:00:58 +0000 | |||
411 | @@ -49,6 +49,7 @@ | |||
412 | 49 | add_library(mirclientobjects OBJECT | 49 | add_library(mirclientobjects OBJECT |
413 | 50 | 50 | ||
414 | 51 | display_configuration.cpp | 51 | display_configuration.cpp |
415 | 52 | drag_and_drop.cpp drag_and_drop.h | ||
416 | 52 | error_connections.cpp | 53 | error_connections.cpp |
417 | 53 | event.cpp | 54 | event.cpp |
418 | 54 | event_printer.cpp | 55 | event_printer.cpp |
419 | @@ -105,6 +106,7 @@ | |||
420 | 105 | ${CMAKE_SOURCE_DIR}/include/client/mir_toolkit/mir_error.h | 106 | ${CMAKE_SOURCE_DIR}/include/client/mir_toolkit/mir_error.h |
421 | 106 | mir_extension_core.cpp | 107 | mir_extension_core.cpp |
422 | 107 | ${CMAKE_SOURCE_DIR}/include/client/mir_toolkit/mir_extension_core.h | 108 | ${CMAKE_SOURCE_DIR}/include/client/mir_toolkit/mir_extension_core.h |
423 | 109 | ${CMAKE_SOURCE_DIR}/include/client/mir_toolkit/extensions/drag_and_drop.h | ||
424 | 108 | ) | 110 | ) |
425 | 109 | 111 | ||
426 | 110 | # Ensure protobuf C++ headers have been produced before | 112 | # Ensure protobuf C++ headers have been produced before |
427 | 111 | 113 | ||
428 | === added file 'src/client/drag_and_drop.cpp' | |||
429 | --- src/client/drag_and_drop.cpp 1970-01-01 00:00:00 +0000 | |||
430 | +++ src/client/drag_and_drop.cpp 2017-03-14 11:00:58 +0000 | |||
431 | @@ -0,0 +1,67 @@ | |||
432 | 1 | /* | ||
433 | 2 | * Copyright © 2017 Canonical Ltd. | ||
434 | 3 | * | ||
435 | 4 | * This program is free software: you can redistribute it and/or modify it | ||
436 | 5 | * under the terms of the GNU Lesser General Public License version 3, | ||
437 | 6 | * as published by the Free Software Foundation. | ||
438 | 7 | * | ||
439 | 8 | * This program is distributed in the hope that it will be useful, | ||
440 | 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
441 | 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
442 | 11 | * GNU Lesser General Public License for more details. | ||
443 | 12 | * | ||
444 | 13 | * You should have received a copy of the GNU Lesser General Public License | ||
445 | 14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
446 | 15 | * | ||
447 | 16 | * Authored by: Alan Griffiths <alan@octopull.co.uk> | ||
448 | 17 | */ | ||
449 | 18 | |||
450 | 19 | #include "drag_and_drop.h" | ||
451 | 20 | #include "mir_toolkit/extensions/drag_and_drop.h" | ||
452 | 21 | |||
453 | 22 | #include "mir/uncaught.h" | ||
454 | 23 | #include "mir/events/surface_event.h" | ||
455 | 24 | #include "mir/events/pointer_event.h" | ||
456 | 25 | |||
457 | 26 | #include "mir_surface.h" | ||
458 | 27 | |||
459 | 28 | namespace | ||
460 | 29 | { | ||
461 | 30 | |||
462 | 31 | void request_drag_and_drop(MirWindow* window, MirCookie const* cookie) | ||
463 | 32 | try | ||
464 | 33 | { | ||
465 | 34 | window->request_drag_and_drop(cookie); | ||
466 | 35 | } | ||
467 | 36 | catch (std::exception const& e) | ||
468 | 37 | { | ||
469 | 38 | MIR_LOG_UNCAUGHT_EXCEPTION(e); | ||
470 | 39 | abort(); | ||
471 | 40 | } | ||
472 | 41 | |||
473 | 42 | MirBlob* start_drag_and_drop(MirWindowEvent const* event) | ||
474 | 43 | try | ||
475 | 44 | { | ||
476 | 45 | return event->dnd_handle(); | ||
477 | 46 | } | ||
478 | 47 | catch (std::exception const& e) | ||
479 | 48 | { | ||
480 | 49 | MIR_LOG_UNCAUGHT_EXCEPTION(e); | ||
481 | 50 | abort(); | ||
482 | 51 | } | ||
483 | 52 | |||
484 | 53 | MirBlob* pointer_drag_and_drop(MirPointerEvent const* event) | ||
485 | 54 | try | ||
486 | 55 | { | ||
487 | 56 | return event->dnd_handle(); | ||
488 | 57 | } | ||
489 | 58 | catch (std::exception const& e) | ||
490 | 59 | { | ||
491 | 60 | MIR_LOG_UNCAUGHT_EXCEPTION(e); | ||
492 | 61 | abort(); | ||
493 | 62 | } | ||
494 | 63 | |||
495 | 64 | MirDragAndDropV1 const impl{&request_drag_and_drop, &start_drag_and_drop, &pointer_drag_and_drop}; | ||
496 | 65 | } | ||
497 | 66 | |||
498 | 67 | MirDragAndDropV1 const* const mir::drag_and_drop::v1 = &impl; | ||
499 | 0 | 68 | ||
500 | === added file 'src/client/drag_and_drop.h' | |||
501 | --- src/client/drag_and_drop.h 1970-01-01 00:00:00 +0000 | |||
502 | +++ src/client/drag_and_drop.h 2017-03-14 11:00:58 +0000 | |||
503 | @@ -0,0 +1,32 @@ | |||
504 | 1 | /* | ||
505 | 2 | * Copyright © 2017 Canonical Ltd. | ||
506 | 3 | * | ||
507 | 4 | * This program is free software: you can redistribute it and/or modify it | ||
508 | 5 | * under the terms of the GNU Lesser General Public License version 3, | ||
509 | 6 | * as published by the Free Software Foundation. | ||
510 | 7 | * | ||
511 | 8 | * This program is distributed in the hope that it will be useful, | ||
512 | 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
513 | 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
514 | 11 | * GNU Lesser General Public License for more details. | ||
515 | 12 | * | ||
516 | 13 | * You should have received a copy of the GNU Lesser General Public License | ||
517 | 14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
518 | 15 | * | ||
519 | 16 | * Authored by: Alan Griffiths <alan@octopull.co.uk> | ||
520 | 17 | */ | ||
521 | 18 | |||
522 | 19 | #ifndef MIR_DRAG_AND_DROP_V1_H | ||
523 | 20 | #define MIR_DRAG_AND_DROP_V1_H | ||
524 | 21 | |||
525 | 22 | typedef struct MirDragAndDropV1 MirDragAndDropV1; | ||
526 | 23 | |||
527 | 24 | namespace mir | ||
528 | 25 | { | ||
529 | 26 | namespace drag_and_drop | ||
530 | 27 | { | ||
531 | 28 | extern MirDragAndDropV1 const* const v1; | ||
532 | 29 | } | ||
533 | 30 | } | ||
534 | 31 | |||
535 | 32 | #endif //MIR_DRAG_AND_DROP_V1_H | ||
536 | 0 | 33 | ||
537 | === modified file 'src/client/events/event_builders.cpp' | |||
538 | --- src/client/events/event_builders.cpp 2017-02-15 13:36:35 +0000 | |||
539 | +++ src/client/events/event_builders.cpp 2017-03-14 11:00:58 +0000 | |||
540 | @@ -110,6 +110,20 @@ | |||
541 | 110 | return make_uptr_event(e); | 110 | return make_uptr_event(e); |
542 | 111 | } | 111 | } |
543 | 112 | 112 | ||
544 | 113 | auto mev::make_start_drag_and_drop_event(frontend::SurfaceId const& surface_id, std::vector<uint8_t> const& handle) | ||
545 | 114 | -> EventUPtr | ||
546 | 115 | { | ||
547 | 116 | auto e = new_event<MirWindowEvent>(); | ||
548 | 117 | |||
549 | 118 | e->set_id(surface_id.as_value()); | ||
550 | 119 | e->set_attrib(mir_window_attrib_drag_and_drop_handle); | ||
551 | 120 | e->set_value(0); | ||
552 | 121 | e->set_dnd_handle(handle); | ||
553 | 122 | |||
554 | 123 | return make_uptr_event(e); | ||
555 | 124 | |||
556 | 125 | } | ||
557 | 126 | |||
558 | 113 | mir::EventUPtr mev::make_event(mf::SurfaceId const& surface_id) | 127 | mir::EventUPtr mev::make_event(mf::SurfaceId const& surface_id) |
559 | 114 | { | 128 | { |
560 | 115 | auto e = new_event<MirCloseWindowEvent>(); | 129 | auto e = new_event<MirCloseWindowEvent>(); |
561 | @@ -450,3 +464,14 @@ | |||
562 | 450 | BOOST_THROW_EXCEPTION(std::invalid_argument("Event has no window id.")); | 464 | BOOST_THROW_EXCEPTION(std::invalid_argument("Event has no window id.")); |
563 | 451 | } | 465 | } |
564 | 452 | } | 466 | } |
565 | 467 | |||
566 | 468 | void mev::set_drag_and_drop_handle(MirEvent& event, std::vector<uint8_t> const& handle) | ||
567 | 469 | { | ||
568 | 470 | if (event.type() == mir_event_type_input) | ||
569 | 471 | { | ||
570 | 472 | auto const input_event = event.to_input(); | ||
571 | 473 | if (mir_input_event_get_type(input_event) == mir_input_event_type_pointer) | ||
572 | 474 | const_cast<MirPointerEvent*>(mir_input_event_get_pointer_event(input_event))->set_dnd_handle(handle); | ||
573 | 475 | } | ||
574 | 476 | } | ||
575 | 477 | |||
576 | 453 | 478 | ||
577 | === modified file 'src/client/mir_blob.cpp' | |||
578 | --- src/client/mir_blob.cpp 2017-01-18 02:29:37 +0000 | |||
579 | +++ src/client/mir_blob.cpp 2017-03-14 11:00:58 +0000 | |||
580 | @@ -16,6 +16,7 @@ | |||
581 | 16 | * Authored by: Alan Griffiths <alan@octopull.co.uk> | 16 | * Authored by: Alan Griffiths <alan@octopull.co.uk> |
582 | 17 | */ | 17 | */ |
583 | 18 | 18 | ||
584 | 19 | #include "mir_blob.h" | ||
585 | 19 | #include "display_configuration.h" | 20 | #include "display_configuration.h" |
586 | 20 | 21 | ||
587 | 21 | #include "mir_toolkit/mir_blob.h" | 22 | #include "mir_toolkit/mir_blob.h" |
588 | @@ -25,14 +26,6 @@ | |||
589 | 25 | 26 | ||
590 | 26 | namespace mp = mir::protobuf; | 27 | namespace mp = mir::protobuf; |
591 | 27 | 28 | ||
592 | 28 | struct MirBlob | ||
593 | 29 | { | ||
594 | 30 | virtual size_t size() const = 0; | ||
595 | 31 | virtual void const* data() const = 0; | ||
596 | 32 | |||
597 | 33 | virtual ~MirBlob() = default; | ||
598 | 34 | }; | ||
599 | 35 | |||
600 | 36 | namespace | 29 | namespace |
601 | 37 | { | 30 | { |
602 | 38 | struct MirManagedBlob : MirBlob | 31 | struct MirManagedBlob : MirBlob |
603 | 39 | 32 | ||
604 | === modified file 'src/client/mir_connection.cpp' | |||
605 | --- src/client/mir_connection.cpp 2017-03-14 04:41:33 +0000 | |||
606 | +++ src/client/mir_connection.cpp 2017-03-14 11:00:58 +0000 | |||
607 | @@ -17,6 +17,7 @@ | |||
608 | 17 | */ | 17 | */ |
609 | 18 | 18 | ||
610 | 19 | #include "mir_connection.h" | 19 | #include "mir_connection.h" |
611 | 20 | #include "drag_and_drop.h" | ||
612 | 20 | #include "mir_surface.h" | 21 | #include "mir_surface.h" |
613 | 21 | #include "mir_prompt_session.h" | 22 | #include "mir_prompt_session.h" |
614 | 22 | #include "mir_toolkit/extensions/graphics_module.h" | 23 | #include "mir_toolkit/extensions/graphics_module.h" |
615 | @@ -1451,6 +1452,9 @@ | |||
616 | 1451 | if (!strcmp(name, "mir_extension_graphics_module") && (version == 1) && graphics_module_extension.is_set()) | 1452 | if (!strcmp(name, "mir_extension_graphics_module") && (version == 1) && graphics_module_extension.is_set()) |
617 | 1452 | return &graphics_module_extension.value(); | 1453 | return &graphics_module_extension.value(); |
618 | 1453 | 1454 | ||
619 | 1455 | if (!strcmp(name, "mir_drag_and_drop") && (version == 1)) | ||
620 | 1456 | return const_cast<MirDragAndDropV1*>(mir::drag_and_drop::v1); | ||
621 | 1457 | |||
622 | 1454 | return platform->request_interface(name, version); | 1458 | return platform->request_interface(name, version); |
623 | 1455 | } | 1459 | } |
624 | 1456 | 1460 | ||
625 | 1457 | 1461 | ||
626 | === modified file 'src/client/mir_surface.cpp' | |||
627 | --- src/client/mir_surface.cpp 2017-03-14 04:41:33 +0000 | |||
628 | +++ src/client/mir_surface.cpp 2017-03-14 11:00:58 +0000 | |||
629 | @@ -598,6 +598,23 @@ | |||
630 | 598 | google::protobuf::NewCallback(google::protobuf::DoNothing)); | 598 | google::protobuf::NewCallback(google::protobuf::DoNothing)); |
631 | 599 | } | 599 | } |
632 | 600 | 600 | ||
633 | 601 | void MirSurface::request_drag_and_drop(MirCookie const* cookie) | ||
634 | 602 | { | ||
635 | 603 | mp::RequestAuthority authority; | ||
636 | 604 | |||
637 | 605 | std::unique_lock<decltype(mutex)> lock(mutex); | ||
638 | 606 | authority.mutable_surface_id()->set_value(surface->id().value()); | ||
639 | 607 | |||
640 | 608 | auto const event_cookie = authority.mutable_cookie(); | ||
641 | 609 | |||
642 | 610 | event_cookie->set_cookie(cookie->cookie().data(), cookie->size()); | ||
643 | 611 | |||
644 | 612 | server->request_drag_and_drop( | ||
645 | 613 | &authority, | ||
646 | 614 | void_response.get(), | ||
647 | 615 | google::protobuf::NewCallback(google::protobuf::DoNothing)); | ||
648 | 616 | } | ||
649 | 617 | |||
650 | 601 | MirBufferStream* MirSurface::get_buffer_stream() | 618 | MirBufferStream* MirSurface::get_buffer_stream() |
651 | 602 | { | 619 | { |
652 | 603 | std::lock_guard<decltype(mutex)> lock(mutex); | 620 | std::lock_guard<decltype(mutex)> lock(mutex); |
653 | 604 | 621 | ||
654 | === modified file 'src/client/mir_surface.h' | |||
655 | --- src/client/mir_surface.h 2017-02-15 14:45:41 +0000 | |||
656 | +++ src/client/mir_surface.h 2017-03-14 11:00:58 +0000 | |||
657 | @@ -200,6 +200,7 @@ | |||
658 | 200 | MirWaitHandle* set_preferred_orientation(MirOrientationMode mode); | 200 | MirWaitHandle* set_preferred_orientation(MirOrientationMode mode); |
659 | 201 | 201 | ||
660 | 202 | void raise_surface(MirCookie const* cookie); | 202 | void raise_surface(MirCookie const* cookie); |
661 | 203 | void request_drag_and_drop(MirCookie const* cookie); | ||
662 | 203 | 204 | ||
663 | 204 | MirWaitHandle* configure_cursor(MirCursorConfiguration const* cursor); | 205 | MirWaitHandle* configure_cursor(MirCursorConfiguration const* cursor); |
664 | 205 | 206 | ||
665 | 206 | 207 | ||
666 | === modified file 'src/client/rpc/mir_display_server.cpp' | |||
667 | --- src/client/rpc/mir_display_server.cpp 2017-02-15 07:38:33 +0000 | |||
668 | +++ src/client/rpc/mir_display_server.cpp 2017-03-14 11:00:58 +0000 | |||
669 | @@ -238,6 +238,15 @@ | |||
670 | 238 | { | 238 | { |
671 | 239 | channel->call_method(std::string(__func__), request, response, done); | 239 | channel->call_method(std::string(__func__), request, response, done); |
672 | 240 | } | 240 | } |
673 | 241 | |||
674 | 242 | void mclr::DisplayServer::request_drag_and_drop( | ||
675 | 243 | mir::protobuf::RequestAuthority const* request, | ||
676 | 244 | mir::protobuf::Void* response, | ||
677 | 245 | google::protobuf::Closure* done) | ||
678 | 246 | { | ||
679 | 247 | channel->call_method(std::string(__func__), request, response, done); | ||
680 | 248 | } | ||
681 | 249 | |||
682 | 241 | void mclr::DisplayServer::apply_input_configuration( | 250 | void mclr::DisplayServer::apply_input_configuration( |
683 | 242 | mir::protobuf::InputConfigurationRequest const* request, | 251 | mir::protobuf::InputConfigurationRequest const* request, |
684 | 243 | mir::protobuf::Void* response, | 252 | mir::protobuf::Void* response, |
685 | 244 | 253 | ||
686 | === modified file 'src/client/rpc/mir_display_server.h' | |||
687 | --- src/client/rpc/mir_display_server.h 2017-02-15 07:38:33 +0000 | |||
688 | +++ src/client/rpc/mir_display_server.h 2017-03-14 11:00:58 +0000 | |||
689 | @@ -155,6 +155,10 @@ | |||
690 | 155 | mir::protobuf::RaiseRequest const* request, | 155 | mir::protobuf::RaiseRequest const* request, |
691 | 156 | mir::protobuf::Void* response, | 156 | mir::protobuf::Void* response, |
692 | 157 | google::protobuf::Closure* done) override; | 157 | google::protobuf::Closure* done) override; |
693 | 158 | void request_drag_and_drop( | ||
694 | 159 | mir::protobuf::RequestAuthority const* request, | ||
695 | 160 | mir::protobuf::Void* response, | ||
696 | 161 | google::protobuf::Closure* done) override; | ||
697 | 158 | void apply_input_configuration( | 162 | void apply_input_configuration( |
698 | 159 | mir::protobuf::InputConfigurationRequest const* request, | 163 | mir::protobuf::InputConfigurationRequest const* request, |
699 | 160 | mir::protobuf::Void* response, | 164 | mir::protobuf::Void* response, |
700 | 161 | 165 | ||
701 | === modified file 'src/client/symbols.map' | |||
702 | --- src/client/symbols.map 2017-03-14 04:41:33 +0000 | |||
703 | +++ src/client/symbols.map 2017-03-14 11:00:58 +0000 | |||
704 | @@ -604,6 +604,8 @@ | |||
705 | 604 | global: | 604 | global: |
706 | 605 | extern "C++" { | 605 | extern "C++" { |
707 | 606 | mir::events::set_window_id*; | 606 | mir::events::set_window_id*; |
708 | 607 | mir::events::make_start_drag_and_drop_event*; | ||
709 | 608 | mir::events::set_drag_and_drop_handle*; | ||
710 | 607 | }; | 609 | }; |
711 | 608 | } MIR_CLIENT_DETAIL_0.26.1; | 610 | } MIR_CLIENT_DETAIL_0.26.1; |
712 | 609 | 611 | ||
713 | 610 | 612 | ||
714 | === modified file 'src/common/events/pointer_event.cpp' | |||
715 | --- src/common/events/pointer_event.cpp 2016-11-07 23:02:26 +0000 | |||
716 | +++ src/common/events/pointer_event.cpp 2017-03-14 11:00:58 +0000 | |||
717 | @@ -1,5 +1,5 @@ | |||
718 | 1 | /* | 1 | /* |
720 | 2 | * Copyright © 2016 Canonical Ltd. | 2 | * Copyright © 2016-2017 Canonical Ltd. |
721 | 3 | * | 3 | * |
722 | 4 | * This program is free software: you can redistribute it and/or modify it | 4 | * This program is free software: you can redistribute it and/or modify it |
723 | 5 | * under the terms of the GNU Lesser General Public License version 3, | 5 | * under the terms of the GNU Lesser General Public License version 3, |
724 | @@ -16,10 +16,11 @@ | |||
725 | 16 | * Authored by: Andreas Pokorny <andreas.pokorny@canonical.com> | 16 | * Authored by: Andreas Pokorny <andreas.pokorny@canonical.com> |
726 | 17 | */ | 17 | */ |
727 | 18 | 18 | ||
728 | 19 | #include "mir/events/pointer_event.h" | ||
729 | 20 | #include "mir_blob.h" | ||
730 | 21 | |||
731 | 19 | #include <boost/throw_exception.hpp> | 22 | #include <boost/throw_exception.hpp> |
732 | 20 | 23 | ||
733 | 21 | #include "mir/events/pointer_event.h" | ||
734 | 22 | |||
735 | 23 | MirPointerEvent::MirPointerEvent() | 24 | MirPointerEvent::MirPointerEvent() |
736 | 24 | { | 25 | { |
737 | 25 | event.initInput(); | 26 | event.initInput(); |
738 | @@ -132,3 +133,40 @@ | |||
739 | 132 | { | 133 | { |
740 | 133 | event.getInput().getPointer().setAction(static_cast<mir::capnp::PointerEvent::PointerAction>(action)); | 134 | event.getInput().getPointer().setAction(static_cast<mir::capnp::PointerEvent::PointerAction>(action)); |
741 | 134 | } | 135 | } |
742 | 136 | |||
743 | 137 | void MirPointerEvent::set_dnd_handle(std::vector<uint8_t> const& handle) | ||
744 | 138 | { | ||
745 | 139 | event.getInput().getPointer().initDndHandle(handle.size()); | ||
746 | 140 | event.getInput().getPointer().setDndHandle(::kj::ArrayPtr<uint8_t const>{&*begin(handle), &*end(handle)}); | ||
747 | 141 | } | ||
748 | 142 | |||
749 | 143 | namespace | ||
750 | 144 | { | ||
751 | 145 | struct MyMirBlob : MirBlob | ||
752 | 146 | { | ||
753 | 147 | |||
754 | 148 | size_t size() const override { return data_.size(); } | ||
755 | 149 | virtual void const* data() const override { return data_.data(); } | ||
756 | 150 | |||
757 | 151 | std::vector<uint8_t> data_; | ||
758 | 152 | }; | ||
759 | 153 | } | ||
760 | 154 | |||
761 | 155 | MirBlob* MirPointerEvent::dnd_handle() const | ||
762 | 156 | { | ||
763 | 157 | auto const reader = event.asReader().getInput().getPointer(); | ||
764 | 158 | |||
765 | 159 | if (!reader.hasDndHandle()) | ||
766 | 160 | return nullptr; | ||
767 | 161 | |||
768 | 162 | auto const dnd_handle = reader.getDndHandle(); | ||
769 | 163 | |||
770 | 164 | auto blob = std::make_unique<MyMirBlob>(); | ||
771 | 165 | blob->data_.reserve(dnd_handle.size()); | ||
772 | 166 | |||
773 | 167 | //std::copy(dnd_handle.begin(), dnd_handle.end(), back_inserter(blob->data_)); | ||
774 | 168 | for (auto p = dnd_handle.begin(); p != dnd_handle.end(); ++p) | ||
775 | 169 | blob->data_.push_back(*p); | ||
776 | 170 | |||
777 | 171 | return blob.release(); | ||
778 | 172 | } | ||
779 | 135 | 173 | ||
780 | === modified file 'src/common/events/surface_event.cpp' | |||
781 | --- src/common/events/surface_event.cpp 2017-01-23 03:38:33 +0000 | |||
782 | +++ src/common/events/surface_event.cpp 2017-03-14 11:00:58 +0000 | |||
783 | @@ -1,5 +1,5 @@ | |||
784 | 1 | /* | 1 | /* |
786 | 2 | * Copyright © 2016 Canonical Ltd. | 2 | * Copyright © 2016-2017 Canonical Ltd. |
787 | 3 | * | 3 | * |
788 | 4 | * This program is free software: you can redistribute it and/or modify it | 4 | * This program is free software: you can redistribute it and/or modify it |
789 | 5 | * under the terms of the GNU Lesser General Public License version 3, | 5 | * under the terms of the GNU Lesser General Public License version 3, |
790 | @@ -17,6 +17,7 @@ | |||
791 | 17 | */ | 17 | */ |
792 | 18 | 18 | ||
793 | 19 | #include "mir/events/surface_event.h" | 19 | #include "mir/events/surface_event.h" |
794 | 20 | #include "mir_blob.h" | ||
795 | 20 | 21 | ||
796 | 21 | // MirSurfaceEvent is a deprecated type, but we need to implement it | 22 | // MirSurfaceEvent is a deprecated type, but we need to implement it |
797 | 22 | #pragma GCC diagnostic ignored "-Wdeprecated-declarations" | 23 | #pragma GCC diagnostic ignored "-Wdeprecated-declarations" |
798 | @@ -55,3 +56,40 @@ | |||
799 | 55 | { | 56 | { |
800 | 56 | event.getSurface().setValue(value); | 57 | event.getSurface().setValue(value); |
801 | 57 | } | 58 | } |
802 | 59 | |||
803 | 60 | void MirSurfaceEvent::set_dnd_handle(std::vector<uint8_t> const& handle) | ||
804 | 61 | { | ||
805 | 62 | event.getSurface().initDndHandle(handle.size()); | ||
806 | 63 | event.getSurface().setDndHandle(::kj::ArrayPtr<uint8_t const>{&*begin(handle), &*end(handle)}); | ||
807 | 64 | } | ||
808 | 65 | |||
809 | 66 | namespace | ||
810 | 67 | { | ||
811 | 68 | struct MyMirBlob : MirBlob | ||
812 | 69 | { | ||
813 | 70 | |||
814 | 71 | size_t size() const override { return data_.size(); } | ||
815 | 72 | virtual void const* data() const override { return data_.data(); } | ||
816 | 73 | |||
817 | 74 | std::vector<uint8_t> data_; | ||
818 | 75 | }; | ||
819 | 76 | } | ||
820 | 77 | |||
821 | 78 | MirBlob* MirSurfaceEvent::dnd_handle() const | ||
822 | 79 | { | ||
823 | 80 | if (!event.asReader().getSurface().hasDndHandle()) | ||
824 | 81 | return nullptr; | ||
825 | 82 | |||
826 | 83 | auto blob = std::make_unique<MyMirBlob>(); | ||
827 | 84 | |||
828 | 85 | auto reader = event.asReader().getSurface().getDndHandle(); | ||
829 | 86 | |||
830 | 87 | blob->data_.reserve(reader.size()); | ||
831 | 88 | |||
832 | 89 | // Can't use std::copy() as the CapnP iterators don't provide an iterator category | ||
833 | 90 | for (auto p = reader.begin(); p != reader.end(); ++p) | ||
834 | 91 | blob->data_.push_back(*p); | ||
835 | 92 | |||
836 | 93 | return blob.release(); | ||
837 | 94 | } | ||
838 | 95 | |||
839 | 58 | 96 | ||
840 | === modified file 'src/common/symbols.map' | |||
841 | --- src/common/symbols.map 2017-02-28 08:53:57 +0000 | |||
842 | +++ src/common/symbols.map 2017-03-14 11:00:58 +0000 | |||
843 | @@ -432,5 +432,9 @@ | |||
844 | 432 | MirInputEvent::window_id*; | 432 | MirInputEvent::window_id*; |
845 | 433 | MirKeyboardEvent::set_text*; | 433 | MirKeyboardEvent::set_text*; |
846 | 434 | MirKeyboardEvent::text*; | 434 | MirKeyboardEvent::text*; |
847 | 435 | MirPointerEvent::dnd_handle*; | ||
848 | 436 | MirPointerEvent::set_dnd_handle*; | ||
849 | 437 | MirSurfaceEvent::dnd_handle*; | ||
850 | 438 | MirSurfaceEvent::set_dnd_handle*; | ||
851 | 435 | }; | 439 | }; |
852 | 436 | } MIR_COMMON_0.26; | 440 | } MIR_COMMON_0.26; |
853 | 437 | 441 | ||
854 | === modified file 'src/include/common/mir/events/pointer_event.h' | |||
855 | --- src/include/common/mir/events/pointer_event.h 2016-09-22 19:21:34 +0000 | |||
856 | +++ src/include/common/mir/events/pointer_event.h 2017-03-14 11:00:58 +0000 | |||
857 | @@ -1,5 +1,5 @@ | |||
858 | 1 | /* | 1 | /* |
860 | 2 | * Copyright © 2016 Canonical Ltd. | 2 | * Copyright © 2016-2017 Canonical Ltd. |
861 | 3 | * | 3 | * |
862 | 4 | * This program is free software: you can redistribute it and/or modify it | 4 | * This program is free software: you can redistribute it and/or modify it |
863 | 5 | * under the terms of the GNU Lesser General Public License version 3, | 5 | * under the terms of the GNU Lesser General Public License version 3, |
864 | @@ -21,6 +21,8 @@ | |||
865 | 21 | 21 | ||
866 | 22 | #include "mir/events/input_event.h" | 22 | #include "mir/events/input_event.h" |
867 | 23 | 23 | ||
868 | 24 | typedef struct MirBlob MirBlob; | ||
869 | 25 | |||
870 | 24 | struct MirPointerEvent : MirInputEvent | 26 | struct MirPointerEvent : MirInputEvent |
871 | 25 | { | 27 | { |
872 | 26 | MirPointerEvent(); | 28 | MirPointerEvent(); |
873 | @@ -60,6 +62,9 @@ | |||
874 | 60 | 62 | ||
875 | 61 | MirPointerButtons buttons() const; | 63 | MirPointerButtons buttons() const; |
876 | 62 | void set_buttons(MirPointerButtons buttons); | 64 | void set_buttons(MirPointerButtons buttons); |
877 | 65 | |||
878 | 66 | void set_dnd_handle(std::vector<uint8_t> const& handle); | ||
879 | 67 | MirBlob* dnd_handle() const; | ||
880 | 63 | private: | 68 | private: |
881 | 64 | }; | 69 | }; |
882 | 65 | 70 | ||
883 | 66 | 71 | ||
884 | === modified file 'src/include/common/mir/events/surface_event.h' | |||
885 | --- src/include/common/mir/events/surface_event.h 2017-01-18 02:29:37 +0000 | |||
886 | +++ src/include/common/mir/events/surface_event.h 2017-03-14 11:00:58 +0000 | |||
887 | @@ -1,5 +1,5 @@ | |||
888 | 1 | /* | 1 | /* |
890 | 2 | * Copyright © 2016 Canonical Ltd. | 2 | * Copyright © 2016-2017 Canonical Ltd. |
891 | 3 | * | 3 | * |
892 | 4 | * This program is free software: you can redistribute it and/or modify it | 4 | * This program is free software: you can redistribute it and/or modify it |
893 | 5 | * under the terms of the GNU Lesser General Public License version 3, | 5 | * under the terms of the GNU Lesser General Public License version 3, |
894 | @@ -21,6 +21,8 @@ | |||
895 | 21 | 21 | ||
896 | 22 | #include "mir/events/event.h" | 22 | #include "mir/events/event.h" |
897 | 23 | 23 | ||
898 | 24 | typedef struct MirBlob MirBlob; | ||
899 | 25 | |||
900 | 24 | struct MirSurfaceEvent : MirEvent | 26 | struct MirSurfaceEvent : MirEvent |
901 | 25 | { | 27 | { |
902 | 26 | MirSurfaceEvent(); | 28 | MirSurfaceEvent(); |
903 | @@ -33,6 +35,9 @@ | |||
904 | 33 | 35 | ||
905 | 34 | int value() const; | 36 | int value() const; |
906 | 35 | void set_value(int value); | 37 | void set_value(int value); |
907 | 38 | |||
908 | 39 | void set_dnd_handle(std::vector<uint8_t> const& handle); | ||
909 | 40 | MirBlob* dnd_handle() const; | ||
910 | 36 | }; | 41 | }; |
911 | 37 | 42 | ||
912 | 38 | #endif /* MIR_COMMON_SURFACE_EVENT_H_ */ | 43 | #endif /* MIR_COMMON_SURFACE_EVENT_H_ */ |
913 | 39 | 44 | ||
914 | === modified file 'src/include/common/mir/protobuf/display_server.h' | |||
915 | --- src/include/common/mir/protobuf/display_server.h 2017-02-15 07:38:33 +0000 | |||
916 | +++ src/include/common/mir/protobuf/display_server.h 2017-03-14 11:00:58 +0000 | |||
917 | @@ -151,6 +151,10 @@ | |||
918 | 151 | mir::protobuf::RaiseRequest const* request, | 151 | mir::protobuf::RaiseRequest const* request, |
919 | 152 | mir::protobuf::Void* response, | 152 | mir::protobuf::Void* response, |
920 | 153 | google::protobuf::Closure* done) = 0; | 153 | google::protobuf::Closure* done) = 0; |
921 | 154 | virtual void request_drag_and_drop( | ||
922 | 155 | mir::protobuf::RequestAuthority const* request, | ||
923 | 156 | mir::protobuf::Void* response, | ||
924 | 157 | google::protobuf::Closure* done) = 0; | ||
925 | 154 | virtual void apply_input_configuration( | 158 | virtual void apply_input_configuration( |
926 | 155 | mir::protobuf::InputConfigurationRequest const* request, | 159 | mir::protobuf::InputConfigurationRequest const* request, |
927 | 156 | mir::protobuf::Void* response, | 160 | mir::protobuf::Void* response, |
928 | 157 | 161 | ||
929 | === added file 'src/include/common/mir_blob.h' | |||
930 | --- src/include/common/mir_blob.h 1970-01-01 00:00:00 +0000 | |||
931 | +++ src/include/common/mir_blob.h 2017-03-14 11:00:58 +0000 | |||
932 | @@ -0,0 +1,32 @@ | |||
933 | 1 | /* | ||
934 | 2 | * Copyright © 2017 Canonical Ltd. | ||
935 | 3 | * | ||
936 | 4 | * This program is free software: you can redistribute it and/or modify | ||
937 | 5 | * it under the terms of the GNU Lesser General Public License version 3 as | ||
938 | 6 | * published by the Free Software Foundation. | ||
939 | 7 | * | ||
940 | 8 | * This program is distributed in the hope that it will be useful, | ||
941 | 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
942 | 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
943 | 11 | * GNU Lesser General Public License for more details. | ||
944 | 12 | * | ||
945 | 13 | * You should have received a copy of the GNU Lesser General Public License | ||
946 | 14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
947 | 15 | * | ||
948 | 16 | * Authored by: Alan Griffiths <alan@octopull.co.uk> | ||
949 | 17 | */ | ||
950 | 18 | |||
951 | 19 | #ifndef MIR_MIR_BLOB_H_H | ||
952 | 20 | #define MIR_MIR_BLOB_H_H | ||
953 | 21 | |||
954 | 22 | #include <stddef.h> | ||
955 | 23 | |||
956 | 24 | struct MirBlob | ||
957 | 25 | { | ||
958 | 26 | virtual size_t size() const = 0; | ||
959 | 27 | virtual void const* data() const = 0; | ||
960 | 28 | |||
961 | 29 | virtual ~MirBlob() = default; | ||
962 | 30 | }; | ||
963 | 31 | |||
964 | 32 | #endif //MIR_MIR_BLOB_H_H | ||
965 | 0 | 33 | ||
966 | === modified file 'src/include/server/mir/frontend/shell.h' | |||
967 | --- src/include/server/mir/frontend/shell.h 2017-01-18 02:29:37 +0000 | |||
968 | +++ src/include/server/mir/frontend/shell.h 2017-03-14 11:00:58 +0000 | |||
969 | @@ -87,6 +87,11 @@ | |||
970 | 87 | SurfaceId surface_id, | 87 | SurfaceId surface_id, |
971 | 88 | uint64_t timestamp) = 0; | 88 | uint64_t timestamp) = 0; |
972 | 89 | 89 | ||
973 | 90 | virtual void request_drag_and_drop( | ||
974 | 91 | std::shared_ptr<Session> const& session, | ||
975 | 92 | SurfaceId surface_id, | ||
976 | 93 | uint64_t timestamp) = 0; | ||
977 | 94 | |||
978 | 90 | protected: | 95 | protected: |
979 | 91 | Shell() = default; | 96 | Shell() = default; |
980 | 92 | Shell(const Shell&) = delete; | 97 | Shell(const Shell&) = delete; |
981 | 93 | 98 | ||
982 | === modified file 'src/include/server/mir/scene/surface_event_source.h' | |||
983 | --- src/include/server/mir/scene/surface_event_source.h 2017-02-15 13:36:35 +0000 | |||
984 | +++ src/include/server/mir/scene/surface_event_source.h 2017-03-14 11:00:58 +0000 | |||
985 | @@ -51,6 +51,7 @@ | |||
986 | 51 | std::string const& variant, std::string const& options) override; | 51 | std::string const& variant, std::string const& options) override; |
987 | 52 | void placed_relative(geometry::Rectangle const& placement) override; | 52 | void placed_relative(geometry::Rectangle const& placement) override; |
988 | 53 | void input_consumed(MirEvent const* event) override; | 53 | void input_consumed(MirEvent const* event) override; |
989 | 54 | void start_drag_and_drop(std::vector<uint8_t> const& handle) override; | ||
990 | 54 | 55 | ||
991 | 55 | private: | 56 | private: |
992 | 56 | frontend::SurfaceId const id; | 57 | frontend::SurfaceId const id; |
993 | 57 | 58 | ||
994 | === modified file 'src/include/server/mir/scene/surface_observers.h' | |||
995 | --- src/include/server/mir/scene/surface_observers.h 2017-02-15 13:36:35 +0000 | |||
996 | +++ src/include/server/mir/scene/surface_observers.h 2017-03-14 11:00:58 +0000 | |||
997 | @@ -51,6 +51,7 @@ | |||
998 | 51 | void cursor_image_removed() override; | 51 | void cursor_image_removed() override; |
999 | 52 | void placed_relative(geometry::Rectangle const& placement) override; | 52 | void placed_relative(geometry::Rectangle const& placement) override; |
1000 | 53 | void input_consumed(MirEvent const* event) override; | 53 | void input_consumed(MirEvent const* event) override; |
1001 | 54 | void start_drag_and_drop(std::vector<uint8_t> const& handle) override; | ||
1002 | 54 | }; | 55 | }; |
1003 | 55 | 56 | ||
1004 | 56 | } | 57 | } |
1005 | 57 | 58 | ||
1006 | === modified file 'src/include/server/mir/shell/basic_window_manager.h' | |||
1007 | --- src/include/server/mir/shell/basic_window_manager.h 2017-01-18 02:29:37 +0000 | |||
1008 | +++ src/include/server/mir/shell/basic_window_manager.h 2017-03-14 11:00:58 +0000 | |||
1009 | @@ -65,6 +65,9 @@ | |||
1010 | 65 | 65 | ||
1011 | 66 | virtual void raise_tree(std::shared_ptr<scene::Surface> const& root) = 0; | 66 | virtual void raise_tree(std::shared_ptr<scene::Surface> const& root) = 0; |
1012 | 67 | 67 | ||
1013 | 68 | virtual void set_drag_and_drop_handle(std::vector<uint8_t> const& handle) = 0; | ||
1014 | 69 | virtual void clear_drag_and_drop_handle() = 0; | ||
1015 | 70 | |||
1016 | 68 | virtual ~WindowManagerTools() = default; | 71 | virtual ~WindowManagerTools() = default; |
1017 | 69 | WindowManagerTools() = default; | 72 | WindowManagerTools() = default; |
1018 | 70 | WindowManagerTools(WindowManagerTools const&) = delete; | 73 | WindowManagerTools(WindowManagerTools const&) = delete; |
1019 | @@ -107,6 +110,10 @@ | |||
1020 | 107 | std::shared_ptr<scene::Session> const& session, | 110 | std::shared_ptr<scene::Session> const& session, |
1021 | 108 | std::shared_ptr<scene::Surface> const& surface) = 0; | 111 | std::shared_ptr<scene::Surface> const& surface) = 0; |
1022 | 109 | 112 | ||
1023 | 113 | virtual void handle_request_drag_and_drop( | ||
1024 | 114 | std::shared_ptr<scene::Session> const& session, | ||
1025 | 115 | std::shared_ptr<scene::Surface> const& surface) = 0; | ||
1026 | 116 | |||
1027 | 110 | virtual ~WindowManagementPolicy() = default; | 117 | virtual ~WindowManagementPolicy() = default; |
1028 | 111 | WindowManagementPolicy() = default; | 118 | WindowManagementPolicy() = default; |
1029 | 112 | WindowManagementPolicy(WindowManagementPolicy const&) = delete; | 119 | WindowManagementPolicy(WindowManagementPolicy const&) = delete; |
1030 | @@ -163,6 +170,11 @@ | |||
1031 | 163 | std::shared_ptr<scene::Surface> const& surface, | 170 | std::shared_ptr<scene::Surface> const& surface, |
1032 | 164 | uint64_t timestamp) override; | 171 | uint64_t timestamp) override; |
1033 | 165 | 172 | ||
1034 | 173 | void handle_request_drag_and_drop( | ||
1035 | 174 | std::shared_ptr<scene::Session> const& session, | ||
1036 | 175 | std::shared_ptr<scene::Surface> const& surface, | ||
1037 | 176 | uint64_t timestamp) override; | ||
1038 | 177 | |||
1039 | 166 | int set_surface_attribute( | 178 | int set_surface_attribute( |
1040 | 167 | std::shared_ptr<scene::Session> const& /*session*/, | 179 | std::shared_ptr<scene::Session> const& /*session*/, |
1041 | 168 | std::shared_ptr<scene::Surface> const& surface, | 180 | std::shared_ptr<scene::Surface> const& surface, |
1042 | @@ -192,6 +204,9 @@ | |||
1043 | 192 | 204 | ||
1044 | 193 | void raise_tree(std::shared_ptr<scene::Surface> const& root) override; | 205 | void raise_tree(std::shared_ptr<scene::Surface> const& root) override; |
1045 | 194 | 206 | ||
1046 | 207 | void set_drag_and_drop_handle(std::vector<uint8_t> const& handle) override; | ||
1047 | 208 | void clear_drag_and_drop_handle() override; | ||
1048 | 209 | |||
1049 | 195 | private: | 210 | private: |
1050 | 196 | shell::FocusController* const focus_controller; | 211 | shell::FocusController* const focus_controller; |
1051 | 197 | std::unique_ptr<WindowManagementPolicy> const policy; | 212 | std::unique_ptr<WindowManagementPolicy> const policy; |
1052 | 198 | 213 | ||
1053 | === modified file 'src/include/server/mir/shell/canonical_window_manager.h' | |||
1054 | --- src/include/server/mir/shell/canonical_window_manager.h 2017-01-18 02:29:37 +0000 | |||
1055 | +++ src/include/server/mir/shell/canonical_window_manager.h 2017-03-14 11:00:58 +0000 | |||
1056 | @@ -75,6 +75,10 @@ | |||
1057 | 75 | std::shared_ptr<scene::Session> const& session, | 75 | std::shared_ptr<scene::Session> const& session, |
1058 | 76 | std::shared_ptr<scene::Surface> const& surface) override; | 76 | std::shared_ptr<scene::Surface> const& surface) override; |
1059 | 77 | 77 | ||
1060 | 78 | void handle_request_drag_and_drop( | ||
1061 | 79 | std::shared_ptr<scene::Session> const& session, | ||
1062 | 80 | std::shared_ptr<scene::Surface> const& surface) override; | ||
1063 | 81 | |||
1064 | 78 | private: | 82 | private: |
1065 | 79 | static const int modifier_mask = | 83 | static const int modifier_mask = |
1066 | 80 | mir_input_event_modifier_alt | | 84 | mir_input_event_modifier_alt | |
1067 | 81 | 85 | ||
1068 | === modified file 'src/protobuf/mir_protobuf.proto' | |||
1069 | --- src/protobuf/mir_protobuf.proto 2017-03-14 04:41:33 +0000 | |||
1070 | +++ src/protobuf/mir_protobuf.proto 2017-03-14 11:00:58 +0000 | |||
1071 | @@ -444,6 +444,11 @@ | |||
1072 | 444 | required SurfaceId surface_id = 2; | 444 | required SurfaceId surface_id = 2; |
1073 | 445 | } | 445 | } |
1074 | 446 | 446 | ||
1075 | 447 | message RequestAuthority { | ||
1076 | 448 | required Cookie cookie = 1; | ||
1077 | 449 | required SurfaceId surface_id = 2; | ||
1078 | 450 | } | ||
1079 | 451 | |||
1080 | 447 | message InputDevices { | 452 | message InputDevices { |
1081 | 448 | repeated InputDeviceInfo device_info = 1; | 453 | repeated InputDeviceInfo device_info = 1; |
1082 | 449 | } | 454 | } |
1083 | 450 | 455 | ||
1084 | === modified file 'src/protobuf/symbols.map' | |||
1085 | --- src/protobuf/symbols.map 2017-02-15 07:38:33 +0000 | |||
1086 | +++ src/protobuf/symbols.map 2017-03-14 11:00:58 +0000 | |||
1087 | @@ -1112,3 +1112,29 @@ | |||
1088 | 1112 | vtable?for?mir::protobuf::PromptSession; | 1112 | vtable?for?mir::protobuf::PromptSession; |
1089 | 1113 | }; | 1113 | }; |
1090 | 1114 | } MIR_PROTOBUF_0.22; | 1114 | } MIR_PROTOBUF_0.22; |
1091 | 1115 | |||
1092 | 1116 | MIR_PROTOBUF_0.27 { | ||
1093 | 1117 | global: | ||
1094 | 1118 | extern "C++" { | ||
1095 | 1119 | mir::protobuf::RequestAuthority::ByteSize*; | ||
1096 | 1120 | mir::protobuf::RequestAuthority::CheckTypeAndMergeFrom*; | ||
1097 | 1121 | mir::protobuf::RequestAuthority::Clear*; | ||
1098 | 1122 | mir::protobuf::RequestAuthority::CopyFrom*; | ||
1099 | 1123 | mir::protobuf::RequestAuthority::default_instance*; | ||
1100 | 1124 | mir::protobuf::RequestAuthority::DiscardUnknownFields*; | ||
1101 | 1125 | mir::protobuf::RequestAuthority::GetTypeName*; | ||
1102 | 1126 | mir::protobuf::RequestAuthority::IsInitialized*; | ||
1103 | 1127 | mir::protobuf::RequestAuthority::kCookieFieldNumber*; | ||
1104 | 1128 | mir::protobuf::RequestAuthority::kSurfaceIdFieldNumber*; | ||
1105 | 1129 | mir::protobuf::RequestAuthority::MergeFrom*; | ||
1106 | 1130 | mir::protobuf::RequestAuthority::MergePartialFromCodedStream*; | ||
1107 | 1131 | mir::protobuf::RequestAuthority::New*; | ||
1108 | 1132 | mir::protobuf::RequestAuthority::?RequestAuthority*; | ||
1109 | 1133 | mir::protobuf::RequestAuthority::RequestAuthority*; | ||
1110 | 1134 | mir::protobuf::RequestAuthority::SerializeWithCachedSizes*; | ||
1111 | 1135 | mir::protobuf::RequestAuthority::Swap*; | ||
1112 | 1136 | non-virtual?thunk?to?mir::protobuf::RequestAuthority::?RequestAuthority*; | ||
1113 | 1137 | typeinfo?for?mir::protobuf::RequestAuthority; | ||
1114 | 1138 | vtable?for?mir::protobuf::RequestAuthority; | ||
1115 | 1139 | }; | ||
1116 | 1140 | } MIR_PROTOBUF_0.26; | ||
1117 | 1115 | 1141 | ||
1118 | === modified file 'src/server/frontend/protobuf_message_processor.cpp' | |||
1119 | --- src/server/frontend/protobuf_message_processor.cpp 2017-02-15 07:38:33 +0000 | |||
1120 | +++ src/server/frontend/protobuf_message_processor.cpp 2017-03-14 11:00:58 +0000 | |||
1121 | @@ -305,6 +305,10 @@ | |||
1122 | 305 | { | 305 | { |
1123 | 306 | invoke(this, display_server.get(), &protobuf::DisplayServer::stop_prompt_session, invocation); | 306 | invoke(this, display_server.get(), &protobuf::DisplayServer::stop_prompt_session, invocation); |
1124 | 307 | } | 307 | } |
1125 | 308 | else if ("request_drag_and_drop" == invocation.method_name()) | ||
1126 | 309 | { | ||
1127 | 310 | invoke(this, display_server.get(), &protobuf::DisplayServer::request_drag_and_drop, invocation); | ||
1128 | 311 | } | ||
1129 | 308 | else if ("disconnect" == invocation.method_name()) | 312 | else if ("disconnect" == invocation.method_name()) |
1130 | 309 | { | 313 | { |
1131 | 310 | invoke(this, display_server.get(), &DisplayServer::disconnect, invocation); | 314 | invoke(this, display_server.get(), &DisplayServer::disconnect, invocation); |
1132 | 311 | 315 | ||
1133 | === modified file 'src/server/frontend/session_mediator.cpp' | |||
1134 | --- src/server/frontend/session_mediator.cpp 2017-03-14 04:41:33 +0000 | |||
1135 | +++ src/server/frontend/session_mediator.cpp 2017-03-14 11:00:58 +0000 | |||
1136 | @@ -1175,6 +1175,26 @@ | |||
1137 | 1175 | done->Run(); | 1175 | done->Run(); |
1138 | 1176 | } | 1176 | } |
1139 | 1177 | 1177 | ||
1140 | 1178 | void mir::frontend::SessionMediator::request_drag_and_drop(mir::protobuf::RequestAuthority const* request, | ||
1141 | 1179 | mir::protobuf::Void*, google::protobuf::Closure* done) | ||
1142 | 1180 | { | ||
1143 | 1181 | auto const session = weak_session.lock(); | ||
1144 | 1182 | if (!session) | ||
1145 | 1183 | BOOST_THROW_EXCEPTION(std::logic_error("Invalid application session")); | ||
1146 | 1184 | |||
1147 | 1185 | auto const cookie = request->cookie(); | ||
1148 | 1186 | auto const surface_id = request->surface_id(); | ||
1149 | 1187 | |||
1150 | 1188 | auto cookie_string = cookie.cookie(); | ||
1151 | 1189 | |||
1152 | 1190 | std::vector<uint8_t> cookie_bytes(cookie_string.begin(), cookie_string.end()); | ||
1153 | 1191 | auto const cookie_ptr = cookie_authority->make_cookie(cookie_bytes); | ||
1154 | 1192 | |||
1155 | 1193 | shell->request_drag_and_drop(session, mf::SurfaceId{surface_id.value()}, cookie_ptr->timestamp()); | ||
1156 | 1194 | |||
1157 | 1195 | done->Run(); | ||
1158 | 1196 | } | ||
1159 | 1197 | |||
1160 | 1178 | void mf::SessionMediator::apply_input_configuration( | 1198 | void mf::SessionMediator::apply_input_configuration( |
1161 | 1179 | mir::protobuf::InputConfigurationRequest const* request, | 1199 | mir::protobuf::InputConfigurationRequest const* request, |
1162 | 1180 | mir::protobuf::Void*, | 1200 | mir::protobuf::Void*, |
1163 | @@ -1254,7 +1274,6 @@ | |||
1164 | 1254 | screencast_buffer_tracker.remove_session(id); | 1274 | screencast_buffer_tracker.remove_session(id); |
1165 | 1255 | } | 1275 | } |
1166 | 1256 | 1276 | ||
1167 | 1257 | |||
1168 | 1258 | auto mf::detail::PromptSessionStore::insert(std::shared_ptr<PromptSession> const& session) -> PromptSessionId | 1277 | auto mf::detail::PromptSessionStore::insert(std::shared_ptr<PromptSession> const& session) -> PromptSessionId |
1169 | 1259 | { | 1278 | { |
1170 | 1260 | std::lock_guard<decltype(mutex)> lock{mutex}; | 1279 | std::lock_guard<decltype(mutex)> lock{mutex}; |
1171 | 1261 | 1280 | ||
1172 | === modified file 'src/server/frontend/session_mediator.h' | |||
1173 | --- src/server/frontend/session_mediator.h 2017-03-14 02:26:28 +0000 | |||
1174 | +++ src/server/frontend/session_mediator.h 2017-03-14 11:00:58 +0000 | |||
1175 | @@ -249,6 +249,10 @@ | |||
1176 | 249 | mir::protobuf::RaiseRequest const* request, | 249 | mir::protobuf::RaiseRequest const* request, |
1177 | 250 | mir::protobuf::Void*, | 250 | mir::protobuf::Void*, |
1178 | 251 | google::protobuf::Closure* done) override; | 251 | google::protobuf::Closure* done) override; |
1179 | 252 | void request_drag_and_drop( | ||
1180 | 253 | mir::protobuf::RequestAuthority const* request, | ||
1181 | 254 | mir::protobuf::Void*, | ||
1182 | 255 | google::protobuf::Closure* done) override; | ||
1183 | 252 | void apply_input_configuration( | 256 | void apply_input_configuration( |
1184 | 253 | mir::protobuf::InputConfigurationRequest const* request, | 257 | mir::protobuf::InputConfigurationRequest const* request, |
1185 | 254 | mir::protobuf::Void* response, | 258 | mir::protobuf::Void* response, |
1186 | 255 | 259 | ||
1187 | === modified file 'src/server/frontend/shell_wrapper.cpp' | |||
1188 | --- src/server/frontend/shell_wrapper.cpp 2017-01-18 02:29:37 +0000 | |||
1189 | +++ src/server/frontend/shell_wrapper.cpp 2017-03-14 11:00:58 +0000 | |||
1190 | @@ -106,3 +106,11 @@ | |||
1191 | 106 | { | 106 | { |
1192 | 107 | wrapped->raise_surface(session, surface_id, timestamp); | 107 | wrapped->raise_surface(session, surface_id, timestamp); |
1193 | 108 | } | 108 | } |
1194 | 109 | |||
1195 | 110 | void mf::ShellWrapper::request_drag_and_drop( | ||
1196 | 111 | std::shared_ptr<Session> const& session, | ||
1197 | 112 | SurfaceId surface_id, | ||
1198 | 113 | uint64_t timestamp) | ||
1199 | 114 | { | ||
1200 | 115 | wrapped->request_drag_and_drop(session, surface_id, timestamp); | ||
1201 | 116 | } | ||
1202 | 109 | 117 | ||
1203 | === modified file 'src/server/frontend/shell_wrapper.h' | |||
1204 | --- src/server/frontend/shell_wrapper.h 2017-01-18 02:29:37 +0000 | |||
1205 | +++ src/server/frontend/shell_wrapper.h 2017-03-14 11:00:58 +0000 | |||
1206 | @@ -80,6 +80,11 @@ | |||
1207 | 80 | SurfaceId surface_id, | 80 | SurfaceId surface_id, |
1208 | 81 | uint64_t timestamp) override; | 81 | uint64_t timestamp) override; |
1209 | 82 | 82 | ||
1210 | 83 | void request_drag_and_drop( | ||
1211 | 84 | std::shared_ptr<Session> const& session, | ||
1212 | 85 | SurfaceId surface_id, | ||
1213 | 86 | uint64_t timestamp) override; | ||
1214 | 87 | |||
1215 | 83 | protected: | 88 | protected: |
1216 | 84 | std::shared_ptr<Shell> const wrapped; | 89 | std::shared_ptr<Shell> const wrapped; |
1217 | 85 | }; | 90 | }; |
1218 | 86 | 91 | ||
1219 | === modified file 'src/server/input/null_input_targeter.h' | |||
1220 | --- src/server/input/null_input_targeter.h 2017-02-15 14:45:41 +0000 | |||
1221 | +++ src/server/input/null_input_targeter.h 2017-03-14 11:00:58 +0000 | |||
1222 | @@ -38,6 +38,9 @@ | |||
1223 | 38 | void clear_focus() override | 38 | void clear_focus() override |
1224 | 39 | { | 39 | { |
1225 | 40 | } | 40 | } |
1226 | 41 | |||
1227 | 42 | void set_drag_and_drop_handle(std::vector<uint8_t> const&) override {} | ||
1228 | 43 | void clear_drag_and_drop_handle() override {} | ||
1229 | 41 | }; | 44 | }; |
1230 | 42 | 45 | ||
1231 | 43 | } | 46 | } |
1232 | 44 | 47 | ||
1233 | === modified file 'src/server/input/surface_input_dispatcher.cpp' | |||
1234 | --- src/server/input/surface_input_dispatcher.cpp 2017-01-18 02:29:37 +0000 | |||
1235 | +++ src/server/input/surface_input_dispatcher.cpp 2017-03-14 11:00:58 +0000 | |||
1236 | @@ -70,7 +70,10 @@ | |||
1237 | 70 | std::function<void(ms::Surface*)> const on_removed; | 70 | std::function<void(ms::Surface*)> const on_removed; |
1238 | 71 | }; | 71 | }; |
1239 | 72 | 72 | ||
1241 | 73 | void deliver_without_relative_motion(std::shared_ptr<mi::Surface> const& surface, MirEvent const* ev) | 73 | void deliver_without_relative_motion( |
1242 | 74 | std::shared_ptr<mi::Surface> const& surface, | ||
1243 | 75 | MirEvent const* ev, | ||
1244 | 76 | std::vector<uint8_t> const& drag_and_drop_handle) | ||
1245 | 74 | { | 77 | { |
1246 | 75 | auto const* input_ev = mir_event_get_input_event(ev); | 78 | auto const* input_ev = mir_event_get_input_event(ev); |
1247 | 76 | auto const* pev = mir_input_event_get_pointer_event(input_ev); | 79 | auto const* pev = mir_input_event_get_pointer_event(input_ev); |
1248 | @@ -98,12 +101,21 @@ | |||
1249 | 98 | 0.0f); | 101 | 0.0f); |
1250 | 99 | 102 | ||
1251 | 100 | mev::transform_positions(*to_deliver, geom::Displacement{bounds.top_left.x.as_int(), bounds.top_left.y.as_int()}); | 103 | mev::transform_positions(*to_deliver, geom::Displacement{bounds.top_left.x.as_int(), bounds.top_left.y.as_int()}); |
1252 | 104 | if (!drag_and_drop_handle.empty()) | ||
1253 | 105 | mev::set_drag_and_drop_handle(*to_deliver, drag_and_drop_handle); | ||
1254 | 101 | surface->consume(to_deliver.get()); | 106 | surface->consume(to_deliver.get()); |
1255 | 102 | } | 107 | } |
1256 | 103 | 108 | ||
1258 | 104 | void deliver(std::shared_ptr<mi::Surface> const& surface, MirEvent const* ev) | 109 | void deliver( |
1259 | 110 | std::shared_ptr<mi::Surface> const& surface, | ||
1260 | 111 | MirEvent const* ev, | ||
1261 | 112 | std::vector<uint8_t> const& drag_and_drop_handle) | ||
1262 | 105 | { | 113 | { |
1263 | 106 | auto to_deliver = mev::clone_event(*ev); | 114 | auto to_deliver = mev::clone_event(*ev); |
1264 | 115 | |||
1265 | 116 | if (!drag_and_drop_handle.empty()) | ||
1266 | 117 | mev::set_drag_and_drop_handle(*to_deliver, drag_and_drop_handle); | ||
1267 | 118 | |||
1268 | 107 | auto const& bounds = surface->input_bounds(); | 119 | auto const& bounds = surface->input_bounds(); |
1269 | 108 | mev::transform_positions(*to_deliver, geom::Displacement{bounds.top_left.x.as_int(), bounds.top_left.y.as_int()}); | 120 | mev::transform_positions(*to_deliver, geom::Displacement{bounds.top_left.x.as_int(), bounds.top_left.y.as_int()}); |
1270 | 109 | surface->consume(to_deliver.get()); | 121 | surface->consume(to_deliver.get()); |
1271 | @@ -243,6 +255,8 @@ | |||
1272 | 243 | mir_pointer_event_axis_value(pev, mir_pointer_axis_relative_x), | 255 | mir_pointer_event_axis_value(pev, mir_pointer_axis_relative_x), |
1273 | 244 | mir_pointer_event_axis_value(pev, mir_pointer_axis_relative_y)); | 256 | mir_pointer_event_axis_value(pev, mir_pointer_axis_relative_y)); |
1274 | 245 | 257 | ||
1275 | 258 | if (!drag_and_drop_handle.empty()) | ||
1276 | 259 | mev::set_drag_and_drop_handle(*event, drag_and_drop_handle); | ||
1277 | 246 | surface->consume(event.get()); | 260 | surface->consume(event.get()); |
1278 | 247 | } | 261 | } |
1279 | 248 | 262 | ||
1280 | @@ -270,7 +284,7 @@ | |||
1281 | 270 | 284 | ||
1282 | 271 | if (pointer_state.gesture_owner) | 285 | if (pointer_state.gesture_owner) |
1283 | 272 | { | 286 | { |
1285 | 273 | deliver(pointer_state.gesture_owner, ev); | 287 | deliver(pointer_state.gesture_owner, ev, drag_and_drop_handle); |
1286 | 274 | 288 | ||
1287 | 275 | if (is_gesture_terminator(pev)) | 289 | if (is_gesture_terminator(pev)) |
1288 | 276 | { | 290 | { |
1289 | @@ -323,11 +337,11 @@ | |||
1290 | 323 | if (sent_ev) | 337 | if (sent_ev) |
1291 | 324 | { | 338 | { |
1292 | 325 | if (action != mir_pointer_action_motion) | 339 | if (action != mir_pointer_action_motion) |
1294 | 326 | deliver_without_relative_motion(target, ev); | 340 | deliver_without_relative_motion(target, ev, drag_and_drop_handle); |
1295 | 327 | } | 341 | } |
1296 | 328 | else | 342 | else |
1297 | 329 | { | 343 | { |
1299 | 330 | deliver(target, ev); | 344 | deliver(target, ev, drag_and_drop_handle); |
1300 | 331 | } | 345 | } |
1301 | 332 | return true; | 346 | return true; |
1302 | 333 | } | 347 | } |
1303 | @@ -383,7 +397,7 @@ | |||
1304 | 383 | 397 | ||
1305 | 384 | if (gesture_owner) | 398 | if (gesture_owner) |
1306 | 385 | { | 399 | { |
1308 | 386 | deliver(gesture_owner, ev); | 400 | deliver(gesture_owner, ev, drag_and_drop_handle); |
1309 | 387 | 401 | ||
1310 | 388 | if (is_gesture_end(tev)) | 402 | if (is_gesture_end(tev)) |
1311 | 389 | gesture_owner.reset(); | 403 | gesture_owner.reset(); |
1312 | @@ -450,3 +464,15 @@ | |||
1313 | 450 | set_focus_locked(lg, nullptr); | 464 | set_focus_locked(lg, nullptr); |
1314 | 451 | } | 465 | } |
1315 | 452 | 466 | ||
1316 | 467 | void mir::input::SurfaceInputDispatcher::set_drag_and_drop_handle(std::vector<uint8_t> const& handle) | ||
1317 | 468 | { | ||
1318 | 469 | std::lock_guard<std::mutex> lg(dispatcher_mutex); | ||
1319 | 470 | drag_and_drop_handle = handle; | ||
1320 | 471 | } | ||
1321 | 472 | |||
1322 | 473 | void mir::input::SurfaceInputDispatcher::clear_drag_and_drop_handle() | ||
1323 | 474 | { | ||
1324 | 475 | std::lock_guard<std::mutex> lg(dispatcher_mutex); | ||
1325 | 476 | drag_and_drop_handle.clear(); | ||
1326 | 477 | } | ||
1327 | 478 | |||
1328 | 453 | 479 | ||
1329 | === modified file 'src/server/input/surface_input_dispatcher.h' | |||
1330 | --- src/server/input/surface_input_dispatcher.h 2016-10-05 13:18:38 +0000 | |||
1331 | +++ src/server/input/surface_input_dispatcher.h 2017-03-14 11:00:58 +0000 | |||
1332 | @@ -54,7 +54,10 @@ | |||
1333 | 54 | // InputTargeter | 54 | // InputTargeter |
1334 | 55 | void set_focus(std::shared_ptr<input::Surface> const& target) override; | 55 | void set_focus(std::shared_ptr<input::Surface> const& target) override; |
1335 | 56 | void clear_focus() override; | 56 | void clear_focus() override; |
1337 | 57 | 57 | ||
1338 | 58 | void set_drag_and_drop_handle(std::vector<uint8_t> const& handle) override; | ||
1339 | 59 | void clear_drag_and_drop_handle() override; | ||
1340 | 60 | |||
1341 | 58 | private: | 61 | private: |
1342 | 59 | void device_reset(MirInputDeviceId reset_device_id, std::chrono::nanoseconds when); | 62 | void device_reset(MirInputDeviceId reset_device_id, std::chrono::nanoseconds when); |
1343 | 60 | bool dispatch_key(MirEvent const* kev); | 63 | bool dispatch_key(MirEvent const* kev); |
1344 | @@ -92,6 +95,7 @@ | |||
1345 | 92 | 95 | ||
1346 | 93 | std::mutex dispatcher_mutex; | 96 | std::mutex dispatcher_mutex; |
1347 | 94 | std::weak_ptr<input::Surface> focus_surface; | 97 | std::weak_ptr<input::Surface> focus_surface; |
1348 | 98 | std::vector<uint8_t> drag_and_drop_handle; | ||
1349 | 95 | bool started; | 99 | bool started; |
1350 | 96 | }; | 100 | }; |
1351 | 97 | 101 | ||
1352 | 98 | 102 | ||
1353 | === modified file 'src/server/scene/basic_surface.cpp' | |||
1354 | --- src/server/scene/basic_surface.cpp 2017-02-15 14:45:41 +0000 | |||
1355 | +++ src/server/scene/basic_surface.cpp 2017-03-14 11:00:58 +0000 | |||
1356 | @@ -144,6 +144,12 @@ | |||
1357 | 144 | { observer->input_consumed(event); }); | 144 | { observer->input_consumed(event); }); |
1358 | 145 | } | 145 | } |
1359 | 146 | 146 | ||
1360 | 147 | void ms::SurfaceObservers::start_drag_and_drop(std::vector<uint8_t> const& handle) | ||
1361 | 148 | { | ||
1362 | 149 | for_each([&](std::shared_ptr<SurfaceObserver> const& observer) | ||
1363 | 150 | { observer->start_drag_and_drop(handle); }); | ||
1364 | 151 | } | ||
1365 | 152 | |||
1366 | 147 | 153 | ||
1367 | 148 | struct ms::CursorStreamImageAdapter | 154 | struct ms::CursorStreamImageAdapter |
1368 | 149 | { | 155 | { |
1369 | @@ -590,6 +596,7 @@ | |||
1370 | 590 | case mir_window_attrib_dpi: return dpi_; | 596 | case mir_window_attrib_dpi: return dpi_; |
1371 | 591 | case mir_window_attrib_visibility: return visibility_; | 597 | case mir_window_attrib_visibility: return visibility_; |
1372 | 592 | case mir_window_attrib_preferred_orientation: return pref_orientation_mode; | 598 | case mir_window_attrib_preferred_orientation: return pref_orientation_mode; |
1373 | 599 | case mir_window_attrib_drag_and_drop_handle: return 0; | ||
1374 | 593 | default: BOOST_THROW_EXCEPTION(std::logic_error("Invalid surface " | 600 | default: BOOST_THROW_EXCEPTION(std::logic_error("Invalid surface " |
1375 | 594 | "attribute.")); | 601 | "attribute.")); |
1376 | 595 | } | 602 | } |
1377 | @@ -923,3 +930,8 @@ | |||
1378 | 923 | { | 930 | { |
1379 | 924 | observers.placed_relative(placement); | 931 | observers.placed_relative(placement); |
1380 | 925 | } | 932 | } |
1381 | 933 | |||
1382 | 934 | void mir::scene::BasicSurface::start_drag_and_drop(std::vector<uint8_t> const& handle) | ||
1383 | 935 | { | ||
1384 | 936 | observers.start_drag_and_drop(handle); | ||
1385 | 937 | } | ||
1386 | 926 | 938 | ||
1387 | === modified file 'src/server/scene/basic_surface.h' | |||
1388 | --- src/server/scene/basic_surface.h 2017-02-15 14:45:41 +0000 | |||
1389 | +++ src/server/scene/basic_surface.h 2017-03-14 11:00:58 +0000 | |||
1390 | @@ -139,6 +139,7 @@ | |||
1391 | 139 | void set_confine_pointer_state(MirPointerConfinementState state) override; | 139 | void set_confine_pointer_state(MirPointerConfinementState state) override; |
1392 | 140 | MirPointerConfinementState confine_pointer_state() const override; | 140 | MirPointerConfinementState confine_pointer_state() const override; |
1393 | 141 | void placed_relative(geometry::Rectangle const& placement) override; | 141 | void placed_relative(geometry::Rectangle const& placement) override; |
1394 | 142 | void start_drag_and_drop(std::vector<uint8_t> const& handle) override; | ||
1395 | 142 | 143 | ||
1396 | 143 | private: | 144 | private: |
1397 | 144 | bool visible(std::unique_lock<std::mutex>&) const; | 145 | bool visible(std::unique_lock<std::mutex>&) const; |
1398 | 145 | 146 | ||
1399 | === modified file 'src/server/scene/legacy_surface_change_notification.cpp' | |||
1400 | --- src/server/scene/legacy_surface_change_notification.cpp 2017-02-15 13:36:35 +0000 | |||
1401 | +++ src/server/scene/legacy_surface_change_notification.cpp 2017-03-14 11:00:58 +0000 | |||
1402 | @@ -108,3 +108,7 @@ | |||
1403 | 108 | void ms::LegacySurfaceChangeNotification::input_consumed(MirEvent const*) | 108 | void ms::LegacySurfaceChangeNotification::input_consumed(MirEvent const*) |
1404 | 109 | { | 109 | { |
1405 | 110 | } | 110 | } |
1406 | 111 | |||
1407 | 112 | void ms::LegacySurfaceChangeNotification::start_drag_and_drop(std::vector<uint8_t> const& /*handle*/) | ||
1408 | 113 | { | ||
1409 | 114 | } | ||
1410 | 111 | \ No newline at end of file | 115 | \ No newline at end of file |
1411 | 112 | 116 | ||
1412 | === modified file 'src/server/scene/legacy_surface_change_notification.h' | |||
1413 | --- src/server/scene/legacy_surface_change_notification.h 2017-02-15 13:36:35 +0000 | |||
1414 | +++ src/server/scene/legacy_surface_change_notification.h 2017-03-14 11:00:58 +0000 | |||
1415 | @@ -51,6 +51,7 @@ | |||
1416 | 51 | void cursor_image_removed() override; | 51 | void cursor_image_removed() override; |
1417 | 52 | void placed_relative(geometry::Rectangle const& placement) override; | 52 | void placed_relative(geometry::Rectangle const& placement) override; |
1418 | 53 | void input_consumed(MirEvent const* event) override; | 53 | void input_consumed(MirEvent const* event) override; |
1419 | 54 | void start_drag_and_drop(std::vector<uint8_t> const& handle) override; | ||
1420 | 54 | 55 | ||
1421 | 55 | private: | 56 | private: |
1422 | 56 | std::function<void()> const notify_scene_change; | 57 | std::function<void()> const notify_scene_change; |
1423 | 57 | 58 | ||
1424 | === modified file 'src/server/scene/null_surface_observer.cpp' | |||
1425 | --- src/server/scene/null_surface_observer.cpp 2017-02-15 13:36:35 +0000 | |||
1426 | +++ src/server/scene/null_surface_observer.cpp 2017-03-14 11:00:58 +0000 | |||
1427 | @@ -41,3 +41,4 @@ | |||
1428 | 41 | void ms::NullSurfaceObserver::cursor_image_removed() {} | 41 | void ms::NullSurfaceObserver::cursor_image_removed() {} |
1429 | 42 | void ms::NullSurfaceObserver::placed_relative(geometry::Rectangle const& /*placement*/) {} | 42 | void ms::NullSurfaceObserver::placed_relative(geometry::Rectangle const& /*placement*/) {} |
1430 | 43 | void ms::NullSurfaceObserver::input_consumed(MirEvent const* /*event*/) {} | 43 | void ms::NullSurfaceObserver::input_consumed(MirEvent const* /*event*/) {} |
1431 | 44 | void ms::NullSurfaceObserver::start_drag_and_drop(std::vector<uint8_t> const& /*handle*/) {} | ||
1432 | 44 | 45 | ||
1433 | === modified file 'src/server/scene/surface_event_source.cpp' | |||
1434 | --- src/server/scene/surface_event_source.cpp 2017-02-15 13:36:35 +0000 | |||
1435 | +++ src/server/scene/surface_event_source.cpp 2017-03-14 11:00:58 +0000 | |||
1436 | @@ -101,3 +101,8 @@ | |||
1437 | 101 | mev::set_window_id(*ev, id.as_value()); | 101 | mev::set_window_id(*ev, id.as_value()); |
1438 | 102 | event_sink->handle_event(*ev); | 102 | event_sink->handle_event(*ev); |
1439 | 103 | } | 103 | } |
1440 | 104 | |||
1441 | 105 | void ms::SurfaceEventSource::start_drag_and_drop(std::vector<uint8_t> const& handle) | ||
1442 | 106 | { | ||
1443 | 107 | event_sink->handle_event(*mev::make_start_drag_and_drop_event(id, handle)); | ||
1444 | 108 | } | ||
1445 | 104 | 109 | ||
1446 | === modified file 'src/server/shell/abstract_shell.cpp' | |||
1447 | --- src/server/shell/abstract_shell.cpp 2017-03-10 19:47:57 +0000 | |||
1448 | +++ src/server/shell/abstract_shell.cpp 2017-03-14 11:00:58 +0000 | |||
1449 | @@ -251,6 +251,14 @@ | |||
1450 | 251 | window_manager->handle_raise_surface(session, surface, timestamp); | 251 | window_manager->handle_raise_surface(session, surface, timestamp); |
1451 | 252 | } | 252 | } |
1452 | 253 | 253 | ||
1453 | 254 | void msh::AbstractShell::request_drag_and_drop( | ||
1454 | 255 | std::shared_ptr<scene::Session> const& session, | ||
1455 | 256 | std::shared_ptr<scene::Surface> const& surface, | ||
1456 | 257 | uint64_t timestamp) | ||
1457 | 258 | { | ||
1458 | 259 | window_manager->handle_request_drag_and_drop(session, surface, timestamp); | ||
1459 | 260 | } | ||
1460 | 261 | |||
1461 | 254 | void msh::AbstractShell::focus_next_session() | 262 | void msh::AbstractShell::focus_next_session() |
1462 | 255 | { | 263 | { |
1463 | 256 | std::unique_lock<std::mutex> lock(focus_mutex); | 264 | std::unique_lock<std::mutex> lock(focus_mutex); |
1464 | @@ -401,3 +409,12 @@ | |||
1465 | 401 | report->surfaces_raised(surfaces); | 409 | report->surfaces_raised(surfaces); |
1466 | 402 | } | 410 | } |
1467 | 403 | 411 | ||
1468 | 412 | void msh::AbstractShell::set_drag_and_drop_handle(std::vector<uint8_t> const& handle) | ||
1469 | 413 | { | ||
1470 | 414 | input_targeter->set_drag_and_drop_handle(handle); | ||
1471 | 415 | } | ||
1472 | 416 | |||
1473 | 417 | void msh::AbstractShell::clear_drag_and_drop_handle() | ||
1474 | 418 | { | ||
1475 | 419 | input_targeter->clear_drag_and_drop_handle(); | ||
1476 | 420 | } | ||
1477 | 404 | 421 | ||
1478 | === modified file 'src/server/shell/basic_window_manager.cpp' | |||
1479 | --- src/server/shell/basic_window_manager.cpp 2017-01-18 02:29:37 +0000 | |||
1480 | +++ src/server/shell/basic_window_manager.cpp 2017-03-14 11:00:58 +0000 | |||
1481 | @@ -135,6 +135,16 @@ | |||
1482 | 135 | policy->handle_raise_surface(session, surface); | 135 | policy->handle_raise_surface(session, surface); |
1483 | 136 | } | 136 | } |
1484 | 137 | 137 | ||
1485 | 138 | void msh::BasicWindowManager::handle_request_drag_and_drop( | ||
1486 | 139 | std::shared_ptr<scene::Session> const& session, | ||
1487 | 140 | std::shared_ptr<scene::Surface> const& surface, | ||
1488 | 141 | uint64_t timestamp) | ||
1489 | 142 | { | ||
1490 | 143 | std::lock_guard<decltype(mutex)> lock(mutex); | ||
1491 | 144 | if (timestamp >= last_input_event_timestamp) | ||
1492 | 145 | policy->handle_request_drag_and_drop(session, surface); | ||
1493 | 146 | } | ||
1494 | 147 | |||
1495 | 138 | int msh::BasicWindowManager::set_surface_attribute( | 148 | int msh::BasicWindowManager::set_surface_attribute( |
1496 | 139 | std::shared_ptr<scene::Session> const& /*session*/, | 149 | std::shared_ptr<scene::Session> const& /*session*/, |
1497 | 140 | std::shared_ptr<scene::Surface> const& surface, | 150 | std::shared_ptr<scene::Surface> const& surface, |
1498 | @@ -309,3 +319,14 @@ | |||
1499 | 309 | } | 319 | } |
1500 | 310 | } | 320 | } |
1501 | 311 | } | 321 | } |
1502 | 322 | |||
1503 | 323 | void mir::shell::BasicWindowManager::set_drag_and_drop_handle(std::vector<uint8_t> const& handle) | ||
1504 | 324 | { | ||
1505 | 325 | focus_controller->set_drag_and_drop_handle(handle); | ||
1506 | 326 | } | ||
1507 | 327 | |||
1508 | 328 | void mir::shell::BasicWindowManager::clear_drag_and_drop_handle() | ||
1509 | 329 | { | ||
1510 | 330 | focus_controller->clear_drag_and_drop_handle(); | ||
1511 | 331 | } | ||
1512 | 332 | |||
1513 | 312 | 333 | ||
1514 | === modified file 'src/server/shell/canonical_window_manager.cpp' | |||
1515 | --- src/server/shell/canonical_window_manager.cpp 2017-03-10 19:47:57 +0000 | |||
1516 | +++ src/server/shell/canonical_window_manager.cpp 2017-03-14 11:00:58 +0000 | |||
1517 | @@ -24,6 +24,7 @@ | |||
1518 | 24 | #include "mir/shell/surface_ready_observer.h" | 24 | #include "mir/shell/surface_ready_observer.h" |
1519 | 25 | #include "mir/shell/display_layout.h" | 25 | #include "mir/shell/display_layout.h" |
1520 | 26 | 26 | ||
1521 | 27 | #include <uuid/uuid.h> | ||
1522 | 27 | #include <linux/input.h> | 28 | #include <linux/input.h> |
1523 | 28 | #include <csignal> | 29 | #include <csignal> |
1524 | 29 | 30 | ||
1525 | @@ -583,6 +584,18 @@ | |||
1526 | 583 | select_active_surface(surface); | 584 | select_active_surface(surface); |
1527 | 584 | } | 585 | } |
1528 | 585 | 586 | ||
1529 | 587 | void msh::CanonicalWindowManagerPolicy::handle_request_drag_and_drop( | ||
1530 | 588 | std::shared_ptr<ms::Session> const& /*session*/, | ||
1531 | 589 | std::shared_ptr<ms::Surface> const& surface) | ||
1532 | 590 | { | ||
1533 | 591 | uuid_t uuid; | ||
1534 | 592 | uuid_generate(uuid); | ||
1535 | 593 | std::vector<uint8_t> const handle{std::begin(uuid), std::end(uuid)}; | ||
1536 | 594 | |||
1537 | 595 | surface->start_drag_and_drop(handle); | ||
1538 | 596 | tools->set_drag_and_drop_handle(handle); | ||
1539 | 597 | } | ||
1540 | 598 | |||
1541 | 586 | bool msh::CanonicalWindowManagerPolicy::handle_keyboard_event(MirKeyboardEvent const* event) | 599 | bool msh::CanonicalWindowManagerPolicy::handle_keyboard_event(MirKeyboardEvent const* event) |
1542 | 587 | { | 600 | { |
1543 | 588 | auto const action = mir_keyboard_event_action(event); | 601 | auto const action = mir_keyboard_event_action(event); |
1544 | 589 | 602 | ||
1545 | === modified file 'src/server/shell/frontend_shell.cpp' | |||
1546 | --- src/server/shell/frontend_shell.cpp 2017-01-18 02:29:37 +0000 | |||
1547 | +++ src/server/shell/frontend_shell.cpp 2017-03-14 11:00:58 +0000 | |||
1548 | @@ -157,3 +157,13 @@ | |||
1549 | 157 | auto const surface = scene_session->surface(surface_id); | 157 | auto const surface = scene_session->surface(surface_id); |
1550 | 158 | wrapped->raise_surface(scene_session, surface, timestamp); | 158 | wrapped->raise_surface(scene_session, surface, timestamp); |
1551 | 159 | } | 159 | } |
1552 | 160 | |||
1553 | 161 | void msh::FrontendShell::request_drag_and_drop( | ||
1554 | 162 | std::shared_ptr<mf::Session> const& session, | ||
1555 | 163 | mf::SurfaceId surface_id, | ||
1556 | 164 | uint64_t timestamp) | ||
1557 | 165 | { | ||
1558 | 166 | auto const scene_session = std::dynamic_pointer_cast<ms::Session>(session); | ||
1559 | 167 | auto const surface = scene_session->surface(surface_id); | ||
1560 | 168 | wrapped->request_drag_and_drop(scene_session, surface, timestamp); | ||
1561 | 169 | } | ||
1562 | 160 | 170 | ||
1563 | === modified file 'src/server/shell/frontend_shell.h' | |||
1564 | --- src/server/shell/frontend_shell.h 2017-01-18 02:29:37 +0000 | |||
1565 | +++ src/server/shell/frontend_shell.h 2017-03-14 11:00:58 +0000 | |||
1566 | @@ -91,6 +91,11 @@ | |||
1567 | 91 | std::shared_ptr<mf::Session> const& session, | 91 | std::shared_ptr<mf::Session> const& session, |
1568 | 92 | mf::SurfaceId surface_id, | 92 | mf::SurfaceId surface_id, |
1569 | 93 | uint64_t timestamp) override; | 93 | uint64_t timestamp) override; |
1570 | 94 | |||
1571 | 95 | void request_drag_and_drop( | ||
1572 | 96 | std::shared_ptr<mf::Session> const& session, | ||
1573 | 97 | mf::SurfaceId surface_id, | ||
1574 | 98 | uint64_t timestamp) override; | ||
1575 | 94 | }; | 99 | }; |
1576 | 95 | } | 100 | } |
1577 | 96 | } | 101 | } |
1578 | 97 | 102 | ||
1579 | === modified file 'src/server/shell/shell_wrapper.cpp' | |||
1580 | --- src/server/shell/shell_wrapper.cpp 2017-01-18 02:29:37 +0000 | |||
1581 | +++ src/server/shell/shell_wrapper.cpp 2017-03-14 11:00:58 +0000 | |||
1582 | @@ -120,6 +120,14 @@ | |||
1583 | 120 | wrapped->raise_surface(session, surface, timestamp); | 120 | wrapped->raise_surface(session, surface, timestamp); |
1584 | 121 | } | 121 | } |
1585 | 122 | 122 | ||
1586 | 123 | void msh::ShellWrapper::request_drag_and_drop( | ||
1587 | 124 | std::shared_ptr<ms::Session> const& session, | ||
1588 | 125 | std::shared_ptr<ms::Surface> const& surface, | ||
1589 | 126 | uint64_t timestamp) | ||
1590 | 127 | { | ||
1591 | 128 | wrapped->request_drag_and_drop(session, surface, timestamp); | ||
1592 | 129 | } | ||
1593 | 130 | |||
1594 | 123 | void msh::ShellWrapper::add_display(geometry::Rectangle const& area) | 131 | void msh::ShellWrapper::add_display(geometry::Rectangle const& area) |
1595 | 124 | { | 132 | { |
1596 | 125 | wrapped->add_display(area); | 133 | wrapped->add_display(area); |
1597 | @@ -149,3 +157,13 @@ | |||
1598 | 149 | { | 157 | { |
1599 | 150 | return wrapped->raise(surfaces); | 158 | return wrapped->raise(surfaces); |
1600 | 151 | } | 159 | } |
1601 | 160 | |||
1602 | 161 | void msh::ShellWrapper::set_drag_and_drop_handle(std::vector<uint8_t> const& handle) | ||
1603 | 162 | { | ||
1604 | 163 | wrapped->set_drag_and_drop_handle(handle); | ||
1605 | 164 | } | ||
1606 | 165 | |||
1607 | 166 | void msh::ShellWrapper::clear_drag_and_drop_handle() | ||
1608 | 167 | { | ||
1609 | 168 | wrapped->clear_drag_and_drop_handle(); | ||
1610 | 169 | } | ||
1611 | 152 | 170 | ||
1612 | === modified file 'src/server/shell/system_compositor_window_manager.cpp' | |||
1613 | --- src/server/shell/system_compositor_window_manager.cpp 2017-01-18 02:29:37 +0000 | |||
1614 | +++ src/server/shell/system_compositor_window_manager.cpp 2017-03-14 11:00:58 +0000 | |||
1615 | @@ -201,3 +201,10 @@ | |||
1616 | 201 | uint64_t /*timestamp*/) | 201 | uint64_t /*timestamp*/) |
1617 | 202 | { | 202 | { |
1618 | 203 | } | 203 | } |
1619 | 204 | |||
1620 | 205 | void msh::SystemCompositorWindowManager::handle_request_drag_and_drop( | ||
1621 | 206 | std::shared_ptr<ms::Session> const& /*session*/, | ||
1622 | 207 | std::shared_ptr<ms::Surface> const& /*surface*/, | ||
1623 | 208 | uint64_t /*timestamp*/) | ||
1624 | 209 | { | ||
1625 | 210 | } | ||
1626 | 204 | 211 | ||
1627 | === modified file 'src/server/symbols.map' | |||
1628 | --- src/server/symbols.map 2017-03-13 08:12:52 +0000 | |||
1629 | +++ src/server/symbols.map 2017-03-14 11:00:58 +0000 | |||
1630 | @@ -130,6 +130,7 @@ | |||
1631 | 130 | mir::scene::NullSurfaceObserver::reception_mode_set_to*; | 130 | mir::scene::NullSurfaceObserver::reception_mode_set_to*; |
1632 | 131 | mir::scene::NullSurfaceObserver::renamed*; | 131 | mir::scene::NullSurfaceObserver::renamed*; |
1633 | 132 | mir::scene::NullSurfaceObserver::resized_to*; | 132 | mir::scene::NullSurfaceObserver::resized_to*; |
1634 | 133 | mir::scene::NullSurfaceObserver::start_drag_and_drop*; | ||
1635 | 133 | mir::scene::NullSurfaceObserver::transformation_set_to*; | 134 | mir::scene::NullSurfaceObserver::transformation_set_to*; |
1636 | 134 | mir::scene::Observer::?Observer*; | 135 | mir::scene::Observer::?Observer*; |
1637 | 135 | mir::scene::Observer::Observer*; | 136 | mir::scene::Observer::Observer*; |
1638 | @@ -294,6 +295,7 @@ | |||
1639 | 294 | mir::shell::ShellReport::ShellReport*; | 295 | mir::shell::ShellReport::ShellReport*; |
1640 | 295 | mir::shell::ShellWrapper::add_display*; | 296 | mir::shell::ShellWrapper::add_display*; |
1641 | 296 | mir::shell::ShellWrapper::add_prompt_provider_for*; | 297 | mir::shell::ShellWrapper::add_prompt_provider_for*; |
1642 | 298 | mir::shell::ShellWrapper::clear_drag_and_drop_handle*; | ||
1643 | 297 | mir::shell::ShellWrapper::close_session*; | 299 | mir::shell::ShellWrapper::close_session*; |
1644 | 298 | mir::shell::ShellWrapper::create_surface*; | 300 | mir::shell::ShellWrapper::create_surface*; |
1645 | 299 | mir::shell::ShellWrapper::destroy_surface*; | 301 | mir::shell::ShellWrapper::destroy_surface*; |
1646 | @@ -307,9 +309,11 @@ | |||
1647 | 307 | mir::shell::ShellWrapper::raise*; | 309 | mir::shell::ShellWrapper::raise*; |
1648 | 308 | mir::shell::ShellWrapper::raise_surface*; | 310 | mir::shell::ShellWrapper::raise_surface*; |
1649 | 309 | mir::shell::ShellWrapper::remove_display*; | 311 | mir::shell::ShellWrapper::remove_display*; |
1650 | 312 | mir::shell::ShellWrapper::request_drag_and_drop*; | ||
1651 | 310 | mir::shell::ShellWrapper::set_focus_to*; | 313 | mir::shell::ShellWrapper::set_focus_to*; |
1652 | 311 | mir::shell::ShellWrapper::set_surface_attribute*; | 314 | mir::shell::ShellWrapper::set_surface_attribute*; |
1653 | 312 | mir::shell::ShellWrapper::ShellWrapper*; | 315 | mir::shell::ShellWrapper::ShellWrapper*; |
1654 | 316 | mir::shell::ShellWrapper::set_drag_and_drop_handle*; | ||
1655 | 313 | mir::shell::ShellWrapper::start_prompt_session_for*; | 317 | mir::shell::ShellWrapper::start_prompt_session_for*; |
1656 | 314 | mir::shell::ShellWrapper::stop_prompt_session*; | 318 | mir::shell::ShellWrapper::stop_prompt_session*; |
1657 | 315 | mir::shell::ShellWrapper::surface_at*; | 319 | mir::shell::ShellWrapper::surface_at*; |
1658 | @@ -339,6 +343,7 @@ | |||
1659 | 339 | mir::shell::SystemCompositorWindowManager::remove_display*; | 343 | mir::shell::SystemCompositorWindowManager::remove_display*; |
1660 | 340 | mir::shell::SystemCompositorWindowManager::remove_session*; | 344 | mir::shell::SystemCompositorWindowManager::remove_session*; |
1661 | 341 | mir::shell::SystemCompositorWindowManager::remove_surface*; | 345 | mir::shell::SystemCompositorWindowManager::remove_surface*; |
1662 | 346 | mir::shell::SystemCompositorWindowManager::handle_request_drag_and_drop*; | ||
1663 | 342 | mir::shell::SystemCompositorWindowManager::set_surface_attribute*; | 347 | mir::shell::SystemCompositorWindowManager::set_surface_attribute*; |
1664 | 343 | mir::shell::SystemCompositorWindowManager::SystemCompositorWindowManager*; | 348 | mir::shell::SystemCompositorWindowManager::SystemCompositorWindowManager*; |
1665 | 344 | mir::shell::WindowManager::operator*; | 349 | mir::shell::WindowManager::operator*; |
1666 | @@ -696,6 +701,7 @@ | |||
1667 | 696 | mir::shell::CanonicalWindowManagerPolicy::handle_touch_event*; | 701 | mir::shell::CanonicalWindowManagerPolicy::handle_touch_event*; |
1668 | 697 | mir::shell::CanonicalWindowManagerPolicy::handle_pointer_event*; | 702 | mir::shell::CanonicalWindowManagerPolicy::handle_pointer_event*; |
1669 | 698 | mir::shell::CanonicalWindowManagerPolicy::handle_raise_surface*; | 703 | mir::shell::CanonicalWindowManagerPolicy::handle_raise_surface*; |
1670 | 704 | mir::shell::CanonicalWindowManagerPolicy::handle_request_drag_and_drop*; | ||
1671 | 699 | typeinfo?for?mir::shell::CanonicalWindowManagerPolicy; | 705 | typeinfo?for?mir::shell::CanonicalWindowManagerPolicy; |
1672 | 700 | vtable?for?mir::shell::CanonicalWindowManagerPolicy; | 706 | vtable?for?mir::shell::CanonicalWindowManagerPolicy; |
1673 | 701 | VTT?for?mir::shell::CanonicalWindowManagerPolicy; | 707 | VTT?for?mir::shell::CanonicalWindowManagerPolicy; |
1674 | @@ -832,6 +838,7 @@ | |||
1675 | 832 | mir::shell::BasicWindowManager::add_session*; | 838 | mir::shell::BasicWindowManager::add_session*; |
1676 | 833 | mir::shell::BasicWindowManager::add_surface*; | 839 | mir::shell::BasicWindowManager::add_surface*; |
1677 | 834 | mir::shell::BasicWindowManager::BasicWindowManager*; | 840 | mir::shell::BasicWindowManager::BasicWindowManager*; |
1678 | 841 | mir::shell::BasicWindowManager::clear_drag_and_drop_handle*; | ||
1679 | 835 | mir::shell::BasicWindowManager::find_session*; | 842 | mir::shell::BasicWindowManager::find_session*; |
1680 | 836 | mir::shell::BasicWindowManager::focused_session*; | 843 | mir::shell::BasicWindowManager::focused_session*; |
1681 | 837 | mir::shell::BasicWindowManager::focused_surface*; | 844 | mir::shell::BasicWindowManager::focused_surface*; |
1682 | @@ -840,6 +847,7 @@ | |||
1683 | 840 | mir::shell::BasicWindowManager::handle_keyboard_event*; | 847 | mir::shell::BasicWindowManager::handle_keyboard_event*; |
1684 | 841 | mir::shell::BasicWindowManager::handle_pointer_event*; | 848 | mir::shell::BasicWindowManager::handle_pointer_event*; |
1685 | 842 | mir::shell::BasicWindowManager::handle_raise_surface*; | 849 | mir::shell::BasicWindowManager::handle_raise_surface*; |
1686 | 850 | mir::shell::BasicWindowManager::handle_request_drag_and_drop*; | ||
1687 | 843 | mir::shell::BasicWindowManager::handle_touch_event*; | 851 | mir::shell::BasicWindowManager::handle_touch_event*; |
1688 | 844 | mir::shell::BasicWindowManager::info_for*; | 852 | mir::shell::BasicWindowManager::info_for*; |
1689 | 845 | mir::shell::BasicWindowManager::modify_surface*; | 853 | mir::shell::BasicWindowManager::modify_surface*; |
1690 | @@ -847,6 +855,7 @@ | |||
1691 | 847 | mir::shell::BasicWindowManager::remove_display*; | 855 | mir::shell::BasicWindowManager::remove_display*; |
1692 | 848 | mir::shell::BasicWindowManager::remove_session*; | 856 | mir::shell::BasicWindowManager::remove_session*; |
1693 | 849 | mir::shell::BasicWindowManager::remove_surface*; | 857 | mir::shell::BasicWindowManager::remove_surface*; |
1694 | 858 | mir::shell::BasicWindowManager::set_drag_and_drop_handle*; | ||
1695 | 850 | mir::shell::BasicWindowManager::set_focus_to*; | 859 | mir::shell::BasicWindowManager::set_focus_to*; |
1696 | 851 | mir::shell::BasicWindowManager::set_surface_attribute*; | 860 | mir::shell::BasicWindowManager::set_surface_attribute*; |
1697 | 852 | mir::shell::BasicWindowManager::surface_at*; | 861 | mir::shell::BasicWindowManager::surface_at*; |
1698 | @@ -857,6 +866,7 @@ | |||
1699 | 857 | virtual?thunk?to?mir::shell::BasicWindowManager::handle_keyboard_event*; | 866 | virtual?thunk?to?mir::shell::BasicWindowManager::handle_keyboard_event*; |
1700 | 858 | virtual?thunk?to?mir::shell::BasicWindowManager::handle_pointer_event*; | 867 | virtual?thunk?to?mir::shell::BasicWindowManager::handle_pointer_event*; |
1701 | 859 | virtual?thunk?to?mir::shell::BasicWindowManager::handle_raise_surface*; | 868 | virtual?thunk?to?mir::shell::BasicWindowManager::handle_raise_surface*; |
1702 | 869 | virtual?thunk?to?mir::shell::BasicWindowManager::handle_request_drag_and_drop*; | ||
1703 | 860 | virtual?thunk?to?mir::shell::BasicWindowManager::handle_touch_event*; | 870 | virtual?thunk?to?mir::shell::BasicWindowManager::handle_touch_event*; |
1704 | 861 | virtual?thunk?to?mir::shell::BasicWindowManager::modify_surface*; | 871 | virtual?thunk?to?mir::shell::BasicWindowManager::modify_surface*; |
1705 | 862 | virtual?thunk?to?mir::shell::BasicWindowManager::remove_display*; | 872 | virtual?thunk?to?mir::shell::BasicWindowManager::remove_display*; |
1706 | 863 | 873 | ||
1707 | === modified file 'tests/acceptance-tests/CMakeLists.txt' | |||
1708 | --- tests/acceptance-tests/CMakeLists.txt 2017-03-10 19:47:57 +0000 | |||
1709 | +++ tests/acceptance-tests/CMakeLists.txt 2017-03-14 11:00:58 +0000 | |||
1710 | @@ -3,6 +3,8 @@ | |||
1711 | 3 | set( | 3 | set( |
1712 | 4 | SOURCES | 4 | SOURCES |
1713 | 5 | 5 | ||
1714 | 6 | drag_and_drop.cpp | ||
1715 | 7 | |||
1716 | 6 | # Catch double-free bugs by wrapping close() and abort()ing on EBADF | 8 | # Catch double-free bugs by wrapping close() and abort()ing on EBADF |
1717 | 7 | strict_close.cpp | 9 | strict_close.cpp |
1718 | 8 | 10 | ||
1719 | 9 | 11 | ||
1720 | === added file 'tests/acceptance-tests/drag_and_drop.cpp' | |||
1721 | --- tests/acceptance-tests/drag_and_drop.cpp 1970-01-01 00:00:00 +0000 | |||
1722 | +++ tests/acceptance-tests/drag_and_drop.cpp 2017-03-14 11:00:58 +0000 | |||
1723 | @@ -0,0 +1,293 @@ | |||
1724 | 1 | /* | ||
1725 | 2 | * Copyright © 2017 Canonical Ltd. | ||
1726 | 3 | * | ||
1727 | 4 | * This program is free software: you can redistribute it and/or modify it | ||
1728 | 5 | * under the terms of the GNU General Public License version 3, | ||
1729 | 6 | * as published by the Free Software Foundation. | ||
1730 | 7 | * | ||
1731 | 8 | * This program is distributed in the hope that it will be useful, | ||
1732 | 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
1733 | 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
1734 | 11 | * GNU General Public License for more details. | ||
1735 | 12 | * | ||
1736 | 13 | * You should have received a copy of the GNU General Public License | ||
1737 | 14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
1738 | 15 | * | ||
1739 | 16 | * Authored by: Alan Griffiths <alan@octopull.co.uk> | ||
1740 | 17 | */ | ||
1741 | 18 | |||
1742 | 19 | #include <mir_toolkit/extensions/drag_and_drop.h> | ||
1743 | 20 | #include <mir_toolkit/mir_blob.h> | ||
1744 | 21 | |||
1745 | 22 | #include <mir/geometry/displacement.h> | ||
1746 | 23 | #include <mir/input/input_device_info.h> | ||
1747 | 24 | #include <mir/input/device_capability.h> | ||
1748 | 25 | #include <mir/shell/shell.h> | ||
1749 | 26 | |||
1750 | 27 | #include <mir_test_framework/connected_client_with_a_window.h> | ||
1751 | 28 | #include <mir_test_framework/fake_input_device.h> | ||
1752 | 29 | #include <mir_test_framework/stub_server_platform_factory.h> | ||
1753 | 30 | #include <mir/test/event_factory.h> | ||
1754 | 31 | #include <mir/test/signal.h> | ||
1755 | 32 | |||
1756 | 33 | #include <gmock/gmock.h> | ||
1757 | 34 | #include <gtest/gtest.h> | ||
1758 | 35 | |||
1759 | 36 | #include <linux/input.h> | ||
1760 | 37 | |||
1761 | 38 | #include <boost/throw_exception.hpp> | ||
1762 | 39 | |||
1763 | 40 | using namespace std::chrono_literals; | ||
1764 | 41 | using namespace mir::geometry; | ||
1765 | 42 | using namespace testing; | ||
1766 | 43 | using mir::test::Signal; | ||
1767 | 44 | |||
1768 | 45 | namespace | ||
1769 | 46 | { | ||
1770 | 47 | class Cookie | ||
1771 | 48 | { | ||
1772 | 49 | public: | ||
1773 | 50 | Cookie() = default; | ||
1774 | 51 | explicit Cookie(MirCookie const* cookie) : self{cookie, deleter} {} | ||
1775 | 52 | |||
1776 | 53 | operator MirCookie const*() const { return self.get(); } | ||
1777 | 54 | auto get() const -> MirCookie const* { return self.get(); } | ||
1778 | 55 | |||
1779 | 56 | void reset() { self.reset(); } | ||
1780 | 57 | void reset(MirCookie const* cookie) { self.reset(cookie, deleter); } | ||
1781 | 58 | |||
1782 | 59 | private: | ||
1783 | 60 | static void deleter(MirCookie const* cookie) { mir_cookie_release(cookie); } | ||
1784 | 61 | std::shared_ptr<MirCookie const> self; | ||
1785 | 62 | }; | ||
1786 | 63 | |||
1787 | 64 | void mir_cookie_release(Cookie const&) = delete; | ||
1788 | 65 | |||
1789 | 66 | class Blob | ||
1790 | 67 | { | ||
1791 | 68 | public: | ||
1792 | 69 | Blob() = default; | ||
1793 | 70 | explicit Blob(MirBlob* blob) : self{blob, deleter} {} | ||
1794 | 71 | |||
1795 | 72 | operator MirBlob*() const { return self.get(); } | ||
1796 | 73 | auto get() const -> MirBlob* { return self.get(); } | ||
1797 | 74 | |||
1798 | 75 | void reset() { self.reset(); } | ||
1799 | 76 | void reset(MirBlob* blob) { self.reset(blob, deleter); } | ||
1800 | 77 | |||
1801 | 78 | private: | ||
1802 | 79 | static void deleter(MirBlob* blob) { mir_blob_release(blob); } | ||
1803 | 80 | std::shared_ptr<MirBlob> self; | ||
1804 | 81 | }; | ||
1805 | 82 | |||
1806 | 83 | void mir_blob_release(Blob const&) = delete; | ||
1807 | 84 | |||
1808 | 85 | struct MouseMoverAndFaker | ||
1809 | 86 | { | ||
1810 | 87 | void start_dragging_mouse() | ||
1811 | 88 | { | ||
1812 | 89 | using namespace mir::input::synthesis; | ||
1813 | 90 | fake_mouse->emit_event(a_button_down_event().of_button(BTN_LEFT)); | ||
1814 | 91 | } | ||
1815 | 92 | |||
1816 | 93 | void move_mouse(Displacement const& displacement) | ||
1817 | 94 | { | ||
1818 | 95 | using mir::input::synthesis::a_pointer_event; | ||
1819 | 96 | fake_mouse->emit_event(a_pointer_event().with_movement(displacement.dx.as_int(), displacement.dy.as_int())); | ||
1820 | 97 | } | ||
1821 | 98 | |||
1822 | 99 | private: | ||
1823 | 100 | std::unique_ptr<mir_test_framework::FakeInputDevice> fake_mouse{ | ||
1824 | 101 | mir_test_framework::add_fake_input_device( | ||
1825 | 102 | mir::input::InputDeviceInfo{"mouse", "mouse-uid", mir::input::DeviceCapability::pointer})}; | ||
1826 | 103 | }; | ||
1827 | 104 | |||
1828 | 105 | Rectangle const screen_geometry{{0,0}, {800,600}}; | ||
1829 | 106 | auto const receive_event_timeout = 90s; | ||
1830 | 107 | |||
1831 | 108 | struct DragAndDrop : mir_test_framework::ConnectedClientWithAWindow, | ||
1832 | 109 | MouseMoverAndFaker | ||
1833 | 110 | { | ||
1834 | 111 | MirDragAndDropV1 const* dnd = nullptr; | ||
1835 | 112 | |||
1836 | 113 | void SetUp() override | ||
1837 | 114 | { | ||
1838 | 115 | initial_display_layout({screen_geometry}); | ||
1839 | 116 | mir_test_framework::ConnectedClientWithAWindow::SetUp(); | ||
1840 | 117 | |||
1841 | 118 | dnd = mir_drag_and_drop_v1(connection); | ||
1842 | 119 | |||
1843 | 120 | paint_window(); | ||
1844 | 121 | mir_window_set_event_handler(window, &window_event_handler, this); | ||
1845 | 122 | |||
1846 | 123 | center_mouse(); | ||
1847 | 124 | } | ||
1848 | 125 | |||
1849 | 126 | void TearDown() override | ||
1850 | 127 | { | ||
1851 | 128 | set_window_event_handler([&](MirWindow*, MirEvent const*) {}); | ||
1852 | 129 | mir_test_framework::ConnectedClientWithAWindow::TearDown(); | ||
1853 | 130 | } | ||
1854 | 131 | |||
1855 | 132 | auto user_initiates_drag() -> Cookie; | ||
1856 | 133 | auto client_requests_drag(Cookie const& cookie) -> Blob; | ||
1857 | 134 | auto handle_from_mouse_move() -> Blob; | ||
1858 | 135 | |||
1859 | 136 | private: | ||
1860 | 137 | void center_mouse() { move_mouse(0.5 * as_displacement(screen_geometry.size)); } | ||
1861 | 138 | void paint_window() const { mir_buffer_stream_swap_buffers_sync(mir_window_get_buffer_stream(window)); } | ||
1862 | 139 | void set_window_event_handler(std::function<void(MirWindow* window, MirEvent const* event)> const& handler); | ||
1863 | 140 | |||
1864 | 141 | void invoke_window_event_handler(MirWindow* window, MirEvent const* event) | ||
1865 | 142 | { | ||
1866 | 143 | std::lock_guard<decltype(window_event_handler_mutex)> lock{window_event_handler_mutex}; | ||
1867 | 144 | window_event_handler_(window, event); | ||
1868 | 145 | } | ||
1869 | 146 | |||
1870 | 147 | std::mutex window_event_handler_mutex; | ||
1871 | 148 | std::function<void(MirWindow* window, MirEvent const* event)> window_event_handler_ = | ||
1872 | 149 | [](MirWindow*, MirEvent const*) {}; | ||
1873 | 150 | |||
1874 | 151 | static void window_event_handler(MirWindow* window, MirEvent const* event, void* context); | ||
1875 | 152 | }; | ||
1876 | 153 | |||
1877 | 154 | void DragAndDrop::set_window_event_handler(std::function<void(MirWindow* window, MirEvent const* event)> const& handler) | ||
1878 | 155 | { | ||
1879 | 156 | std::lock_guard<decltype(window_event_handler_mutex)> lock{window_event_handler_mutex}; | ||
1880 | 157 | window_event_handler_ = handler; | ||
1881 | 158 | } | ||
1882 | 159 | |||
1883 | 160 | void DragAndDrop::window_event_handler(MirWindow* window, MirEvent const* event, void* context) | ||
1884 | 161 | { | ||
1885 | 162 | static_cast<DragAndDrop*>(context)->invoke_window_event_handler(window, event); | ||
1886 | 163 | } | ||
1887 | 164 | |||
1888 | 165 | auto DragAndDrop::user_initiates_drag() -> Cookie | ||
1889 | 166 | { | ||
1890 | 167 | Cookie cookie; | ||
1891 | 168 | Signal have_cookie; | ||
1892 | 169 | |||
1893 | 170 | set_window_event_handler([&](MirWindow*, MirEvent const* event) | ||
1894 | 171 | { | ||
1895 | 172 | if (mir_event_get_type(event) != mir_event_type_input) | ||
1896 | 173 | return; | ||
1897 | 174 | |||
1898 | 175 | auto const input_event = mir_event_get_input_event(event); | ||
1899 | 176 | |||
1900 | 177 | if (mir_input_event_get_type(input_event) != mir_input_event_type_pointer) | ||
1901 | 178 | return; | ||
1902 | 179 | |||
1903 | 180 | auto const pointer_event = mir_input_event_get_pointer_event(input_event); | ||
1904 | 181 | |||
1905 | 182 | if (mir_pointer_event_action(pointer_event) != mir_pointer_action_button_down) | ||
1906 | 183 | return; | ||
1907 | 184 | |||
1908 | 185 | cookie = Cookie{mir_input_event_get_cookie(input_event)}; | ||
1909 | 186 | have_cookie.raise(); | ||
1910 | 187 | }); | ||
1911 | 188 | |||
1912 | 189 | start_dragging_mouse(); | ||
1913 | 190 | |||
1914 | 191 | EXPECT_THAT(have_cookie.wait_for(receive_event_timeout), Eq(true)); | ||
1915 | 192 | |||
1916 | 193 | return cookie; | ||
1917 | 194 | } | ||
1918 | 195 | |||
1919 | 196 | auto DragAndDrop::client_requests_drag(Cookie const& cookie) -> Blob | ||
1920 | 197 | { | ||
1921 | 198 | Blob blob; | ||
1922 | 199 | Signal initiated; | ||
1923 | 200 | |||
1924 | 201 | set_window_event_handler([&](MirWindow*, MirEvent const* event) | ||
1925 | 202 | { | ||
1926 | 203 | if (mir_event_get_type(event) != mir_event_type_window) | ||
1927 | 204 | return; | ||
1928 | 205 | |||
1929 | 206 | if (!dnd) return; | ||
1930 | 207 | |||
1931 | 208 | blob.reset(dnd->start_drag_and_drop(mir_event_get_window_event(event))); | ||
1932 | 209 | |||
1933 | 210 | if (blob) | ||
1934 | 211 | initiated.raise(); | ||
1935 | 212 | }); | ||
1936 | 213 | |||
1937 | 214 | EXPECT_THAT(dnd, Ne(nullptr)) << "No Drag and Drop extension"; | ||
1938 | 215 | |||
1939 | 216 | if (dnd) | ||
1940 | 217 | dnd->request_drag_and_drop(window, cookie); | ||
1941 | 218 | |||
1942 | 219 | EXPECT_TRUE(initiated.wait_for(receive_event_timeout)); | ||
1943 | 220 | |||
1944 | 221 | return blob; | ||
1945 | 222 | } | ||
1946 | 223 | |||
1947 | 224 | auto DragAndDrop::handle_from_mouse_move() -> Blob | ||
1948 | 225 | { | ||
1949 | 226 | Blob blob; | ||
1950 | 227 | Signal have_blob; | ||
1951 | 228 | |||
1952 | 229 | set_window_event_handler([&](MirWindow*, MirEvent const* event) | ||
1953 | 230 | { | ||
1954 | 231 | if (mir_event_get_type(event) != mir_event_type_input) | ||
1955 | 232 | return; | ||
1956 | 233 | |||
1957 | 234 | auto const input_event = mir_event_get_input_event(event); | ||
1958 | 235 | |||
1959 | 236 | if (mir_input_event_get_type(input_event) != mir_input_event_type_pointer) | ||
1960 | 237 | return; | ||
1961 | 238 | |||
1962 | 239 | auto const pointer_event = mir_input_event_get_pointer_event(input_event); | ||
1963 | 240 | |||
1964 | 241 | EXPECT_THAT(dnd, Ne(nullptr)) << "No Drag and Drop extension"; | ||
1965 | 242 | |||
1966 | 243 | if (dnd) | ||
1967 | 244 | blob.reset(dnd->pointer_drag_and_drop(pointer_event)); | ||
1968 | 245 | |||
1969 | 246 | if (blob) | ||
1970 | 247 | have_blob.raise(); | ||
1971 | 248 | }); | ||
1972 | 249 | |||
1973 | 250 | move_mouse({1,1}); | ||
1974 | 251 | |||
1975 | 252 | EXPECT_TRUE(have_blob.wait_for(receive_event_timeout)); | ||
1976 | 253 | return blob; | ||
1977 | 254 | } | ||
1978 | 255 | |||
1979 | 256 | MATCHER_P(BlobContentEq, p, "") | ||
1980 | 257 | { | ||
1981 | 258 | if (!arg || !p) | ||
1982 | 259 | return false; | ||
1983 | 260 | if (mir_blob_size(arg) != mir_blob_size(p)) | ||
1984 | 261 | return false; | ||
1985 | 262 | return !memcmp(mir_blob_data(arg), mir_blob_data(p), mir_blob_size(p)); | ||
1986 | 263 | } | ||
1987 | 264 | } | ||
1988 | 265 | |||
1989 | 266 | TEST_F(DragAndDrop, when_user_initiates_drag_client_receives_cookie) | ||
1990 | 267 | { | ||
1991 | 268 | auto const cookie = user_initiates_drag(); | ||
1992 | 269 | |||
1993 | 270 | EXPECT_THAT(cookie.get(), NotNull()); | ||
1994 | 271 | } | ||
1995 | 272 | |||
1996 | 273 | TEST_F(DragAndDrop, when_client_requests_drags_it_receives_handle) | ||
1997 | 274 | { | ||
1998 | 275 | auto const cookie = user_initiates_drag(); | ||
1999 | 276 | ASSERT_THAT(cookie.get(), NotNull()); | ||
2000 | 277 | |||
2001 | 278 | auto const handle = client_requests_drag(cookie); | ||
2002 | 279 | |||
2003 | 280 | EXPECT_THAT(handle.get(), NotNull()); | ||
2004 | 281 | } | ||
2005 | 282 | |||
2006 | 283 | TEST_F(DragAndDrop, during_drag_when_user_moves_mouse_client_receives_handle) | ||
2007 | 284 | { | ||
2008 | 285 | auto const cookie = user_initiates_drag(); | ||
2009 | 286 | ASSERT_THAT(cookie.get(), NotNull()); | ||
2010 | 287 | auto const handle_from_request = client_requests_drag(cookie); | ||
2011 | 288 | |||
2012 | 289 | auto const handle = handle_from_mouse_move(); | ||
2013 | 290 | |||
2014 | 291 | EXPECT_THAT(handle.get(), NotNull()); | ||
2015 | 292 | EXPECT_THAT(handle.get(), BlobContentEq(handle_from_request.get())); | ||
2016 | 293 | } | ||
2017 | 0 | 294 | ||
2018 | === modified file 'tests/acceptance-tests/test_client_cursor_api.cpp' | |||
2019 | --- tests/acceptance-tests/test_client_cursor_api.cpp 2017-02-28 08:53:57 +0000 | |||
2020 | +++ tests/acceptance-tests/test_client_cursor_api.cpp 2017-03-14 11:00:58 +0000 | |||
2021 | @@ -82,6 +82,7 @@ | |||
2022 | 82 | MOCK_METHOD0(cursor_image_removed, void()); | 82 | MOCK_METHOD0(cursor_image_removed, void()); |
2023 | 83 | MOCK_METHOD1(placed_relative, void(geom::Rectangle const& placement)); | 83 | MOCK_METHOD1(placed_relative, void(geom::Rectangle const& placement)); |
2024 | 84 | MOCK_METHOD1(input_consumed, void(MirEvent const*)); | 84 | MOCK_METHOD1(input_consumed, void(MirEvent const*)); |
2025 | 85 | MOCK_METHOD1(start_drag_and_drop, void(std::vector<uint8_t> const& handle)); | ||
2026 | 85 | }; | 86 | }; |
2027 | 86 | 87 | ||
2028 | 87 | 88 | ||
2029 | 88 | 89 | ||
2030 | === modified file 'tests/include/mir/test/doubles/mock_input_targeter.h' | |||
2031 | --- tests/include/mir/test/doubles/mock_input_targeter.h 2015-06-18 02:46:16 +0000 | |||
2032 | +++ tests/include/mir/test/doubles/mock_input_targeter.h 2017-03-14 11:00:58 +0000 | |||
2033 | @@ -35,6 +35,9 @@ | |||
2034 | 35 | virtual ~MockInputTargeter() noexcept(true) {} | 35 | virtual ~MockInputTargeter() noexcept(true) {} |
2035 | 36 | MOCK_METHOD1(set_focus, void(std::shared_ptr<input::Surface> const&)); | 36 | MOCK_METHOD1(set_focus, void(std::shared_ptr<input::Surface> const&)); |
2036 | 37 | MOCK_METHOD0(clear_focus, void()); | 37 | MOCK_METHOD0(clear_focus, void()); |
2037 | 38 | |||
2038 | 39 | void set_drag_and_drop_handle(std::vector<uint8_t> const&) override {} | ||
2039 | 40 | void clear_drag_and_drop_handle() override {} | ||
2040 | 38 | }; | 41 | }; |
2041 | 39 | 42 | ||
2042 | 40 | } | 43 | } |
2043 | 41 | 44 | ||
2044 | === modified file 'tests/include/mir/test/doubles/mock_shell.h' | |||
2045 | --- tests/include/mir/test/doubles/mock_shell.h 2017-01-18 02:29:37 +0000 | |||
2046 | +++ tests/include/mir/test/doubles/mock_shell.h 2017-03-14 11:00:58 +0000 | |||
2047 | @@ -72,6 +72,9 @@ | |||
2048 | 72 | 72 | ||
2049 | 73 | MOCK_METHOD3(raise_surface, void(std::shared_ptr<frontend::Session> const& session, | 73 | MOCK_METHOD3(raise_surface, void(std::shared_ptr<frontend::Session> const& session, |
2050 | 74 | frontend::SurfaceId surface_id, uint64_t timestamp)); | 74 | frontend::SurfaceId surface_id, uint64_t timestamp)); |
2051 | 75 | |||
2052 | 76 | MOCK_METHOD3(request_drag_and_drop, void(std::shared_ptr<frontend::Session> const& session, | ||
2053 | 77 | frontend::SurfaceId surface_id, uint64_t timestamp)); | ||
2054 | 75 | }; | 78 | }; |
2055 | 76 | 79 | ||
2056 | 77 | } | 80 | } |
2057 | 78 | 81 | ||
2058 | === modified file 'tests/include/mir/test/doubles/stub_display_server.h' | |||
2059 | --- tests/include/mir/test/doubles/stub_display_server.h 2017-02-15 07:38:33 +0000 | |||
2060 | +++ tests/include/mir/test/doubles/stub_display_server.h 2017-03-14 11:00:58 +0000 | |||
2061 | @@ -158,6 +158,10 @@ | |||
2062 | 158 | mir::protobuf::RaiseRequest const* /*request*/, | 158 | mir::protobuf::RaiseRequest const* /*request*/, |
2063 | 159 | mir::protobuf::Void* /*response*/, | 159 | mir::protobuf::Void* /*response*/, |
2064 | 160 | google::protobuf::Closure* /*done*/) {} | 160 | google::protobuf::Closure* /*done*/) {} |
2065 | 161 | void request_drag_and_drop( | ||
2066 | 162 | mir::protobuf::RequestAuthority const* /*request*/, | ||
2067 | 163 | mir::protobuf::Void* /*response*/, | ||
2068 | 164 | google::protobuf::Closure* /*done*/) {} | ||
2069 | 161 | void apply_input_configuration( | 165 | void apply_input_configuration( |
2070 | 162 | mir::protobuf::InputConfigurationRequest const* /*request*/, | 166 | mir::protobuf::InputConfigurationRequest const* /*request*/, |
2071 | 163 | mir::protobuf::Void* /*response*/, | 167 | mir::protobuf::Void* /*response*/, |
2072 | 164 | 168 | ||
2073 | === modified file 'tests/include/mir/test/doubles/stub_input_targeter.h' | |||
2074 | --- tests/include/mir/test/doubles/stub_input_targeter.h 2015-06-18 02:46:16 +0000 | |||
2075 | +++ tests/include/mir/test/doubles/stub_input_targeter.h 2017-03-14 11:00:58 +0000 | |||
2076 | @@ -36,6 +36,9 @@ | |||
2077 | 36 | void clear_focus() | 36 | void clear_focus() |
2078 | 37 | { | 37 | { |
2079 | 38 | } | 38 | } |
2080 | 39 | |||
2081 | 40 | void set_drag_and_drop_handle(std::vector<uint8_t> const&) override {} | ||
2082 | 41 | void clear_drag_and_drop_handle() override {} | ||
2083 | 39 | }; | 42 | }; |
2084 | 40 | 43 | ||
2085 | 41 | } | 44 | } |
2086 | 42 | 45 | ||
2087 | === modified file 'tests/include/mir/test/doubles/stub_scene_surface.h' | |||
2088 | --- tests/include/mir/test/doubles/stub_scene_surface.h 2017-02-15 14:45:41 +0000 | |||
2089 | +++ tests/include/mir/test/doubles/stub_scene_surface.h 2017-03-14 11:00:58 +0000 | |||
2090 | @@ -94,6 +94,7 @@ | |||
2091 | 94 | void set_confine_pointer_state(MirPointerConfinementState /*state*/) override {} | 94 | void set_confine_pointer_state(MirPointerConfinementState /*state*/) override {} |
2092 | 95 | MirPointerConfinementState confine_pointer_state() const override { return {}; } | 95 | MirPointerConfinementState confine_pointer_state() const override { return {}; } |
2093 | 96 | void placed_relative(geometry::Rectangle const& /*placement*/) override {} | 96 | void placed_relative(geometry::Rectangle const& /*placement*/) override {} |
2094 | 97 | void start_drag_and_drop(std::vector<uint8_t> const& /*handle*/) override {} | ||
2095 | 97 | }; | 98 | }; |
2096 | 98 | 99 | ||
2097 | 99 | } | 100 | } |
2098 | 100 | 101 | ||
2099 | === modified file 'tests/mir_test_framework/observant_shell.cpp' | |||
2100 | --- tests/mir_test_framework/observant_shell.cpp 2017-01-20 00:01:50 +0000 | |||
2101 | +++ tests/mir_test_framework/observant_shell.cpp 2017-03-14 11:00:58 +0000 | |||
2102 | @@ -155,7 +155,26 @@ | |||
2103 | 155 | void mtf::ObservantShell::raise_surface( | 155 | void mtf::ObservantShell::raise_surface( |
2104 | 156 | std::shared_ptr<msc::Session> const& session, | 156 | std::shared_ptr<msc::Session> const& session, |
2105 | 157 | std::shared_ptr<msc::Surface> const& window, | 157 | std::shared_ptr<msc::Surface> const& window, |
2106 | 158 | uint64_t timestamp) | ||
2107 | 159 | { | ||
2108 | 160 | return wrapped->raise_surface(session, window, timestamp); | ||
2109 | 161 | } | ||
2110 | 162 | |||
2111 | 163 | void mtf::ObservantShell::request_drag_and_drop( | ||
2112 | 164 | std::shared_ptr<msc::Session> const& session, | ||
2113 | 165 | std::shared_ptr<msc::Surface> const& window, | ||
2114 | 158 | uint64_t timestamp) | 166 | uint64_t timestamp) |
2115 | 159 | { | 167 | { |
2118 | 160 | return wrapped->raise_surface(session, window, timestamp); | 168 | return wrapped->request_drag_and_drop(session, window, timestamp); |
2119 | 161 | } | 169 | } |
2120 | 170 | |||
2121 | 171 | void mtf::ObservantShell::set_drag_and_drop_handle(std::vector<uint8_t> const& handle) | ||
2122 | 172 | { | ||
2123 | 173 | wrapped->set_drag_and_drop_handle(handle); | ||
2124 | 174 | } | ||
2125 | 175 | |||
2126 | 176 | void mtf::ObservantShell::clear_drag_and_drop_handle() | ||
2127 | 177 | { | ||
2128 | 178 | wrapped->clear_drag_and_drop_handle(); | ||
2129 | 179 | } | ||
2130 | 180 | |||
2131 | 162 | 181 | ||
2132 | === modified file 'tests/mir_test_framework/stub_surface.cpp' | |||
2133 | --- tests/mir_test_framework/stub_surface.cpp 2017-02-15 14:45:41 +0000 | |||
2134 | +++ tests/mir_test_framework/stub_surface.cpp 2017-03-14 11:00:58 +0000 | |||
2135 | @@ -198,6 +198,10 @@ | |||
2136 | 198 | { | 198 | { |
2137 | 199 | } | 199 | } |
2138 | 200 | 200 | ||
2139 | 201 | void mtd::StubSurface::start_drag_and_drop(std::vector<uint8_t> const& /*handle*/) | ||
2140 | 202 | { | ||
2141 | 203 | } | ||
2142 | 204 | |||
2143 | 201 | namespace | 205 | namespace |
2144 | 202 | { | 206 | { |
2145 | 203 | // Ensure we don't accidentally have an abstract class | 207 | // Ensure we don't accidentally have an abstract class |
2146 | 204 | 208 | ||
2147 | === modified file 'tests/unit-tests/client/test_client_mir_surface.cpp' | |||
2148 | --- tests/unit-tests/client/test_client_mir_surface.cpp 2017-03-10 19:47:57 +0000 | |||
2149 | +++ tests/unit-tests/client/test_client_mir_surface.cpp 2017-03-14 11:00:58 +0000 | |||
2150 | @@ -215,7 +215,8 @@ | |||
2151 | 215 | { mir_window_attrib_focus, mir_window_focus_state_focused }, | 215 | { mir_window_attrib_focus, mir_window_focus_state_focused }, |
2152 | 216 | { mir_window_attrib_dpi, 19 }, | 216 | { mir_window_attrib_dpi, 19 }, |
2153 | 217 | { mir_window_attrib_visibility, mir_window_visibility_exposed }, | 217 | { mir_window_attrib_visibility, mir_window_visibility_exposed }, |
2155 | 218 | { mir_window_attrib_preferred_orientation, mir_orientation_mode_any } | 218 | { mir_window_attrib_preferred_orientation, mir_orientation_mode_any }, |
2156 | 219 | { mir_window_attrib_drag_and_drop_handle, 0 } | ||
2157 | 219 | }; | 220 | }; |
2158 | 220 | 221 | ||
2159 | 221 | class TestConnectionConfiguration : public mcl::DefaultConnectionConfiguration | 222 | class TestConnectionConfiguration : public mcl::DefaultConnectionConfiguration |
FAILED: Continuous integration, rev:4104 /mir-jenkins. ubuntu. com/job/ mir-ci/ 3127/ /mir-jenkins. ubuntu. com/job/ build-mir/ 4199/console /mir-jenkins. ubuntu. com/job/ build-0- fetch/4286 /mir-jenkins. ubuntu. com/job/ build-1- sourcepkg/ release= vivid+overlay/ 4276 /mir-jenkins. ubuntu. com/job/ build-1- sourcepkg/ release= xenial+ overlay/ 4276 /mir-jenkins. ubuntu. com/job/ build-1- sourcepkg/ release= zesty/4276 /mir-jenkins. ubuntu. com/job/ build-2- binpkg- mir/arch= amd64,compiler= clang,platform= mesa,release= zesty/4226/ console /mir-jenkins. ubuntu. com/job/ build-2- binpkg- mir/arch= amd64,compiler= gcc,platform= mesa,release= xenial+ overlay/ 4226/console /mir-jenkins. ubuntu. com/job/ build-2- binpkg- mir/arch= amd64,compiler= gcc,platform= mesa,release= zesty/4226/ console /mir-jenkins. ubuntu. com/job/ build-2- binpkg- mir/arch= cross-armhf, compiler= gcc,platform= android, release= vivid+overlay/ 4226/console /mir-jenkins. ubuntu. com/job/ build-2- binpkg- mir/arch= i386,compiler= gcc,platform= android, release= vivid+overlay/ 4226/console /mir-jenkins. ubuntu. com/job/ build-2- binpkg- mir/arch= i386,compiler= gcc,platform= mesa,release= xenial+ overlay/ 4226/console
https:/
Executed test runs:
FAILURE: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
Click here to trigger a rebuild: /mir-jenkins. ubuntu. com/job/ mir-ci/ 3127/rebuild
https:/