aboutsummaryrefslogtreecommitdiff
path: root/sway/tree/view.c
diff options
context:
space:
mode:
Diffstat (limited to 'sway/tree/view.c')
-rw-r--r--sway/tree/view.c88
1 files changed, 57 insertions, 31 deletions
diff --git a/sway/tree/view.c b/sway/tree/view.c
index ee25faf1..402fa179 100644
--- a/sway/tree/view.c
+++ b/sway/tree/view.c
@@ -56,7 +56,6 @@ bool view_init(struct sway_view *view, enum sway_view_type type,
view->type = type;
view->impl = impl;
view->executed_criteria = create_list();
- wl_list_init(&view->saved_buffers);
view->allow_request_urgent = true;
view->shortcuts_inhibit = SHORTCUTS_INHIBIT_DEFAULT;
wl_signal_init(&view->events.unmap);
@@ -77,9 +76,6 @@ void view_destroy(struct sway_view *view) {
return;
}
wl_list_remove(&view->events.unmap.listener_list);
- if (!wl_list_empty(&view->saved_buffers)) {
- view_remove_saved_buffer(view);
- }
list_free(view->executed_criteria);
view_assign_ctx(view, NULL);
@@ -931,10 +927,10 @@ void view_center_surface(struct sway_view *view) {
struct sway_container *con = view->container;
// We always center the current coordinates rather than the next, as the
// geometry immediately affects the currently active rendering.
- con->surface_x = fmax(con->current.content_x, con->current.content_x +
- (con->current.content_width - view->geometry.width) / 2);
- con->surface_y = fmax(con->current.content_y, con->current.content_y +
- (con->current.content_height - view->geometry.height) / 2);
+ int x = (int) fmax(0, (con->current.content_width - view->geometry.width) / 2);
+ int y = (int) fmax(0, (con->current.content_height - view->geometry.height) / 2);
+
+ wlr_scene_node_set_position(&view->content_tree->node, x, y);
}
struct sway_view *view_from_wlr_surface(struct wlr_surface *wlr_surface) {
@@ -1161,40 +1157,54 @@ bool view_is_urgent(struct sway_view *view) {
}
void view_remove_saved_buffer(struct sway_view *view) {
- if (!sway_assert(!wl_list_empty(&view->saved_buffers), "Expected a saved buffer")) {
+ if (!sway_assert(view->saved_surface_tree, "Expected a saved buffer")) {
return;
}
- struct sway_saved_buffer *saved_buf, *tmp;
- wl_list_for_each_safe(saved_buf, tmp, &view->saved_buffers, link) {
- wlr_buffer_unlock(&saved_buf->buffer->base);
- wl_list_remove(&saved_buf->link);
- free(saved_buf);
- }
+
+ wlr_scene_node_destroy(&view->saved_surface_tree->node);
+ view->saved_surface_tree = NULL;
+ wlr_scene_node_set_enabled(&view->content_tree->node, true);
}
-static void view_save_buffer_iterator(struct wlr_surface *surface,
+static void view_save_buffer_iterator(struct wlr_scene_buffer *buffer,
int sx, int sy, void *data) {
- struct sway_view *view = data;
-
- if (surface && surface->buffer) {
- wlr_buffer_lock(&surface->buffer->base);
- struct sway_saved_buffer *saved_buffer = calloc(1, sizeof(struct sway_saved_buffer));
- saved_buffer->buffer = surface->buffer;
- saved_buffer->width = surface->current.width;
- saved_buffer->height = surface->current.height;
- saved_buffer->x = view->container->surface_x + sx;
- saved_buffer->y = view->container->surface_y + sy;
- saved_buffer->transform = surface->current.transform;
- wlr_surface_get_buffer_source_box(surface, &saved_buffer->source_box);
- wl_list_insert(view->saved_buffers.prev, &saved_buffer->link);
+ struct wlr_scene_tree *tree = data;
+
+ struct wlr_scene_buffer *sbuf = wlr_scene_buffer_create(tree, NULL);
+ if (!sbuf) {
+ sway_log(SWAY_ERROR, "Could not allocate a scene buffer when saving a surface");
+ return;
}
+
+ wlr_scene_buffer_set_dest_size(sbuf,
+ buffer->dst_width, buffer->dst_height);
+ wlr_scene_buffer_set_opaque_region(sbuf, &buffer->opaque_region);
+ wlr_scene_buffer_set_source_box(sbuf, &buffer->src_box);
+ wlr_scene_node_set_position(&sbuf->node, sx, sy);
+ wlr_scene_buffer_set_transform(sbuf, buffer->transform);
+ wlr_scene_buffer_set_buffer(sbuf, buffer->buffer);
}
void view_save_buffer(struct sway_view *view) {
- if (!sway_assert(wl_list_empty(&view->saved_buffers), "Didn't expect saved buffer")) {
+ if (!sway_assert(!view->saved_surface_tree, "Didn't expect saved buffer")) {
view_remove_saved_buffer(view);
}
- view_for_each_surface(view, view_save_buffer_iterator, view);
+
+ view->saved_surface_tree = wlr_scene_tree_create(view->scene_tree);
+ if (!view->saved_surface_tree) {
+ sway_log(SWAY_ERROR, "Could not allocate a scene tree node when saving a surface");
+ return;
+ }
+
+ // Enable and disable the saved surface tree like so to atomitaclly update
+ // the tree. This will prevent over damaging or other weirdness.
+ wlr_scene_node_set_enabled(&view->saved_surface_tree->node, false);
+
+ wlr_scene_node_for_each_buffer(&view->content_tree->node,
+ view_save_buffer_iterator, view->saved_surface_tree);
+
+ wlr_scene_node_set_enabled(&view->content_tree->node, false);
+ wlr_scene_node_set_enabled(&view->saved_surface_tree->node, true);
}
bool view_is_transient_for(struct sway_view *child,
@@ -1202,3 +1212,19 @@ bool view_is_transient_for(struct sway_view *child,
return child->impl->is_transient_for &&
child->impl->is_transient_for(child, ancestor);
}
+
+static void send_frame_done_iterator(struct wlr_scene_buffer *scene_buffer,
+ int x, int y, void *data) {
+ struct timespec *when = data;
+ wl_signal_emit_mutable(&scene_buffer->events.frame_done, when);
+}
+
+void view_send_frame_done(struct sway_view *view) {
+ struct timespec when;
+ clock_gettime(CLOCK_MONOTONIC, &when);
+
+ struct wlr_scene_node *node;
+ wl_list_for_each(node, &view->content_tree->children, link) {
+ wlr_scene_node_for_each_buffer(node, send_frame_done_iterator, &when);
+ }
+}