diff options
author | emersion <contact@emersion.fr> | 2018-10-23 23:38:57 +0200 |
---|---|---|
committer | emersion <contact@emersion.fr> | 2018-10-23 23:38:57 +0200 |
commit | a654ac1bd626e13917568acaebb6ecdb04c77596 (patch) | |
tree | 87d9e727e76d7eea9f74ba609f73cf7aa82b9c2f /sway | |
parent | Merge pull request #2942 from ianyfan/swaybar (diff) | |
download | sway-a654ac1bd626e13917568acaebb6ecdb04c77596.tar.gz sway-a654ac1bd626e13917568acaebb6ecdb04c77596.tar.zst sway-a654ac1bd626e13917568acaebb6ecdb04c77596.zip |
Implement the presentation-time protocol
Diffstat (limited to 'sway')
-rw-r--r-- | sway/desktop/output.c | 185 | ||||
-rw-r--r-- | sway/server.c | 3 | ||||
-rw-r--r-- | sway/tree/output.c | 2 |
3 files changed, 103 insertions, 87 deletions
diff --git a/sway/desktop/output.c b/sway/desktop/output.c index 018a7285..ed9300bb 100644 --- a/sway/desktop/output.c +++ b/sway/desktop/output.c | |||
@@ -11,10 +11,11 @@ | |||
11 | #include <wlr/types/wlr_output_damage.h> | 11 | #include <wlr/types/wlr_output_damage.h> |
12 | #include <wlr/types/wlr_output_layout.h> | 12 | #include <wlr/types/wlr_output_layout.h> |
13 | #include <wlr/types/wlr_output.h> | 13 | #include <wlr/types/wlr_output.h> |
14 | #include <wlr/types/wlr_presentation_time.h> | ||
14 | #include <wlr/types/wlr_surface.h> | 15 | #include <wlr/types/wlr_surface.h> |
15 | #include <wlr/util/region.h> | 16 | #include <wlr/util/region.h> |
16 | #include "log.h" | ||
17 | #include "config.h" | 17 | #include "config.h" |
18 | #include "log.h" | ||
18 | #include "sway/config.h" | 19 | #include "sway/config.h" |
19 | #include "sway/desktop/transaction.h" | 20 | #include "sway/desktop/transaction.h" |
20 | #include "sway/input/input-manager.h" | 21 | #include "sway/input/input-manager.h" |
@@ -223,6 +224,75 @@ void output_drag_icons_for_each_surface(struct sway_output *output, | |||
223 | } | 224 | } |
224 | } | 225 | } |
225 | 226 | ||
227 | static void for_each_surface_container_iterator(struct sway_container *con, | ||
228 | void *_data) { | ||
229 | if (!con->view || !view_is_visible(con->view)) { | ||
230 | return; | ||
231 | } | ||
232 | |||
233 | struct surface_iterator_data *data = _data; | ||
234 | output_view_for_each_surface(data->output, con->view, | ||
235 | data->user_iterator, data->user_data); | ||
236 | } | ||
237 | |||
238 | static void output_for_each_surface(struct sway_output *output, | ||
239 | sway_surface_iterator_func_t iterator, void *user_data) { | ||
240 | if (output_has_opaque_overlay_layer_surface(output)) { | ||
241 | goto overlay; | ||
242 | } | ||
243 | |||
244 | struct surface_iterator_data data = { | ||
245 | .user_iterator = iterator, | ||
246 | .user_data = user_data, | ||
247 | .output = output, | ||
248 | }; | ||
249 | |||
250 | struct sway_workspace *workspace = output_get_active_workspace(output); | ||
251 | if (workspace->current.fullscreen) { | ||
252 | for_each_surface_container_iterator( | ||
253 | workspace->current.fullscreen, &data); | ||
254 | container_for_each_child(workspace->current.fullscreen, | ||
255 | for_each_surface_container_iterator, &data); | ||
256 | for (int i = 0; i < workspace->current.floating->length; ++i) { | ||
257 | struct sway_container *floater = | ||
258 | workspace->current.floating->items[i]; | ||
259 | if (container_is_transient_for(floater, | ||
260 | workspace->current.fullscreen)) { | ||
261 | for_each_surface_container_iterator(floater, &data); | ||
262 | } | ||
263 | } | ||
264 | #ifdef HAVE_XWAYLAND | ||
265 | output_unmanaged_for_each_surface(output, &root->xwayland_unmanaged, | ||
266 | iterator, user_data); | ||
267 | #endif | ||
268 | } else { | ||
269 | output_layer_for_each_surface(output, | ||
270 | &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND], | ||
271 | iterator, user_data); | ||
272 | output_layer_for_each_surface(output, | ||
273 | &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM], | ||
274 | iterator, user_data); | ||
275 | |||
276 | workspace_for_each_container(workspace, | ||
277 | for_each_surface_container_iterator, &data); | ||
278 | |||
279 | #ifdef HAVE_XWAYLAND | ||
280 | output_unmanaged_for_each_surface(output, &root->xwayland_unmanaged, | ||
281 | iterator, user_data); | ||
282 | #endif | ||
283 | output_layer_for_each_surface(output, | ||
284 | &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_TOP], | ||
285 | iterator, user_data); | ||
286 | } | ||
287 | |||
288 | overlay: | ||
289 | output_layer_for_each_surface(output, | ||
290 | &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY], | ||
291 | iterator, user_data); | ||
292 | output_drag_icons_for_each_surface(output, &root->drag_icons, | ||
293 | iterator, user_data); | ||
294 | } | ||
295 | |||
226 | static int scale_length(int length, int offset, float scale) { | 296 | static int scale_length(int length, int offset, float scale) { |
227 | return round((offset + length) * scale) - round(offset * scale); | 297 | return round((offset + length) * scale) - round(offset * scale); |
228 | } | 298 | } |
@@ -274,96 +344,13 @@ bool output_has_opaque_overlay_layer_surface(struct sway_output *output) { | |||
274 | 344 | ||
275 | static void send_frame_done_iterator(struct sway_output *output, | 345 | static void send_frame_done_iterator(struct sway_output *output, |
276 | struct wlr_surface *surface, struct wlr_box *box, float rotation, | 346 | struct wlr_surface *surface, struct wlr_box *box, float rotation, |
277 | void *_data) { | 347 | void *data) { |
278 | struct timespec *when = _data; | 348 | struct timespec *when = data; |
279 | wlr_surface_send_frame_done(surface, when); | 349 | wlr_surface_send_frame_done(surface, when); |
280 | } | 350 | } |
281 | 351 | ||
282 | static void send_frame_done_layer(struct sway_output *output, | ||
283 | struct wl_list *layer_surfaces, struct timespec *when) { | ||
284 | output_layer_for_each_surface(output, layer_surfaces, | ||
285 | send_frame_done_iterator, when); | ||
286 | } | ||
287 | |||
288 | #ifdef HAVE_XWAYLAND | ||
289 | static void send_frame_done_unmanaged(struct sway_output *output, | ||
290 | struct wl_list *unmanaged, struct timespec *when) { | ||
291 | output_unmanaged_for_each_surface(output, unmanaged, | ||
292 | send_frame_done_iterator, when); | ||
293 | } | ||
294 | #endif | ||
295 | |||
296 | static void send_frame_done_drag_icons(struct sway_output *output, | ||
297 | struct wl_list *drag_icons, struct timespec *when) { | ||
298 | output_drag_icons_for_each_surface(output, drag_icons, | ||
299 | send_frame_done_iterator, when); | ||
300 | } | ||
301 | |||
302 | struct send_frame_done_data { | ||
303 | struct sway_output *output; | ||
304 | struct timespec *when; | ||
305 | }; | ||
306 | |||
307 | static void send_frame_done_container_iterator(struct sway_container *con, | ||
308 | void *_data) { | ||
309 | if (!con->view) { | ||
310 | return; | ||
311 | } | ||
312 | if (!view_is_visible(con->view)) { | ||
313 | return; | ||
314 | } | ||
315 | |||
316 | struct send_frame_done_data *data = _data; | ||
317 | output_view_for_each_surface(data->output, con->view, | ||
318 | send_frame_done_iterator, data->when); | ||
319 | } | ||
320 | |||
321 | static void send_frame_done(struct sway_output *output, struct timespec *when) { | 352 | static void send_frame_done(struct sway_output *output, struct timespec *when) { |
322 | if (output_has_opaque_overlay_layer_surface(output)) { | 353 | output_for_each_surface(output, send_frame_done_iterator, when); |
323 | goto send_frame_overlay; | ||
324 | } | ||
325 | |||
326 | struct send_frame_done_data data = { | ||
327 | .output = output, | ||
328 | .when = when, | ||
329 | }; | ||
330 | struct sway_workspace *workspace = output_get_active_workspace(output); | ||
331 | if (workspace->current.fullscreen) { | ||
332 | send_frame_done_container_iterator( | ||
333 | workspace->current.fullscreen, &data); | ||
334 | container_for_each_child(workspace->current.fullscreen, | ||
335 | send_frame_done_container_iterator, &data); | ||
336 | for (int i = 0; i < workspace->current.floating->length; ++i) { | ||
337 | struct sway_container *floater = | ||
338 | workspace->current.floating->items[i]; | ||
339 | if (container_is_transient_for(floater, | ||
340 | workspace->current.fullscreen)) { | ||
341 | send_frame_done_container_iterator(floater, &data); | ||
342 | } | ||
343 | } | ||
344 | #ifdef HAVE_XWAYLAND | ||
345 | send_frame_done_unmanaged(output, &root->xwayland_unmanaged, when); | ||
346 | #endif | ||
347 | } else { | ||
348 | send_frame_done_layer(output, | ||
349 | &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND], when); | ||
350 | send_frame_done_layer(output, | ||
351 | &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM], when); | ||
352 | |||
353 | workspace_for_each_container(workspace, | ||
354 | send_frame_done_container_iterator, &data); | ||
355 | |||
356 | #ifdef HAVE_XWAYLAND | ||
357 | send_frame_done_unmanaged(output, &root->xwayland_unmanaged, when); | ||
358 | #endif | ||
359 | send_frame_done_layer(output, | ||
360 | &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_TOP], when); | ||
361 | } | ||
362 | |||
363 | send_frame_overlay: | ||
364 | send_frame_done_layer(output, | ||
365 | &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY], when); | ||
366 | send_frame_done_drag_icons(output, &root->drag_icons, when); | ||
367 | } | 354 | } |
368 | 355 | ||
369 | static void damage_handle_frame(struct wl_listener *listener, void *data) { | 356 | static void damage_handle_frame(struct wl_listener *listener, void *data) { |
@@ -545,6 +532,29 @@ static void handle_scale(struct wl_listener *listener, void *data) { | |||
545 | transaction_commit_dirty(); | 532 | transaction_commit_dirty(); |
546 | } | 533 | } |
547 | 534 | ||
535 | static void send_presented_iterator(struct sway_output *output, | ||
536 | struct wlr_surface *surface, struct wlr_box *box, float rotation, | ||
537 | void *data) { | ||
538 | struct wlr_presentation_event *event = data; | ||
539 | wlr_presentation_send_surface_presented(server.presentation, | ||
540 | surface, event); | ||
541 | } | ||
542 | |||
543 | static void handle_present(struct wl_listener *listener, void *data) { | ||
544 | struct sway_output *output = wl_container_of(listener, output, present); | ||
545 | struct wlr_output_event_present *output_event = data; | ||
546 | |||
547 | struct wlr_presentation_event event = { | ||
548 | .output = output->wlr_output, | ||
549 | .tv_sec = (uint64_t)output_event->when->tv_sec, | ||
550 | .tv_nsec = (uint32_t)output_event->when->tv_nsec, | ||
551 | .refresh = (uint32_t)output_event->refresh, | ||
552 | .seq = (uint64_t)output_event->seq, | ||
553 | .flags = output_event->flags, | ||
554 | }; | ||
555 | output_for_each_surface(output, send_presented_iterator, &event); | ||
556 | } | ||
557 | |||
548 | void handle_new_output(struct wl_listener *listener, void *data) { | 558 | void handle_new_output(struct wl_listener *listener, void *data) { |
549 | struct sway_server *server = wl_container_of(listener, server, new_output); | 559 | struct sway_server *server = wl_container_of(listener, server, new_output); |
550 | struct wlr_output *wlr_output = data; | 560 | struct wlr_output *wlr_output = data; |
@@ -571,6 +581,7 @@ void output_add_listeners(struct sway_output *output) { | |||
571 | output->mode.notify = handle_mode; | 581 | output->mode.notify = handle_mode; |
572 | output->transform.notify = handle_transform; | 582 | output->transform.notify = handle_transform; |
573 | output->scale.notify = handle_scale; | 583 | output->scale.notify = handle_scale; |
584 | output->present.notify = handle_present; | ||
574 | output->damage_frame.notify = damage_handle_frame; | 585 | output->damage_frame.notify = damage_handle_frame; |
575 | output->damage_destroy.notify = damage_handle_destroy; | 586 | output->damage_destroy.notify = damage_handle_destroy; |
576 | } | 587 | } |
diff --git a/sway/server.c b/sway/server.c index 23d42028..f06173d1 100644 --- a/sway/server.c +++ b/sway/server.c | |||
@@ -135,6 +135,9 @@ bool server_init(struct sway_server *server) { | |||
135 | server->xdg_decoration.notify = handle_xdg_decoration; | 135 | server->xdg_decoration.notify = handle_xdg_decoration; |
136 | wl_list_init(&server->xdg_decorations); | 136 | wl_list_init(&server->xdg_decorations); |
137 | 137 | ||
138 | server->presentation = | ||
139 | wlr_presentation_create(server->wl_display, server->backend); | ||
140 | |||
138 | wlr_export_dmabuf_manager_v1_create(server->wl_display); | 141 | wlr_export_dmabuf_manager_v1_create(server->wl_display); |
139 | wlr_screencopy_manager_v1_create(server->wl_display); | 142 | wlr_screencopy_manager_v1_create(server->wl_display); |
140 | 143 | ||
diff --git a/sway/tree/output.c b/sway/tree/output.c index 04219b5f..e5794b8a 100644 --- a/sway/tree/output.c +++ b/sway/tree/output.c | |||
@@ -103,6 +103,7 @@ void output_enable(struct sway_output *output, struct output_config *oc) { | |||
103 | wl_signal_add(&wlr_output->events.mode, &output->mode); | 103 | wl_signal_add(&wlr_output->events.mode, &output->mode); |
104 | wl_signal_add(&wlr_output->events.transform, &output->transform); | 104 | wl_signal_add(&wlr_output->events.transform, &output->transform); |
105 | wl_signal_add(&wlr_output->events.scale, &output->scale); | 105 | wl_signal_add(&wlr_output->events.scale, &output->scale); |
106 | wl_signal_add(&wlr_output->events.present, &output->present); | ||
106 | wl_signal_add(&output->damage->events.frame, &output->damage_frame); | 107 | wl_signal_add(&output->damage->events.frame, &output->damage_frame); |
107 | wl_signal_add(&output->damage->events.destroy, &output->damage_destroy); | 108 | wl_signal_add(&output->damage->events.destroy, &output->damage_destroy); |
108 | 109 | ||
@@ -214,6 +215,7 @@ void output_disable(struct sway_output *output) { | |||
214 | wl_list_remove(&output->mode.link); | 215 | wl_list_remove(&output->mode.link); |
215 | wl_list_remove(&output->transform.link); | 216 | wl_list_remove(&output->transform.link); |
216 | wl_list_remove(&output->scale.link); | 217 | wl_list_remove(&output->scale.link); |
218 | wl_list_remove(&output->present.link); | ||
217 | wl_list_remove(&output->damage_destroy.link); | 219 | wl_list_remove(&output->damage_destroy.link); |
218 | wl_list_remove(&output->damage_frame.link); | 220 | wl_list_remove(&output->damage_frame.link); |
219 | 221 | ||