Merge lp:~raof/mir/wayland-input-fixes into lp:mir
- wayland-input-fixes
- Merge into development-branch
Proposed by
Chris Halse Rogers
Status: | Superseded | ||||
---|---|---|---|---|---|
Proposed branch: | lp:~raof/mir/wayland-input-fixes | ||||
Merge into: | lp:mir | ||||
Diff against target: |
752 lines (+266/-65) 6 files modified
debian/control (+1/-0) include/client/mir/client/event.h (+54/-0) src/client/CMakeLists.txt (+1/-0) src/protocol/wrapper_generator.cpp (+11/-1) src/server/frontend/wayland/core_generated_interfaces.h (+60/-12) src/server/frontend/wayland/wayland_connector.cpp (+139/-52) |
||||
To merge this branch: | bzr merge lp:~raof/mir/wayland-input-fixes | ||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Mir CI Bot | continuous-integration | Needs Fixing | |
Mir development team | Pending | ||
Review via email: mp+331281@code.launchpad.net |
Commit message
Wayland: Fix lifetimes of wrapper objects.
This prevents client disconnects/
Description of the change
To post a comment you must log in.
Revision history for this message
Mir CI Bot (mir-ci-bot) wrote : | # |
review:
Needs Fixing
(continuous-integration)
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'debian/control' | |||
2 | --- debian/control 2017-09-13 04:15:28 +0000 | |||
3 | +++ debian/control 2017-09-25 18:25:28 +0000 | |||
4 | @@ -47,6 +47,7 @@ | |||
5 | 47 | capnproto, | 47 | capnproto, |
6 | 48 | libepoxy-dev, | 48 | libepoxy-dev, |
7 | 49 | python3-pil:native, | 49 | python3-pil:native, |
8 | 50 | linux-libc-dev, | ||
9 | 50 | Standards-Version: 3.9.4 | 51 | Standards-Version: 3.9.4 |
10 | 51 | Homepage: https://launchpad.net/mir | 52 | Homepage: https://launchpad.net/mir |
11 | 52 | # If you aren't a member of ~mir-team but need to upload packaging changes, | 53 | # If you aren't a member of ~mir-team but need to upload packaging changes, |
12 | 53 | 54 | ||
13 | === added file 'include/client/mir/client/event.h' | |||
14 | --- include/client/mir/client/event.h 1970-01-01 00:00:00 +0000 | |||
15 | +++ include/client/mir/client/event.h 2017-09-25 18:25:28 +0000 | |||
16 | @@ -0,0 +1,54 @@ | |||
17 | 1 | /* | ||
18 | 2 | * Copyright © 2017 Canonical Ltd. | ||
19 | 3 | * | ||
20 | 4 | * This program is free software: you can redistribute it and/or modify | ||
21 | 5 | * it under the terms of the GNU Lesser General Public License version 2 or 3 as | ||
22 | 6 | * published by the Free Software Foundation. | ||
23 | 7 | * | ||
24 | 8 | * This program is distributed in the hope that it will be useful, | ||
25 | 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
26 | 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
27 | 11 | * GNU General Public License for more details. | ||
28 | 12 | * | ||
29 | 13 | * You should have received a copy of the GNU General Public License | ||
30 | 14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
31 | 15 | * | ||
32 | 16 | * Authored by: Christopher James Halse Rogers <christopher.halse.rogers@canonical.com> | ||
33 | 17 | */ | ||
34 | 18 | |||
35 | 19 | #ifndef MIR_CLIENT_EVENT_H_ | ||
36 | 20 | #define MIR_CLIENT_EVENT_H_ | ||
37 | 21 | |||
38 | 22 | #include "mir_toolkit/events/event.h" | ||
39 | 23 | |||
40 | 24 | #include <memory> | ||
41 | 25 | |||
42 | 26 | namespace mir | ||
43 | 27 | { | ||
44 | 28 | namespace client | ||
45 | 29 | { | ||
46 | 30 | /// Handle class for MirEvent - provides automatic reference counting. | ||
47 | 31 | class Event | ||
48 | 32 | { | ||
49 | 33 | public: | ||
50 | 34 | Event() = default; | ||
51 | 35 | explicit Event(MirEvent const* event) : self{mir_event_ref(event), deleter} | ||
52 | 36 | { | ||
53 | 37 | } | ||
54 | 38 | |||
55 | 39 | operator MirEvent const*() const { return self.get(); } | ||
56 | 40 | |||
57 | 41 | void reset() { self.reset(); } | ||
58 | 42 | |||
59 | 43 | private: | ||
60 | 44 | static void deleter(MirEvent const* event) { mir_event_unref(event); } | ||
61 | 45 | std::shared_ptr<MirEvent const> self; | ||
62 | 46 | }; | ||
63 | 47 | |||
64 | 48 | // Provide a deleted overload to avoid double release "accidents". | ||
65 | 49 | void mir_event_unref(Event const& event) = delete; | ||
66 | 50 | } | ||
67 | 51 | } | ||
68 | 52 | |||
69 | 53 | #endif //MIR_CLIENT_EVENT_H_ | ||
70 | 54 | |||
71 | 0 | 55 | ||
72 | === modified file 'src/client/CMakeLists.txt' | |||
73 | --- src/client/CMakeLists.txt 2017-08-29 14:23:50 +0000 | |||
74 | +++ src/client/CMakeLists.txt 2017-09-25 18:25:28 +0000 | |||
75 | @@ -118,6 +118,7 @@ | |||
76 | 118 | ${CMAKE_SOURCE_DIR}/include/client/mir/client/connection.h | 118 | ${CMAKE_SOURCE_DIR}/include/client/mir/client/connection.h |
77 | 119 | ${CMAKE_SOURCE_DIR}/include/client/mir/client/display_config.h | 119 | ${CMAKE_SOURCE_DIR}/include/client/mir/client/display_config.h |
78 | 120 | ${CMAKE_SOURCE_DIR}/include/client/mir/client/window.h | 120 | ${CMAKE_SOURCE_DIR}/include/client/mir/client/window.h |
79 | 121 | ${CMAKE_SOURCE_DIR}/include/client/mir/client/event.h | ||
80 | 121 | ) | 122 | ) |
81 | 122 | 123 | ||
82 | 123 | # Ensure protobuf C++ headers have been produced before | 124 | # Ensure protobuf C++ headers have been produced before |
83 | 124 | 125 | ||
84 | === modified file 'src/protocol/wrapper_generator.cpp' | |||
85 | --- src/protocol/wrapper_generator.cpp 2017-09-07 00:32:52 +0000 | |||
86 | +++ src/protocol/wrapper_generator.cpp 2017-09-25 18:25:28 +0000 | |||
87 | @@ -373,6 +373,16 @@ | |||
88 | 373 | 373 | ||
89 | 374 | if (!methods.empty()) | 374 | if (!methods.empty()) |
90 | 375 | { | 375 | { |
91 | 376 | if (!is_global) | ||
92 | 377 | { | ||
93 | 378 | emit_indented_lines(out, " ", { | ||
94 | 379 | {"static void resource_destroyed_thunk(wl_resource* us)"}, | ||
95 | 380 | {"{"}, | ||
96 | 381 | {" delete static_cast<", generated_name, "*>(wl_resource_get_user_data(us));"}, | ||
97 | 382 | {"}"} | ||
98 | 383 | }); | ||
99 | 384 | } | ||
100 | 385 | |||
101 | 376 | emit_indented_lines(out, " ", { | 386 | emit_indented_lines(out, " ", { |
102 | 377 | { "static struct ", wl_name, "_interface const vtable;" } | 387 | { "static struct ", wl_name, "_interface const vtable;" } |
103 | 378 | }); | 388 | }); |
104 | @@ -427,7 +437,7 @@ | |||
105 | 427 | if (has_vtable) | 437 | if (has_vtable) |
106 | 428 | { | 438 | { |
107 | 429 | emit_indented_lines(out, indent + " ", | 439 | emit_indented_lines(out, indent + " ", |
109 | 430 | {{ "wl_resource_set_implementation(resource, &vtable, this, nullptr);" }}); | 440 | {{ "wl_resource_set_implementation(resource, &vtable, this, &resource_destroyed_thunk);" }}); |
110 | 431 | } | 441 | } |
111 | 432 | emit_indented_lines(out, indent, { | 442 | emit_indented_lines(out, indent, { |
112 | 433 | { "}" } | 443 | { "}" } |
113 | 434 | 444 | ||
114 | === modified file 'src/server/frontend/wayland/core_generated_interfaces.h' | |||
115 | --- src/server/frontend/wayland/core_generated_interfaces.h 2017-09-07 00:33:43 +0000 | |||
116 | +++ src/server/frontend/wayland/core_generated_interfaces.h 2017-09-25 18:25:28 +0000 | |||
117 | @@ -108,7 +108,7 @@ | |||
118 | 108 | wl_resource_post_no_memory(parent); | 108 | wl_resource_post_no_memory(parent); |
119 | 109 | BOOST_THROW_EXCEPTION((std::bad_alloc{})); | 109 | BOOST_THROW_EXCEPTION((std::bad_alloc{})); |
120 | 110 | } | 110 | } |
122 | 111 | wl_resource_set_implementation(resource, &vtable, this, nullptr); | 111 | wl_resource_set_implementation(resource, &vtable, this, &resource_destroyed_thunk); |
123 | 112 | } | 112 | } |
124 | 113 | virtual ~ShmPool() = default; | 113 | virtual ~ShmPool() = default; |
125 | 114 | 114 | ||
126 | @@ -138,6 +138,10 @@ | |||
127 | 138 | me->resize(size); | 138 | me->resize(size); |
128 | 139 | } | 139 | } |
129 | 140 | 140 | ||
130 | 141 | static void resource_destroyed_thunk(wl_resource* us) | ||
131 | 142 | { | ||
132 | 143 | delete static_cast<ShmPool*>(wl_resource_get_user_data(us)); | ||
133 | 144 | } | ||
134 | 141 | static struct wl_shm_pool_interface const vtable; | 145 | static struct wl_shm_pool_interface const vtable; |
135 | 142 | }; | 146 | }; |
136 | 143 | 147 | ||
137 | @@ -207,7 +211,7 @@ | |||
138 | 207 | wl_resource_post_no_memory(parent); | 211 | wl_resource_post_no_memory(parent); |
139 | 208 | BOOST_THROW_EXCEPTION((std::bad_alloc{})); | 212 | BOOST_THROW_EXCEPTION((std::bad_alloc{})); |
140 | 209 | } | 213 | } |
142 | 210 | wl_resource_set_implementation(resource, &vtable, this, nullptr); | 214 | wl_resource_set_implementation(resource, &vtable, this, &resource_destroyed_thunk); |
143 | 211 | } | 215 | } |
144 | 212 | virtual ~Buffer() = default; | 216 | virtual ~Buffer() = default; |
145 | 213 | 217 | ||
146 | @@ -223,6 +227,10 @@ | |||
147 | 223 | me->destroy(); | 227 | me->destroy(); |
148 | 224 | } | 228 | } |
149 | 225 | 229 | ||
150 | 230 | static void resource_destroyed_thunk(wl_resource* us) | ||
151 | 231 | { | ||
152 | 232 | delete static_cast<Buffer*>(wl_resource_get_user_data(us)); | ||
153 | 233 | } | ||
154 | 226 | static struct wl_buffer_interface const vtable; | 234 | static struct wl_buffer_interface const vtable; |
155 | 227 | }; | 235 | }; |
156 | 228 | 236 | ||
157 | @@ -243,7 +251,7 @@ | |||
158 | 243 | wl_resource_post_no_memory(parent); | 251 | wl_resource_post_no_memory(parent); |
159 | 244 | BOOST_THROW_EXCEPTION((std::bad_alloc{})); | 252 | BOOST_THROW_EXCEPTION((std::bad_alloc{})); |
160 | 245 | } | 253 | } |
162 | 246 | wl_resource_set_implementation(resource, &vtable, this, nullptr); | 254 | wl_resource_set_implementation(resource, &vtable, this, &resource_destroyed_thunk); |
163 | 247 | } | 255 | } |
164 | 248 | virtual ~DataOffer() = default; | 256 | virtual ~DataOffer() = default; |
165 | 249 | 257 | ||
166 | @@ -293,6 +301,10 @@ | |||
167 | 293 | me->set_actions(dnd_actions, preferred_action); | 301 | me->set_actions(dnd_actions, preferred_action); |
168 | 294 | } | 302 | } |
169 | 295 | 303 | ||
170 | 304 | static void resource_destroyed_thunk(wl_resource* us) | ||
171 | 305 | { | ||
172 | 306 | delete static_cast<DataOffer*>(wl_resource_get_user_data(us)); | ||
173 | 307 | } | ||
174 | 296 | static struct wl_data_offer_interface const vtable; | 308 | static struct wl_data_offer_interface const vtable; |
175 | 297 | }; | 309 | }; |
176 | 298 | 310 | ||
177 | @@ -317,7 +329,7 @@ | |||
178 | 317 | wl_resource_post_no_memory(parent); | 329 | wl_resource_post_no_memory(parent); |
179 | 318 | BOOST_THROW_EXCEPTION((std::bad_alloc{})); | 330 | BOOST_THROW_EXCEPTION((std::bad_alloc{})); |
180 | 319 | } | 331 | } |
182 | 320 | wl_resource_set_implementation(resource, &vtable, this, nullptr); | 332 | wl_resource_set_implementation(resource, &vtable, this, &resource_destroyed_thunk); |
183 | 321 | } | 333 | } |
184 | 322 | virtual ~DataSource() = default; | 334 | virtual ~DataSource() = default; |
185 | 323 | 335 | ||
186 | @@ -347,6 +359,10 @@ | |||
187 | 347 | me->set_actions(dnd_actions); | 359 | me->set_actions(dnd_actions); |
188 | 348 | } | 360 | } |
189 | 349 | 361 | ||
190 | 362 | static void resource_destroyed_thunk(wl_resource* us) | ||
191 | 363 | { | ||
192 | 364 | delete static_cast<DataSource*>(wl_resource_get_user_data(us)); | ||
193 | 365 | } | ||
194 | 350 | static struct wl_data_source_interface const vtable; | 366 | static struct wl_data_source_interface const vtable; |
195 | 351 | }; | 367 | }; |
196 | 352 | 368 | ||
197 | @@ -369,7 +385,7 @@ | |||
198 | 369 | wl_resource_post_no_memory(parent); | 385 | wl_resource_post_no_memory(parent); |
199 | 370 | BOOST_THROW_EXCEPTION((std::bad_alloc{})); | 386 | BOOST_THROW_EXCEPTION((std::bad_alloc{})); |
200 | 371 | } | 387 | } |
202 | 372 | wl_resource_set_implementation(resource, &vtable, this, nullptr); | 388 | wl_resource_set_implementation(resource, &vtable, this, &resource_destroyed_thunk); |
203 | 373 | } | 389 | } |
204 | 374 | virtual ~DataDevice() = default; | 390 | virtual ~DataDevice() = default; |
205 | 375 | 391 | ||
206 | @@ -414,6 +430,10 @@ | |||
207 | 414 | me->release(); | 430 | me->release(); |
208 | 415 | } | 431 | } |
209 | 416 | 432 | ||
210 | 433 | static void resource_destroyed_thunk(wl_resource* us) | ||
211 | 434 | { | ||
212 | 435 | delete static_cast<DataDevice*>(wl_resource_get_user_data(us)); | ||
213 | 436 | } | ||
214 | 417 | static struct wl_data_device_interface const vtable; | 437 | static struct wl_data_device_interface const vtable; |
215 | 418 | }; | 438 | }; |
216 | 419 | 439 | ||
217 | @@ -536,7 +556,7 @@ | |||
218 | 536 | wl_resource_post_no_memory(parent); | 556 | wl_resource_post_no_memory(parent); |
219 | 537 | BOOST_THROW_EXCEPTION((std::bad_alloc{})); | 557 | BOOST_THROW_EXCEPTION((std::bad_alloc{})); |
220 | 538 | } | 558 | } |
222 | 539 | wl_resource_set_implementation(resource, &vtable, this, nullptr); | 559 | wl_resource_set_implementation(resource, &vtable, this, &resource_destroyed_thunk); |
223 | 540 | } | 560 | } |
224 | 541 | virtual ~ShellSurface() = default; | 561 | virtual ~ShellSurface() = default; |
225 | 542 | 562 | ||
226 | @@ -625,6 +645,10 @@ | |||
227 | 625 | me->set_class(class_); | 645 | me->set_class(class_); |
228 | 626 | } | 646 | } |
229 | 627 | 647 | ||
230 | 648 | static void resource_destroyed_thunk(wl_resource* us) | ||
231 | 649 | { | ||
232 | 650 | delete static_cast<ShellSurface*>(wl_resource_get_user_data(us)); | ||
233 | 651 | } | ||
234 | 628 | static struct wl_shell_surface_interface const vtable; | 652 | static struct wl_shell_surface_interface const vtable; |
235 | 629 | }; | 653 | }; |
236 | 630 | 654 | ||
237 | @@ -654,7 +678,7 @@ | |||
238 | 654 | wl_resource_post_no_memory(parent); | 678 | wl_resource_post_no_memory(parent); |
239 | 655 | BOOST_THROW_EXCEPTION((std::bad_alloc{})); | 679 | BOOST_THROW_EXCEPTION((std::bad_alloc{})); |
240 | 656 | } | 680 | } |
242 | 657 | wl_resource_set_implementation(resource, &vtable, this, nullptr); | 681 | wl_resource_set_implementation(resource, &vtable, this, &resource_destroyed_thunk); |
243 | 658 | } | 682 | } |
244 | 659 | virtual ~Surface() = default; | 683 | virtual ~Surface() = default; |
245 | 660 | 684 | ||
246 | @@ -748,6 +772,10 @@ | |||
247 | 748 | me->damage_buffer(x, y, width, height); | 772 | me->damage_buffer(x, y, width, height); |
248 | 749 | } | 773 | } |
249 | 750 | 774 | ||
250 | 775 | static void resource_destroyed_thunk(wl_resource* us) | ||
251 | 776 | { | ||
252 | 777 | delete static_cast<Surface*>(wl_resource_get_user_data(us)); | ||
253 | 778 | } | ||
254 | 751 | static struct wl_surface_interface const vtable; | 779 | static struct wl_surface_interface const vtable; |
255 | 752 | }; | 780 | }; |
256 | 753 | 781 | ||
257 | @@ -847,7 +875,7 @@ | |||
258 | 847 | wl_resource_post_no_memory(parent); | 875 | wl_resource_post_no_memory(parent); |
259 | 848 | BOOST_THROW_EXCEPTION((std::bad_alloc{})); | 876 | BOOST_THROW_EXCEPTION((std::bad_alloc{})); |
260 | 849 | } | 877 | } |
262 | 850 | wl_resource_set_implementation(resource, &vtable, this, nullptr); | 878 | wl_resource_set_implementation(resource, &vtable, this, &resource_destroyed_thunk); |
263 | 851 | } | 879 | } |
264 | 852 | virtual ~Pointer() = default; | 880 | virtual ~Pointer() = default; |
265 | 853 | 881 | ||
266 | @@ -875,6 +903,10 @@ | |||
267 | 875 | me->release(); | 903 | me->release(); |
268 | 876 | } | 904 | } |
269 | 877 | 905 | ||
270 | 906 | static void resource_destroyed_thunk(wl_resource* us) | ||
271 | 907 | { | ||
272 | 908 | delete static_cast<Pointer*>(wl_resource_get_user_data(us)); | ||
273 | 909 | } | ||
274 | 878 | static struct wl_pointer_interface const vtable; | 910 | static struct wl_pointer_interface const vtable; |
275 | 879 | }; | 911 | }; |
276 | 880 | 912 | ||
277 | @@ -896,7 +928,7 @@ | |||
278 | 896 | wl_resource_post_no_memory(parent); | 928 | wl_resource_post_no_memory(parent); |
279 | 897 | BOOST_THROW_EXCEPTION((std::bad_alloc{})); | 929 | BOOST_THROW_EXCEPTION((std::bad_alloc{})); |
280 | 898 | } | 930 | } |
282 | 899 | wl_resource_set_implementation(resource, &vtable, this, nullptr); | 931 | wl_resource_set_implementation(resource, &vtable, this, &resource_destroyed_thunk); |
283 | 900 | } | 932 | } |
284 | 901 | virtual ~Keyboard() = default; | 933 | virtual ~Keyboard() = default; |
285 | 902 | 934 | ||
286 | @@ -912,6 +944,10 @@ | |||
287 | 912 | me->release(); | 944 | me->release(); |
288 | 913 | } | 945 | } |
289 | 914 | 946 | ||
290 | 947 | static void resource_destroyed_thunk(wl_resource* us) | ||
291 | 948 | { | ||
292 | 949 | delete static_cast<Keyboard*>(wl_resource_get_user_data(us)); | ||
293 | 950 | } | ||
294 | 915 | static struct wl_keyboard_interface const vtable; | 951 | static struct wl_keyboard_interface const vtable; |
295 | 916 | }; | 952 | }; |
296 | 917 | 953 | ||
297 | @@ -932,7 +968,7 @@ | |||
298 | 932 | wl_resource_post_no_memory(parent); | 968 | wl_resource_post_no_memory(parent); |
299 | 933 | BOOST_THROW_EXCEPTION((std::bad_alloc{})); | 969 | BOOST_THROW_EXCEPTION((std::bad_alloc{})); |
300 | 934 | } | 970 | } |
302 | 935 | wl_resource_set_implementation(resource, &vtable, this, nullptr); | 971 | wl_resource_set_implementation(resource, &vtable, this, &resource_destroyed_thunk); |
303 | 936 | } | 972 | } |
304 | 937 | virtual ~Touch() = default; | 973 | virtual ~Touch() = default; |
305 | 938 | 974 | ||
306 | @@ -948,6 +984,10 @@ | |||
307 | 948 | me->release(); | 984 | me->release(); |
308 | 949 | } | 985 | } |
309 | 950 | 986 | ||
310 | 987 | static void resource_destroyed_thunk(wl_resource* us) | ||
311 | 988 | { | ||
312 | 989 | delete static_cast<Touch*>(wl_resource_get_user_data(us)); | ||
313 | 990 | } | ||
314 | 951 | static struct wl_touch_interface const vtable; | 991 | static struct wl_touch_interface const vtable; |
315 | 952 | }; | 992 | }; |
316 | 953 | 993 | ||
317 | @@ -1014,7 +1054,7 @@ | |||
318 | 1014 | wl_resource_post_no_memory(parent); | 1054 | wl_resource_post_no_memory(parent); |
319 | 1015 | BOOST_THROW_EXCEPTION((std::bad_alloc{})); | 1055 | BOOST_THROW_EXCEPTION((std::bad_alloc{})); |
320 | 1016 | } | 1056 | } |
322 | 1017 | wl_resource_set_implementation(resource, &vtable, this, nullptr); | 1057 | wl_resource_set_implementation(resource, &vtable, this, &resource_destroyed_thunk); |
323 | 1018 | } | 1058 | } |
324 | 1019 | virtual ~Region() = default; | 1059 | virtual ~Region() = default; |
325 | 1020 | 1060 | ||
326 | @@ -1044,6 +1084,10 @@ | |||
327 | 1044 | me->subtract(x, y, width, height); | 1084 | me->subtract(x, y, width, height); |
328 | 1045 | } | 1085 | } |
329 | 1046 | 1086 | ||
330 | 1087 | static void resource_destroyed_thunk(wl_resource* us) | ||
331 | 1088 | { | ||
332 | 1089 | delete static_cast<Region*>(wl_resource_get_user_data(us)); | ||
333 | 1090 | } | ||
334 | 1047 | static struct wl_region_interface const vtable; | 1091 | static struct wl_region_interface const vtable; |
335 | 1048 | }; | 1092 | }; |
336 | 1049 | 1093 | ||
337 | @@ -1120,7 +1164,7 @@ | |||
338 | 1120 | wl_resource_post_no_memory(parent); | 1164 | wl_resource_post_no_memory(parent); |
339 | 1121 | BOOST_THROW_EXCEPTION((std::bad_alloc{})); | 1165 | BOOST_THROW_EXCEPTION((std::bad_alloc{})); |
340 | 1122 | } | 1166 | } |
342 | 1123 | wl_resource_set_implementation(resource, &vtable, this, nullptr); | 1167 | wl_resource_set_implementation(resource, &vtable, this, &resource_destroyed_thunk); |
343 | 1124 | } | 1168 | } |
344 | 1125 | virtual ~Subsurface() = default; | 1169 | virtual ~Subsurface() = default; |
345 | 1126 | 1170 | ||
346 | @@ -1171,6 +1215,10 @@ | |||
347 | 1171 | me->set_desync(); | 1215 | me->set_desync(); |
348 | 1172 | } | 1216 | } |
349 | 1173 | 1217 | ||
350 | 1218 | static void resource_destroyed_thunk(wl_resource* us) | ||
351 | 1219 | { | ||
352 | 1220 | delete static_cast<Subsurface*>(wl_resource_get_user_data(us)); | ||
353 | 1221 | } | ||
354 | 1174 | static struct wl_subsurface_interface const vtable; | 1222 | static struct wl_subsurface_interface const vtable; |
355 | 1175 | }; | 1223 | }; |
356 | 1176 | 1224 | ||
357 | 1177 | 1225 | ||
358 | === modified file 'src/server/frontend/wayland/wayland_connector.cpp' | |||
359 | --- src/server/frontend/wayland/wayland_connector.cpp 2017-09-22 15:49:10 +0000 | |||
360 | +++ src/server/frontend/wayland/wayland_connector.cpp 2017-09-25 18:25:28 +0000 | |||
361 | @@ -41,6 +41,8 @@ | |||
362 | 41 | 41 | ||
363 | 42 | #include "mir/executor.h" | 42 | #include "mir/executor.h" |
364 | 43 | 43 | ||
365 | 44 | #include "mir/client/event.h" | ||
366 | 45 | |||
367 | 44 | #include <system_error> | 46 | #include <system_error> |
368 | 45 | #include <sys/eventfd.h> | 47 | #include <sys/eventfd.h> |
369 | 46 | #include <wayland-server-core.h> | 48 | #include <wayland-server-core.h> |
370 | @@ -51,6 +53,7 @@ | |||
371 | 51 | #include <functional> | 53 | #include <functional> |
372 | 52 | #include <type_traits> | 54 | #include <type_traits> |
373 | 53 | 55 | ||
374 | 56 | #include <linux/input.h> | ||
375 | 54 | #include <algorithm> | 57 | #include <algorithm> |
376 | 55 | #include <iostream> | 58 | #include <iostream> |
377 | 56 | #include <mir/log.h> | 59 | #include <mir/log.h> |
378 | @@ -69,6 +72,7 @@ | |||
379 | 69 | namespace mc = mir::compositor; | 72 | namespace mc = mir::compositor; |
380 | 70 | namespace ms = mir::scene; | 73 | namespace ms = mir::scene; |
381 | 71 | namespace geom = mir::geometry; | 74 | namespace geom = mir::geometry; |
382 | 75 | namespace mcl = mir::client; | ||
383 | 72 | 76 | ||
384 | 73 | namespace mir | 77 | namespace mir |
385 | 74 | { | 78 | { |
386 | @@ -559,7 +563,7 @@ | |||
387 | 559 | 563 | ||
388 | 560 | void WlSurface::destroy() | 564 | void WlSurface::destroy() |
389 | 561 | { | 565 | { |
391 | 562 | delete this; | 566 | wl_resource_destroy(resource); |
392 | 563 | } | 567 | } |
393 | 564 | 568 | ||
394 | 565 | void WlSurface::attach(std::experimental::optional<wl_resource*> const& buffer, int32_t x, int32_t y) | 569 | void WlSurface::attach(std::experimental::optional<wl_resource*> const& buffer, int32_t x, int32_t y) |
395 | @@ -741,6 +745,19 @@ | |||
396 | 741 | class WlPointer; | 745 | class WlPointer; |
397 | 742 | class WlTouch; | 746 | class WlTouch; |
398 | 743 | 747 | ||
399 | 748 | template<typename Callable> | ||
400 | 749 | auto run_unless(std::shared_ptr<bool> const& condition, Callable&& callable) | ||
401 | 750 | { | ||
402 | 751 | return | ||
403 | 752 | [callable = std::move(callable), condition]() | ||
404 | 753 | { | ||
405 | 754 | if (*condition) | ||
406 | 755 | return; | ||
407 | 756 | |||
408 | 757 | callable(); | ||
409 | 758 | }; | ||
410 | 759 | } | ||
411 | 760 | |||
412 | 744 | class WlKeyboard : public wayland::Keyboard | 761 | class WlKeyboard : public wayland::Keyboard |
413 | 745 | { | 762 | { |
414 | 746 | public: | 763 | public: |
415 | @@ -748,16 +765,29 @@ | |||
416 | 748 | wl_client* client, | 765 | wl_client* client, |
417 | 749 | wl_resource* parent, | 766 | wl_resource* parent, |
418 | 750 | uint32_t id, | 767 | uint32_t id, |
419 | 768 | std::function<void(WlKeyboard*)> const& on_destroy, | ||
420 | 751 | std::shared_ptr<mir::Executor> const& executor) | 769 | std::shared_ptr<mir::Executor> const& executor) |
421 | 752 | : Keyboard(client, parent, id), | 770 | : Keyboard(client, parent, id), |
424 | 753 | executor{executor} | 771 | executor{executor}, |
425 | 754 | { | 772 | on_destroy{on_destroy}, |
426 | 773 | destroyed{std::make_shared<bool>(false)} | ||
427 | 774 | { | ||
428 | 775 | } | ||
429 | 776 | |||
430 | 777 | ~WlKeyboard() | ||
431 | 778 | { | ||
432 | 779 | on_destroy(this); | ||
433 | 780 | *destroyed = true; | ||
434 | 755 | } | 781 | } |
435 | 756 | 782 | ||
436 | 757 | void handle_event(MirInputEvent const* event, wl_resource* /*target*/) | 783 | void handle_event(MirInputEvent const* event, wl_resource* /*target*/) |
437 | 758 | { | 784 | { |
440 | 759 | executor->spawn( | 785 | executor->spawn(run_unless( |
441 | 760 | [ev = mir_event_ref(mir_input_event_get_event(event)), this] () | 786 | destroyed, |
442 | 787 | [ | ||
443 | 788 | ev = mcl::Event{mir_event_ref(mir_input_event_get_event(event))}, | ||
444 | 789 | this | ||
445 | 790 | ] () | ||
446 | 761 | { | 791 | { |
447 | 762 | int const serial = wl_display_next_serial(wl_client_get_display(client)); | 792 | int const serial = wl_display_next_serial(wl_client_get_display(client)); |
448 | 763 | auto event = mir_event_get_input_event(ev); | 793 | auto event = mir_event_get_input_event(ev); |
449 | @@ -782,18 +812,22 @@ | |||
450 | 782 | default: | 812 | default: |
451 | 783 | break; | 813 | break; |
452 | 784 | } | 814 | } |
455 | 785 | mir_event_unref(ev); | 815 | })); |
454 | 786 | }); | ||
456 | 787 | } | 816 | } |
457 | 788 | 817 | ||
458 | 789 | void handle_event(MirWindowEvent const* event, wl_resource* target) | 818 | void handle_event(MirWindowEvent const* event, wl_resource* target) |
459 | 790 | { | 819 | { |
460 | 791 | if (mir_window_event_get_attribute(event) == mir_window_attrib_focus) | 820 | if (mir_window_event_get_attribute(event) == mir_window_attrib_focus) |
461 | 792 | { | 821 | { |
465 | 793 | executor->spawn( | 822 | executor->spawn(run_unless( |
466 | 794 | [resource = resource, serial = wl_display_next_serial(wl_client_get_display(client)), | 823 | destroyed, |
467 | 795 | target = target, focussed = mir_window_event_get_attribute_value(event)]() | 824 | [ |
468 | 825 | target = target, | ||
469 | 826 | focussed = mir_window_event_get_attribute_value(event), | ||
470 | 827 | this | ||
471 | 828 | ]() | ||
472 | 796 | { | 829 | { |
473 | 830 | auto const serial = wl_display_next_serial(wl_client_get_display(client)); | ||
474 | 797 | if (focussed) | 831 | if (focussed) |
475 | 798 | { | 832 | { |
476 | 799 | wl_array key_state; | 833 | wl_array key_state; |
477 | @@ -805,18 +839,21 @@ | |||
478 | 805 | { | 839 | { |
479 | 806 | wl_keyboard_send_leave(resource, serial, target); | 840 | wl_keyboard_send_leave(resource, serial, target); |
480 | 807 | } | 841 | } |
482 | 808 | }); | 842 | })); |
483 | 809 | } | 843 | } |
484 | 810 | } | 844 | } |
485 | 811 | 845 | ||
486 | 812 | private: | 846 | private: |
487 | 813 | std::shared_ptr<mir::Executor> const executor; | 847 | std::shared_ptr<mir::Executor> const executor; |
488 | 848 | std::function<void(WlKeyboard*)> on_destroy; | ||
489 | 849 | std::shared_ptr<bool> const destroyed; | ||
490 | 814 | 850 | ||
491 | 815 | void release() override; | 851 | void release() override; |
492 | 816 | }; | 852 | }; |
493 | 817 | 853 | ||
494 | 818 | void WlKeyboard::release() | 854 | void WlKeyboard::release() |
495 | 819 | { | 855 | { |
496 | 856 | wl_resource_destroy(resource); | ||
497 | 820 | } | 857 | } |
498 | 821 | 858 | ||
499 | 822 | class WlPointer : public wayland::Pointer | 859 | class WlPointer : public wayland::Pointer |
500 | @@ -827,17 +864,27 @@ | |||
501 | 827 | wl_client* client, | 864 | wl_client* client, |
502 | 828 | wl_resource* parent, | 865 | wl_resource* parent, |
503 | 829 | uint32_t id, | 866 | uint32_t id, |
504 | 867 | std::function<void(WlPointer*)> const& on_destroy, | ||
505 | 830 | std::shared_ptr<mir::Executor> const& executor) | 868 | std::shared_ptr<mir::Executor> const& executor) |
506 | 831 | : Pointer(client, parent, id), | 869 | : Pointer(client, parent, id), |
507 | 832 | display{wl_client_get_display(client)}, | 870 | display{wl_client_get_display(client)}, |
510 | 833 | executor{executor} | 871 | executor{executor}, |
511 | 834 | { | 872 | on_destroy{on_destroy}, |
512 | 873 | destroyed{std::make_shared<bool>(false)} | ||
513 | 874 | { | ||
514 | 875 | } | ||
515 | 876 | |||
516 | 877 | ~WlPointer() | ||
517 | 878 | { | ||
518 | 879 | on_destroy(this); | ||
519 | 880 | *destroyed = true; | ||
520 | 835 | } | 881 | } |
521 | 836 | 882 | ||
522 | 837 | void handle_event(MirInputEvent const* event, wl_resource* target) | 883 | void handle_event(MirInputEvent const* event, wl_resource* target) |
523 | 838 | { | 884 | { |
526 | 839 | executor->spawn( | 885 | executor->spawn(run_unless( |
527 | 840 | [ev = mir_event_ref(mir_input_event_get_event(event)), target, this]() | 886 | destroyed, |
528 | 887 | [ev = mcl::Event{mir_input_event_get_event(event)}, target, this]() | ||
529 | 841 | { | 888 | { |
530 | 842 | auto const serial = wl_display_next_serial(display); | 889 | auto const serial = wl_display_next_serial(display); |
531 | 843 | auto const event = mir_event_get_input_event(ev); | 890 | auto const event = mir_event_get_input_event(ev); |
532 | @@ -851,25 +898,27 @@ | |||
533 | 851 | auto const current_set = mir_pointer_event_buttons(pointer_event); | 898 | auto const current_set = mir_pointer_event_buttons(pointer_event); |
534 | 852 | auto const current_time = mir_input_event_get_event_time(event) / 1000; | 899 | auto const current_time = mir_input_event_get_event_time(event) / 1000; |
535 | 853 | 900 | ||
544 | 854 | auto button = 272; // No, I have *no* idea why GTK expects 272 to be the primary button. | 901 | std::unordered_map<MirPointerButton, int> const button_mappings = { |
545 | 855 | // NB button is incremented in the loop and the order mir_pointer_button_XXX matters | 902 | {mir_pointer_button_primary, BTN_LEFT}, |
546 | 856 | for (auto mir_button : | 903 | {mir_pointer_button_secondary, BTN_RIGHT}, |
547 | 857 | {mir_pointer_button_primary, // 272 | 904 | {mir_pointer_button_tertiary, BTN_MIDDLE}, |
548 | 858 | mir_pointer_button_tertiary, // 273 | 905 | {mir_pointer_button_back, BTN_BACK}, |
549 | 859 | mir_pointer_button_secondary, // 274 | 906 | {mir_pointer_button_forward, BTN_FORWARD}, |
550 | 860 | mir_pointer_button_back, // 275 | 907 | {mir_pointer_button_side, BTN_SIDE}, |
551 | 861 | mir_pointer_button_forward}) // 276 | 908 | {mir_pointer_button_task, BTN_TASK}, |
552 | 909 | {mir_pointer_button_extra, BTN_EXTRA} | ||
553 | 910 | }; | ||
554 | 911 | |||
555 | 912 | for (auto mapping : button_mappings) | ||
556 | 862 | { | 913 | { |
558 | 863 | if (mir_button & (current_set ^ last_set)) | 914 | if (mapping.first & (current_set ^ last_set)) |
559 | 864 | { | 915 | { |
561 | 865 | auto const action = (mir_button & current_set) ? | 916 | auto const action = (mapping.first & current_set) ? |
562 | 866 | WL_POINTER_BUTTON_STATE_PRESSED : | 917 | WL_POINTER_BUTTON_STATE_PRESSED : |
563 | 867 | WL_POINTER_BUTTON_STATE_RELEASED; | 918 | WL_POINTER_BUTTON_STATE_RELEASED; |
564 | 868 | 919 | ||
566 | 869 | wl_pointer_send_button(resource, serial, current_time, button, action); | 920 | wl_pointer_send_button(resource, serial, current_time, mapping.second, action); |
567 | 870 | } | 921 | } |
568 | 871 | |||
569 | 872 | ++button; | ||
570 | 873 | } | 922 | } |
571 | 874 | 923 | ||
572 | 875 | last_set = current_set; | 924 | last_set = current_set; |
573 | @@ -934,7 +983,7 @@ | |||
574 | 934 | case mir_pointer_actions: | 983 | case mir_pointer_actions: |
575 | 935 | break; | 984 | break; |
576 | 936 | } | 985 | } |
578 | 937 | }); | 986 | })); |
579 | 938 | } | 987 | } |
580 | 939 | 988 | ||
581 | 940 | // Pointer interface | 989 | // Pointer interface |
582 | @@ -942,6 +991,9 @@ | |||
583 | 942 | wl_display* const display; | 991 | wl_display* const display; |
584 | 943 | std::shared_ptr<mir::Executor> const executor; | 992 | std::shared_ptr<mir::Executor> const executor; |
585 | 944 | 993 | ||
586 | 994 | std::function<void(WlPointer*)> on_destroy; | ||
587 | 995 | std::shared_ptr<bool> const destroyed; | ||
588 | 996 | |||
589 | 945 | MirPointerButtons last_set{0}; | 997 | MirPointerButtons last_set{0}; |
590 | 946 | float last_x, last_y, last_vscroll, last_hscroll; | 998 | float last_x, last_y, last_vscroll, last_hscroll; |
591 | 947 | 999 | ||
592 | @@ -959,7 +1011,7 @@ | |||
593 | 959 | 1011 | ||
594 | 960 | void WlPointer::release() | 1012 | void WlPointer::release() |
595 | 961 | { | 1013 | { |
597 | 962 | delete this; | 1014 | wl_resource_destroy(resource); |
598 | 963 | } | 1015 | } |
599 | 964 | 1016 | ||
600 | 965 | class WlTouch : public wayland::Touch | 1017 | class WlTouch : public wayland::Touch |
601 | @@ -969,9 +1021,18 @@ | |||
602 | 969 | wl_client* client, | 1021 | wl_client* client, |
603 | 970 | wl_resource* parent, | 1022 | wl_resource* parent, |
604 | 971 | uint32_t id, | 1023 | uint32_t id, |
608 | 972 | std::shared_ptr<mir::Executor> const& /*executor*/) | 1024 | std::function<void(WlTouch*)> const& on_destroy, |
609 | 973 | : Touch(client, parent, id) | 1025 | std::shared_ptr<mir::Executor> const& executor) |
610 | 974 | { | 1026 | : Touch(client, parent, id), |
611 | 1027 | executor{executor}, | ||
612 | 1028 | on_destroy{on_destroy} | ||
613 | 1029 | { | ||
614 | 1030 | } | ||
615 | 1031 | |||
616 | 1032 | ~WlTouch() | ||
617 | 1033 | { | ||
618 | 1034 | on_destroy(this); | ||
619 | 1035 | *destroyed = true; | ||
620 | 975 | } | 1036 | } |
621 | 976 | 1037 | ||
622 | 977 | void handle_event(MirInputEvent const* /*event*/, wl_resource* /*target*/) | 1038 | void handle_event(MirInputEvent const* /*event*/, wl_resource* /*target*/) |
623 | @@ -980,11 +1041,16 @@ | |||
624 | 980 | 1041 | ||
625 | 981 | // Touch interface | 1042 | // Touch interface |
626 | 982 | private: | 1043 | private: |
627 | 1044 | std::shared_ptr<mir::Executor> const executor; | ||
628 | 1045 | std::function<void(WlTouch*)> on_destroy; | ||
629 | 1046 | std::shared_ptr<bool> const destroyed; | ||
630 | 1047 | |||
631 | 983 | void release() override; | 1048 | void release() override; |
632 | 984 | }; | 1049 | }; |
633 | 985 | 1050 | ||
634 | 986 | void WlTouch::release() | 1051 | void WlTouch::release() |
635 | 987 | { | 1052 | { |
636 | 1053 | wl_resource_destroy(resource); | ||
637 | 988 | } | 1054 | } |
638 | 989 | 1055 | ||
639 | 990 | template<class InputInterface> | 1056 | template<class InputInterface> |
640 | @@ -997,25 +1063,27 @@ | |||
641 | 997 | InputCtx(InputCtx const&) = delete; | 1063 | InputCtx(InputCtx const&) = delete; |
642 | 998 | InputCtx& operator=(InputCtx const&) = delete; | 1064 | InputCtx& operator=(InputCtx const&) = delete; |
643 | 999 | 1065 | ||
645 | 1000 | void register_listener(std::shared_ptr<InputInterface> const& listener) | 1066 | void register_listener(InputInterface* listener) |
646 | 1001 | { | 1067 | { |
647 | 1068 | std::lock_guard<std::mutex> lock{mutex}; | ||
648 | 1002 | listeners.push_back(listener); | 1069 | listeners.push_back(listener); |
649 | 1003 | } | 1070 | } |
650 | 1004 | 1071 | ||
651 | 1005 | void unregister_listener(InputInterface const* listener) | 1072 | void unregister_listener(InputInterface const* listener) |
652 | 1006 | { | 1073 | { |
660 | 1007 | std::remove_if( | 1074 | std::lock_guard<std::mutex> lock{mutex}; |
661 | 1008 | listeners.begin(), | 1075 | listeners.erase( |
662 | 1009 | listeners.end(), | 1076 | std::remove( |
663 | 1010 | [listener](auto candidate) | 1077 | listeners.begin(), |
664 | 1011 | { | 1078 | listeners.end(), |
665 | 1012 | return candidate.get() == listener; | 1079 | listener), |
666 | 1013 | }); | 1080 | listeners.end()); |
667 | 1014 | } | 1081 | } |
668 | 1015 | 1082 | ||
669 | 1016 | void handle_event(MirInputEvent const* event, wl_resource* target) const | 1083 | void handle_event(MirInputEvent const* event, wl_resource* target) const |
670 | 1017 | { | 1084 | { |
672 | 1018 | for (auto& listener : listeners) | 1085 | std::lock_guard<std::mutex> lock{mutex}; |
673 | 1086 | for (auto listener : listeners) | ||
674 | 1019 | { | 1087 | { |
675 | 1020 | listener->handle_event(event, target); | 1088 | listener->handle_event(event, target); |
676 | 1021 | } | 1089 | } |
677 | @@ -1023,6 +1091,7 @@ | |||
678 | 1023 | 1091 | ||
679 | 1024 | void handle_event(MirWindowEvent const* event, wl_resource* target) const | 1092 | void handle_event(MirWindowEvent const* event, wl_resource* target) const |
680 | 1025 | { | 1093 | { |
681 | 1094 | std::lock_guard<std::mutex> lock{mutex}; | ||
682 | 1026 | for (auto& listener : listeners) | 1095 | for (auto& listener : listeners) |
683 | 1027 | { | 1096 | { |
684 | 1028 | listener->handle_event(event, target); | 1097 | listener->handle_event(event, target); |
685 | @@ -1030,7 +1099,8 @@ | |||
686 | 1030 | } | 1099 | } |
687 | 1031 | 1100 | ||
688 | 1032 | private: | 1101 | private: |
690 | 1033 | std::vector<std::shared_ptr<InputInterface>> listeners; | 1102 | std::mutex mutable mutex; |
691 | 1103 | std::vector<InputInterface*> listeners; | ||
692 | 1034 | }; | 1104 | }; |
693 | 1035 | 1105 | ||
694 | 1036 | class WlSeat | 1106 | class WlSeat |
695 | @@ -1100,32 +1170,49 @@ | |||
696 | 1100 | static void get_pointer(wl_client* client, wl_resource* resource, uint32_t id) | 1170 | static void get_pointer(wl_client* client, wl_resource* resource, uint32_t id) |
697 | 1101 | { | 1171 | { |
698 | 1102 | auto me = reinterpret_cast<WlSeat*>(wl_resource_get_user_data(resource)); | 1172 | auto me = reinterpret_cast<WlSeat*>(wl_resource_get_user_data(resource)); |
701 | 1103 | me->pointer[client].register_listener( | 1173 | auto& input_ctx = me->pointer[client]; |
702 | 1104 | std::make_shared<WlPointer>( | 1174 | input_ctx.register_listener( |
703 | 1175 | new WlPointer{ | ||
704 | 1105 | client, | 1176 | client, |
705 | 1106 | resource, | 1177 | resource, |
706 | 1107 | id, | 1178 | id, |
708 | 1108 | me->executor)); | 1179 | [&input_ctx](WlPointer* listener) |
709 | 1180 | { | ||
710 | 1181 | input_ctx.unregister_listener(listener); | ||
711 | 1182 | }, | ||
712 | 1183 | me->executor}); | ||
713 | 1109 | } | 1184 | } |
714 | 1110 | static void get_keyboard(wl_client* client, wl_resource* resource, uint32_t id) | 1185 | static void get_keyboard(wl_client* client, wl_resource* resource, uint32_t id) |
715 | 1111 | { | 1186 | { |
716 | 1112 | auto me = reinterpret_cast<WlSeat*>(wl_resource_get_user_data(resource)); | 1187 | auto me = reinterpret_cast<WlSeat*>(wl_resource_get_user_data(resource)); |
719 | 1113 | me->keyboard[client].register_listener( | 1188 | auto& input_ctx = me->keyboard[client]; |
720 | 1114 | std::make_shared<WlKeyboard>( | 1189 | |
721 | 1190 | input_ctx.register_listener( | ||
722 | 1191 | new WlKeyboard{ | ||
723 | 1115 | client, | 1192 | client, |
724 | 1116 | resource, | 1193 | resource, |
725 | 1117 | id, | 1194 | id, |
727 | 1118 | me->executor)); | 1195 | [&input_ctx](WlKeyboard* listener) |
728 | 1196 | { | ||
729 | 1197 | input_ctx.unregister_listener(listener); | ||
730 | 1198 | }, | ||
731 | 1199 | me->executor}); | ||
732 | 1119 | } | 1200 | } |
733 | 1120 | static void get_touch(wl_client* client, wl_resource* resource, uint32_t id) | 1201 | static void get_touch(wl_client* client, wl_resource* resource, uint32_t id) |
734 | 1121 | { | 1202 | { |
735 | 1122 | auto me = reinterpret_cast<WlSeat*>(wl_resource_get_user_data(resource)); | 1203 | auto me = reinterpret_cast<WlSeat*>(wl_resource_get_user_data(resource)); |
738 | 1123 | me->touch[client].register_listener( | 1204 | auto& input_ctx = me->touch[client]; |
739 | 1124 | std::make_shared<WlTouch>( | 1205 | |
740 | 1206 | input_ctx.register_listener( | ||
741 | 1207 | new WlTouch{ | ||
742 | 1125 | client, | 1208 | client, |
743 | 1126 | resource, | 1209 | resource, |
744 | 1127 | id, | 1210 | id, |
746 | 1128 | me->executor)); | 1211 | [&input_ctx](WlTouch* listener) |
747 | 1212 | { | ||
748 | 1213 | input_ctx.unregister_listener(listener); | ||
749 | 1214 | }, | ||
750 | 1215 | me->executor}); | ||
751 | 1129 | } | 1216 | } |
752 | 1130 | static void release(struct wl_client* /*client*/, struct wl_resource* /*resource*/) {} | 1217 | static void release(struct wl_client* /*client*/, struct wl_resource* /*resource*/) {} |
753 | 1131 | 1218 |
FAILED: Continuous integration, rev:4276 /mir-jenkins. ubuntu. com/job/ mir-ci/ 3685/ /mir-jenkins. ubuntu. com/job/ build-mir/ 5052/console /mir-jenkins. ubuntu. com/job/ build-0- fetch/5288 /mir-jenkins. ubuntu. com/job/ build-1- sourcepkg/ release= artful/ 5276 /mir-jenkins. ubuntu. com/job/ build-1- sourcepkg/ release= xenial/ 5276 /mir-jenkins. ubuntu. com/job/ build-1- sourcepkg/ release= zesty/5276 /mir-jenkins. ubuntu. com/job/ build-2- binpkg- mir/arch= amd64,compiler= clang,platform= mesa,release= artful/ 5096/console /mir-jenkins. ubuntu. com/job/ build-2- binpkg- mir/arch= amd64,compiler= clang,platform= mesa,release= zesty/5096/ console /mir-jenkins. ubuntu. com/job/ build-2- binpkg- mir/arch= cross-armhf, compiler= gcc,platform= mesa,release= artful/ 5096/console /mir-jenkins. ubuntu. com/job/ build-2- binpkg- mir/arch= i386,compiler= gcc,platform= mesa,release= xenial/ 5096/console
https:/
Executed test runs:
FAILURE: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
ABORTED: https:/
ABORTED: https:/
ABORTED: https:/
FAILURE: https:/
Click here to trigger a rebuild: /mir-jenkins. ubuntu. com/job/ mir-ci/ 3685/rebuild
https:/