mirror of
https://github.com/swaywm/sway.git
synced 2026-04-23 06:46:27 -04:00
view: remove saved buffers
This commit is contained in:
parent
6ffa4b1f70
commit
3809e80ef9
5 changed files with 2 additions and 162 deletions
|
|
@ -56,15 +56,6 @@ struct sway_view_impl {
|
||||||
void (*destroy)(struct sway_view *view);
|
void (*destroy)(struct sway_view *view);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct sway_saved_buffer {
|
|
||||||
struct wlr_client_buffer *buffer;
|
|
||||||
int x, y;
|
|
||||||
int width, height;
|
|
||||||
enum wl_output_transform transform;
|
|
||||||
struct wlr_fbox source_box;
|
|
||||||
struct wl_list link; // sway_view::saved_buffers
|
|
||||||
};
|
|
||||||
|
|
||||||
struct sway_view {
|
struct sway_view {
|
||||||
enum sway_view_type type;
|
enum sway_view_type type;
|
||||||
const struct sway_view_impl *impl;
|
const struct sway_view_impl *impl;
|
||||||
|
|
@ -87,16 +78,10 @@ struct sway_view {
|
||||||
bool allow_request_urgent;
|
bool allow_request_urgent;
|
||||||
struct wl_event_source *urgent_timer;
|
struct wl_event_source *urgent_timer;
|
||||||
|
|
||||||
struct wl_list saved_buffers; // sway_saved_buffer::link
|
|
||||||
|
|
||||||
// The geometry for whatever the client is committing, regardless of
|
// The geometry for whatever the client is committing, regardless of
|
||||||
// transaction state. Updated on every commit.
|
// transaction state. Updated on every commit.
|
||||||
struct wlr_box geometry;
|
struct wlr_box geometry;
|
||||||
|
|
||||||
// The "old" geometry during a transaction. Used to damage the old location
|
|
||||||
// when a transaction is applied.
|
|
||||||
struct wlr_box saved_geometry;
|
|
||||||
|
|
||||||
struct wlr_foreign_toplevel_handle_v1 *foreign_toplevel;
|
struct wlr_foreign_toplevel_handle_v1 *foreign_toplevel;
|
||||||
struct wl_listener foreign_activate_request;
|
struct wl_listener foreign_activate_request;
|
||||||
struct wl_listener foreign_fullscreen_request;
|
struct wl_listener foreign_fullscreen_request;
|
||||||
|
|
@ -356,10 +341,6 @@ void view_set_urgent(struct sway_view *view, bool enable);
|
||||||
|
|
||||||
bool view_is_urgent(struct sway_view *view);
|
bool view_is_urgent(struct sway_view *view);
|
||||||
|
|
||||||
void view_remove_saved_buffer(struct sway_view *view);
|
|
||||||
|
|
||||||
void view_save_buffer(struct sway_view *view);
|
|
||||||
|
|
||||||
bool view_is_transient_for(struct sway_view *child, struct sway_view *ancestor);
|
bool view_is_transient_for(struct sway_view *child, struct sway_view *ancestor);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -431,10 +431,6 @@ static bool scan_out_fullscreen_view(struct sway_output *output,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!wl_list_empty(&view->saved_buffers)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < workspace->current.floating->length; ++i) {
|
for (int i = 0; i < workspace->current.floating->length; ++i) {
|
||||||
struct sway_container *floater =
|
struct sway_container *floater =
|
||||||
workspace->current.floating->items[i];
|
workspace->current.floating->items[i];
|
||||||
|
|
|
||||||
|
|
@ -288,76 +288,13 @@ static void render_view_popups(struct sway_view *view,
|
||||||
render_surface_iterator, &data);
|
render_surface_iterator, &data);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void render_saved_view(struct sway_view *view,
|
|
||||||
struct sway_output *output, pixman_region32_t *damage, float alpha) {
|
|
||||||
struct wlr_output *wlr_output = output->wlr_output;
|
|
||||||
|
|
||||||
if (wl_list_empty(&view->saved_buffers)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool floating = container_is_current_floating(view->container);
|
|
||||||
|
|
||||||
struct sway_saved_buffer *saved_buf;
|
|
||||||
wl_list_for_each(saved_buf, &view->saved_buffers, link) {
|
|
||||||
if (!saved_buf->buffer->texture) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct wlr_box proj_box = {
|
|
||||||
.x = saved_buf->x - view->saved_geometry.x - output->lx,
|
|
||||||
.y = saved_buf->y - view->saved_geometry.y - output->ly,
|
|
||||||
.width = saved_buf->width,
|
|
||||||
.height = saved_buf->height,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct wlr_box output_box = {
|
|
||||||
.width = output->width,
|
|
||||||
.height = output->height,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct wlr_box intersection;
|
|
||||||
bool intersects = wlr_box_intersection(&intersection, &output_box, &proj_box);
|
|
||||||
if (!intersects) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct wlr_box dst_box = proj_box;
|
|
||||||
scale_box(&proj_box, wlr_output->scale);
|
|
||||||
|
|
||||||
float matrix[9];
|
|
||||||
enum wl_output_transform transform = wlr_output_transform_invert(saved_buf->transform);
|
|
||||||
wlr_matrix_project_box(matrix, &proj_box, transform, 0,
|
|
||||||
wlr_output->transform_matrix);
|
|
||||||
|
|
||||||
if (!floating) {
|
|
||||||
dst_box.width = fmin(dst_box.width,
|
|
||||||
view->container->current.content_width -
|
|
||||||
(saved_buf->x - view->container->current.content_x) + view->saved_geometry.x);
|
|
||||||
dst_box.height = fmin(dst_box.height,
|
|
||||||
view->container->current.content_height -
|
|
||||||
(saved_buf->y - view->container->current.content_y) + view->saved_geometry.y);
|
|
||||||
}
|
|
||||||
scale_box(&dst_box, wlr_output->scale);
|
|
||||||
|
|
||||||
render_texture(wlr_output, damage, saved_buf->buffer->texture,
|
|
||||||
&saved_buf->source_box, &dst_box, matrix, alpha);
|
|
||||||
}
|
|
||||||
|
|
||||||
// FIXME: we should set the surface that this saved buffer originates from
|
|
||||||
// as sampled here.
|
|
||||||
// https://github.com/swaywm/sway/pull/4465#discussion_r321082059
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Render a view's surface and left/bottom/right borders.
|
* Render a view's surface and left/bottom/right borders.
|
||||||
*/
|
*/
|
||||||
static void render_view(struct sway_output *output, pixman_region32_t *damage,
|
static void render_view(struct sway_output *output, pixman_region32_t *damage,
|
||||||
struct sway_container *con, struct border_colors *colors) {
|
struct sway_container *con, struct border_colors *colors) {
|
||||||
struct sway_view *view = con->view;
|
struct sway_view *view = con->view;
|
||||||
if (!wl_list_empty(&view->saved_buffers)) {
|
if (view->surface) {
|
||||||
render_saved_view(view, output, damage, view->container->alpha);
|
|
||||||
} else if (view->surface) {
|
|
||||||
render_view_toplevels(view, output, damage, view->container->alpha);
|
render_view_toplevels(view, output, damage, view->container->alpha);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1062,9 +999,7 @@ void output_render(struct sway_output *output, struct timespec *when,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fullscreen_con->view) {
|
if (fullscreen_con->view) {
|
||||||
if (!wl_list_empty(&fullscreen_con->view->saved_buffers)) {
|
if (fullscreen_con->view->surface) {
|
||||||
render_saved_view(fullscreen_con->view, output, damage, 1.0f);
|
|
||||||
} else if (fullscreen_con->view->surface) {
|
|
||||||
render_view_toplevels(fullscreen_con->view,
|
render_view_toplevels(fullscreen_con->view,
|
||||||
output, damage, 1.0f);
|
output, damage, 1.0f);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -232,20 +232,6 @@ static void apply_workspace_state(struct sway_workspace *ws,
|
||||||
static void apply_container_state(struct sway_container *container,
|
static void apply_container_state(struct sway_container *container,
|
||||||
struct sway_container_state *state) {
|
struct sway_container_state *state) {
|
||||||
struct sway_view *view = container->view;
|
struct sway_view *view = container->view;
|
||||||
// Damage the old location
|
|
||||||
desktop_damage_whole_container(container);
|
|
||||||
if (view && !wl_list_empty(&view->saved_buffers)) {
|
|
||||||
struct sway_saved_buffer *saved_buf;
|
|
||||||
wl_list_for_each(saved_buf, &view->saved_buffers, link) {
|
|
||||||
struct wlr_box box = {
|
|
||||||
.x = saved_buf->x - view->saved_geometry.x,
|
|
||||||
.y = saved_buf->y - view->saved_geometry.y,
|
|
||||||
.width = saved_buf->width,
|
|
||||||
.height = saved_buf->height,
|
|
||||||
};
|
|
||||||
desktop_damage_box(&box);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// There are separate children lists for each instruction state, the
|
// There are separate children lists for each instruction state, the
|
||||||
// container's current state and the container's pending state
|
// container's current state and the container's pending state
|
||||||
|
|
@ -256,12 +242,6 @@ static void apply_container_state(struct sway_container *container,
|
||||||
|
|
||||||
memcpy(&container->current, state, sizeof(struct sway_container_state));
|
memcpy(&container->current, state, sizeof(struct sway_container_state));
|
||||||
|
|
||||||
if (view && !wl_list_empty(&view->saved_buffers)) {
|
|
||||||
if (!container->node.destroying || container->node.ntxnrefs == 1) {
|
|
||||||
view_remove_saved_buffer(view);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// If the view hasn't responded to the configure, center it within
|
// If the view hasn't responded to the configure, center it within
|
||||||
// the container. This is important for fullscreen views which
|
// the container. This is important for fullscreen views which
|
||||||
// refuse to resize to the size of the output.
|
// refuse to resize to the size of the output.
|
||||||
|
|
@ -415,22 +395,11 @@ static void transaction_commit(struct sway_transaction *transaction) {
|
||||||
++transaction->num_waiting;
|
++transaction->num_waiting;
|
||||||
}
|
}
|
||||||
|
|
||||||
// From here on we are rendering a saved buffer of the view, which
|
|
||||||
// means we can send a frame done event to make the client redraw it
|
|
||||||
// as soon as possible. Additionally, this is required if a view is
|
|
||||||
// mapping and its default geometry doesn't intersect an output.
|
|
||||||
struct timespec now;
|
struct timespec now;
|
||||||
clock_gettime(CLOCK_MONOTONIC, &now);
|
clock_gettime(CLOCK_MONOTONIC, &now);
|
||||||
wlr_surface_send_frame_done(
|
wlr_surface_send_frame_done(
|
||||||
node->sway_container->view->surface, &now);
|
node->sway_container->view->surface, &now);
|
||||||
}
|
}
|
||||||
if (!hidden && node_is_view(node) &&
|
|
||||||
wl_list_empty(&node->sway_container->view->saved_buffers)) {
|
|
||||||
view_save_buffer(node->sway_container->view);
|
|
||||||
memcpy(&node->sway_container->view->saved_geometry,
|
|
||||||
&node->sway_container->view->geometry,
|
|
||||||
sizeof(struct wlr_box));
|
|
||||||
}
|
|
||||||
node->instruction = instruction;
|
node->instruction = instruction;
|
||||||
}
|
}
|
||||||
transaction->num_configures = transaction->num_waiting;
|
transaction->num_configures = transaction->num_waiting;
|
||||||
|
|
|
||||||
|
|
@ -37,7 +37,6 @@ void view_init(struct sway_view *view, enum sway_view_type type,
|
||||||
view->type = type;
|
view->type = type;
|
||||||
view->impl = impl;
|
view->impl = impl;
|
||||||
view->executed_criteria = create_list();
|
view->executed_criteria = create_list();
|
||||||
wl_list_init(&view->saved_buffers);
|
|
||||||
view->allow_request_urgent = true;
|
view->allow_request_urgent = true;
|
||||||
view->shortcuts_inhibit = SHORTCUTS_INHIBIT_DEFAULT;
|
view->shortcuts_inhibit = SHORTCUTS_INHIBIT_DEFAULT;
|
||||||
wl_signal_init(&view->events.unmap);
|
wl_signal_init(&view->events.unmap);
|
||||||
|
|
@ -57,9 +56,6 @@ void view_destroy(struct sway_view *view) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
wl_list_remove(&view->events.unmap.listener_list);
|
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);
|
list_free(view->executed_criteria);
|
||||||
|
|
||||||
free(view->title_format);
|
free(view->title_format);
|
||||||
|
|
@ -1376,43 +1372,6 @@ bool view_is_urgent(struct sway_view *view) {
|
||||||
return view->urgent.tv_sec || view->urgent.tv_nsec;
|
return view->urgent.tv_sec || view->urgent.tv_nsec;
|
||||||
}
|
}
|
||||||
|
|
||||||
void view_remove_saved_buffer(struct sway_view *view) {
|
|
||||||
if (!sway_assert(!wl_list_empty(&view->saved_buffers), "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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void view_save_buffer_iterator(struct wlr_surface *surface,
|
|
||||||
int sx, int sy, void *data) {
|
|
||||||
struct sway_view *view = data;
|
|
||||||
|
|
||||||
if (surface && wlr_surface_has_buffer(surface)) {
|
|
||||||
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, &saved_buffer->link);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void view_save_buffer(struct sway_view *view) {
|
|
||||||
if (!sway_assert(wl_list_empty(&view->saved_buffers), "Didn't expect saved buffer")) {
|
|
||||||
view_remove_saved_buffer(view);
|
|
||||||
}
|
|
||||||
view_for_each_surface(view, view_save_buffer_iterator, view);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool view_is_transient_for(struct sway_view *child,
|
bool view_is_transient_for(struct sway_view *child,
|
||||||
struct sway_view *ancestor) {
|
struct sway_view *ancestor) {
|
||||||
return child->impl->is_transient_for &&
|
return child->impl->is_transient_for &&
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue