render saved buffer on fade-out
This commit is contained in:
parent
d7cf2986fa
commit
a27fa243ad
9 changed files with 32 additions and 99 deletions
|
@ -8,7 +8,6 @@
|
|||
|
||||
#include "sway/desktop/fx_renderer/fx_framebuffer.h"
|
||||
#include "sway/desktop/fx_renderer/fx_texture.h"
|
||||
#include "sway/tree/view.h"
|
||||
|
||||
enum corner_location { TOP_LEFT, TOP_RIGHT, BOTTOM_RIGHT, BOTTOM_LEFT, ALL, NONE };
|
||||
|
||||
|
@ -125,8 +124,6 @@ struct fx_renderer {
|
|||
|
||||
struct wlr_output *wlr_output;
|
||||
|
||||
struct wlr_egl *wlr_egl;
|
||||
|
||||
// The framebuffer used by wlroots
|
||||
struct fx_framebuffer wlr_buffer;
|
||||
// Contains the blurred background for tiled windows
|
||||
|
@ -217,8 +214,4 @@ void fx_render_blur(struct fx_renderer *renderer, const float matrix[static 9],
|
|||
struct fx_framebuffer **buffer, struct blur_shader *shader, const struct wlr_box *box,
|
||||
int blur_radius);
|
||||
|
||||
void fx_create_container_snapshot(struct fx_renderer *renderer, struct sway_container *con);
|
||||
|
||||
void fx_render_container_snapshot(struct fx_renderer *renderer, struct sway_container *con);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -185,9 +185,6 @@ void render_rounded_rect(struct sway_output *output,
|
|||
float color[static 4], int corner_radius,
|
||||
enum corner_location corner_location);
|
||||
|
||||
void render_container(struct sway_output *output,
|
||||
pixman_region32_t *damage, struct sway_container *con, bool parent_focused);
|
||||
|
||||
void premultiply_alpha(float color[4], float opacity);
|
||||
|
||||
void scale_box(struct wlr_box *box, float scale);
|
||||
|
|
|
@ -380,7 +380,4 @@ void view_assign_ctx(struct sway_view *view, struct launcher_ctx *ctx);
|
|||
|
||||
bool gaps_to_edge(struct sway_view *view);
|
||||
|
||||
|
||||
void view_container_cleanup(struct sway_view *view);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -273,7 +273,6 @@ struct fx_renderer *fx_renderer_create(struct wlr_egl *egl, struct wlr_output *w
|
|||
sway_log(SWAY_ERROR, "GLES2 RENDERER: Could not make EGL current");
|
||||
return NULL;
|
||||
}
|
||||
renderer->wlr_egl = egl;
|
||||
|
||||
renderer->wlr_buffer = fx_framebuffer_create();
|
||||
renderer->blur_buffer = fx_framebuffer_create();
|
||||
|
@ -877,57 +876,3 @@ void fx_render_blur(struct fx_renderer *renderer, const float matrix[static 9],
|
|||
glDisableVertexAttribArray(shader->pos_attrib);
|
||||
glDisableVertexAttribArray(shader->tex_attrib);
|
||||
}
|
||||
|
||||
void fx_render_container_snapshot(struct fx_renderer *renderer, struct sway_container *con) {
|
||||
// TODO: move create_deco_data
|
||||
// TODO: render without blur?
|
||||
struct decoration_data deco_data = {
|
||||
.alpha = 1.0f,
|
||||
.dim = 0.0f,
|
||||
.dim_color = config->dim_inactive_colors.unfocused,
|
||||
.corner_radius = 0,
|
||||
.saturation = 1.0f,
|
||||
.has_titlebar = false,
|
||||
.blur = false,
|
||||
.discard_transparent = false,
|
||||
.shadow = false,
|
||||
};
|
||||
struct sway_output *output = con->pending.workspace->output;
|
||||
struct wlr_box dst_box = { 0, 0, output->width, output->height };
|
||||
enum wl_output_transform transform = wlr_output_transform_invert(output->wlr_output->transform);
|
||||
float matrix[9];
|
||||
wlr_matrix_project_box(matrix, &dst_box, transform, 0.0, output->wlr_output->transform_matrix);
|
||||
|
||||
fx_render_texture_with_matrix(renderer, &con->close_animation_fb.texture, &dst_box, matrix, deco_data);
|
||||
}
|
||||
|
||||
void fx_create_container_snapshot(struct fx_renderer *renderer, struct sway_container *con) {
|
||||
assert(con);
|
||||
|
||||
// TODO: move to function? used in creation too
|
||||
if (!eglMakeCurrent(wlr_egl_get_display(renderer->wlr_egl), EGL_NO_SURFACE, EGL_NO_SURFACE,
|
||||
wlr_egl_get_context(renderer->wlr_egl))) {
|
||||
sway_log(SWAY_ERROR, "GLES2 RENDERER: Could not make EGL current");
|
||||
return;
|
||||
}
|
||||
|
||||
struct sway_output *output = con->pending.workspace->output;
|
||||
|
||||
fx_framebuffer_update(&con->close_animation_fb, output->width, output->height);
|
||||
fx_framebuffer_bind(&con->close_animation_fb);
|
||||
|
||||
// damage whole output to ensure full container is rendered
|
||||
// (temporary, render_container will only render container area)
|
||||
struct wlr_box box = { 0, 0, output->width, output->height };
|
||||
scale_box(&box, output->wlr_output->scale);
|
||||
pixman_region32_t damage;
|
||||
pixman_region32_init(&damage);
|
||||
pixman_region32_union_rect(&damage, &damage, box.x, box.y, box.width, box.height);
|
||||
|
||||
// render container instead?
|
||||
fx_render_container_snapshot(renderer, con);
|
||||
|
||||
// rebind the main fb
|
||||
fx_framebuffer_bind(&renderer->wlr_buffer);
|
||||
printf("snapshot created\n");
|
||||
}
|
||||
|
|
|
@ -765,6 +765,7 @@ static void render_view_popups(struct sway_view *view, struct sway_output *outpu
|
|||
|
||||
static void render_saved_view(struct sway_view *view, struct sway_output *output,
|
||||
pixman_region32_t *damage, struct decoration_data deco_data) {
|
||||
printf("rendering saved view\n");
|
||||
struct wlr_output *wlr_output = output->wlr_output;
|
||||
|
||||
if (wl_list_empty(&view->saved_buffers)) {
|
||||
|
@ -873,8 +874,11 @@ static void render_view(struct sway_output *output, pixman_region32_t *damage,
|
|||
|
||||
// render view
|
||||
if (!wl_list_empty(&view->saved_buffers)) {
|
||||
printf("rendering saved view\n");
|
||||
render_saved_view(view, output, damage, deco_data);
|
||||
} else if (view->surface) {
|
||||
|
||||
printf("rendering view toplevels\n");
|
||||
render_view_toplevels(view, output, damage, deco_data);
|
||||
}
|
||||
|
||||
|
@ -1398,6 +1402,9 @@ struct parent_data {
|
|||
struct sway_container *active_child;
|
||||
};
|
||||
|
||||
static void render_container(struct sway_output *output,
|
||||
pixman_region32_t *damage, struct sway_container *con, bool parent_focused);
|
||||
|
||||
/**
|
||||
* Render a container's children using a L_HORIZ or L_VERT layout.
|
||||
*
|
||||
|
@ -1684,12 +1691,6 @@ static void render_containers(struct sway_output *output,
|
|||
|
||||
void render_container(struct sway_output *output,
|
||||
pixman_region32_t *damage, struct sway_container *con, bool focused) {
|
||||
if (con->is_fading_out) {
|
||||
printf("rendering snapshot\n");
|
||||
fx_render_container_snapshot(output->renderer, con);
|
||||
return;
|
||||
}
|
||||
|
||||
struct parent_data data = {
|
||||
.layout = con->current.layout,
|
||||
.box = {
|
||||
|
@ -1805,6 +1806,7 @@ void output_render(struct sway_output *output, struct timespec *when,
|
|||
struct wlr_output *wlr_output = output->wlr_output;
|
||||
struct fx_renderer *renderer = output->renderer;
|
||||
|
||||
printf("rendering output\n");
|
||||
struct sway_workspace *workspace = output->current.active_workspace;
|
||||
if (workspace == NULL) {
|
||||
return;
|
||||
|
@ -1983,6 +1985,7 @@ void output_render(struct sway_output *output, struct timespec *when,
|
|||
render_output_blur(output, damage);
|
||||
}
|
||||
|
||||
printf("rendering workspace\n");
|
||||
render_workspace(output, damage, workspace, workspace->current.focused);
|
||||
render_floating(output, damage);
|
||||
#if HAVE_XWAYLAND
|
||||
|
|
|
@ -256,7 +256,7 @@ static void apply_container_state(struct sway_container *container,
|
|||
|
||||
memcpy(&container->current, state, sizeof(struct sway_container_state));
|
||||
|
||||
if (view && !wl_list_empty(&view->saved_buffers)) {
|
||||
if (view && !wl_list_empty(&view->saved_buffers) && !container->is_fading_out) {
|
||||
if (!container->node.destroying || container->node.ntxnrefs == 1) {
|
||||
view_remove_saved_buffer(view);
|
||||
}
|
||||
|
@ -401,6 +401,7 @@ static void transaction_commit(struct sway_transaction *transaction) {
|
|||
for (int i = 0; i < transaction->instructions->length; ++i) {
|
||||
struct sway_transaction_instruction *instruction =
|
||||
transaction->instructions->items[i];
|
||||
printf("processing instruction for %s\n", instruction->node->sway_container->title);
|
||||
struct sway_node *node = instruction->node;
|
||||
bool hidden = node_is_view(node) && !node->destroying &&
|
||||
!view_is_visible(node->sway_container->view);
|
||||
|
@ -426,6 +427,7 @@ static void transaction_commit(struct sway_transaction *transaction) {
|
|||
}
|
||||
if (!hidden && node_is_view(node) &&
|
||||
wl_list_empty(&node->sway_container->view->saved_buffers)) {
|
||||
printf("saving buffer\n");
|
||||
view_save_buffer(node->sway_container->view);
|
||||
memcpy(&node->sway_container->view->saved_geometry,
|
||||
&node->sway_container->view->geometry,
|
||||
|
@ -523,6 +525,7 @@ void transaction_notify_view_ready_by_geometry(struct sway_view *view,
|
|||
|
||||
static void _transaction_commit_dirty(bool server_request) {
|
||||
if (!server.dirty_nodes->length) {
|
||||
printf("no dirty nodes\n");
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -540,6 +543,7 @@ static void _transaction_commit_dirty(bool server_request) {
|
|||
}
|
||||
server.dirty_nodes->length = 0;
|
||||
|
||||
printf("committing pending transaction\n");
|
||||
transaction_commit_pending();
|
||||
}
|
||||
|
||||
|
|
|
@ -507,6 +507,7 @@ static void handle_map(struct wl_listener *listener, void *data) {
|
|||
}
|
||||
|
||||
static void handle_destroy(struct wl_listener *listener, void *data) {
|
||||
/*
|
||||
struct sway_xdg_shell_view *xdg_shell_view =
|
||||
wl_container_of(listener, xdg_shell_view, destroy);
|
||||
struct sway_view *view = &xdg_shell_view->view;
|
||||
|
@ -521,6 +522,7 @@ static void handle_destroy(struct wl_listener *listener, void *data) {
|
|||
view->xdg_decoration->view = NULL;
|
||||
}
|
||||
view_begin_destroy(view);
|
||||
*/
|
||||
}
|
||||
|
||||
struct sway_view *view_from_wlr_xdg_surface(
|
||||
|
|
|
@ -52,8 +52,7 @@ static int animation_timer(void *data) {
|
|||
wl_event_source_timer_update(con->animation_present_timer, fastest_output_refresh_s * 1000);
|
||||
} else if (is_closing) { // equal to target and closing
|
||||
printf("done animation; clean up view\n");
|
||||
con->is_fading_out = false;
|
||||
view_container_cleanup(con->view);
|
||||
//con->is_fading_out = false;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -130,13 +129,10 @@ void container_destroy(struct sway_container *con) {
|
|||
|
||||
wl_event_source_remove(con->animation_present_timer);
|
||||
|
||||
printf("alive 0\n");
|
||||
if (con->view && con->view->container == con) {
|
||||
con->view->container = NULL;
|
||||
if (con->view->destroying) {
|
||||
printf("alive\n");
|
||||
view_destroy(con->view);
|
||||
printf("alive 2\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -145,7 +141,6 @@ void container_destroy(struct sway_container *con) {
|
|||
|
||||
void container_begin_destroy(struct sway_container *con) {
|
||||
printf("container begin destroy\n");
|
||||
// TODO; better way of deleting view
|
||||
if (con->view && !con->is_fading_out) {
|
||||
ipc_event_window(con, "close");
|
||||
}
|
||||
|
@ -158,8 +153,6 @@ void container_begin_destroy(struct sway_container *con) {
|
|||
container_fullscreen_disable(con);
|
||||
}
|
||||
|
||||
// TODO: problem here
|
||||
printf("about to emit signal\n");
|
||||
wl_signal_emit_mutable(&con->node.events.destroy, &con->node);
|
||||
|
||||
container_end_mouse_operation(con);
|
||||
|
@ -236,6 +229,9 @@ static struct sway_container *surface_at_view(struct sway_container *con, double
|
|||
return NULL;
|
||||
}
|
||||
struct sway_view *view = con->view;
|
||||
if (con->is_fading_out) {
|
||||
return NULL;
|
||||
}
|
||||
double view_sx = lx - con->surface_x + view->geometry.x;
|
||||
double view_sy = ly - con->surface_y + view->geometry.y;
|
||||
|
||||
|
|
|
@ -46,6 +46,7 @@ void view_init(struct sway_view *view, enum sway_view_type type,
|
|||
}
|
||||
|
||||
void view_destroy(struct sway_view *view) {
|
||||
printf("view destroy\n");
|
||||
if (!sway_assert(view->surface == NULL, "Tried to free mapped view")) {
|
||||
return;
|
||||
}
|
||||
|
@ -76,6 +77,7 @@ void view_destroy(struct sway_view *view) {
|
|||
}
|
||||
|
||||
void view_begin_destroy(struct sway_view *view) {
|
||||
printf("view begin destroy\n");
|
||||
if (!sway_assert(view->surface == NULL, "Tried to destroy a mapped view")) {
|
||||
return;
|
||||
}
|
||||
|
@ -906,9 +908,13 @@ void view_map(struct sway_view *view, struct wlr_surface *wlr_surface,
|
|||
}
|
||||
}
|
||||
|
||||
void view_container_cleanup(struct sway_view *view) {
|
||||
void view_unmap(struct sway_view *view) {
|
||||
printf("unmapping view\n");
|
||||
wl_signal_emit_mutable(&view->events.unmap, view);
|
||||
|
||||
wl_list_remove(&view->surface_new_subsurface.link);
|
||||
|
||||
/*
|
||||
if (view->urgent_timer) {
|
||||
wl_event_source_remove(view->urgent_timer);
|
||||
view->urgent_timer = NULL;
|
||||
|
@ -935,7 +941,7 @@ void view_container_cleanup(struct sway_view *view) {
|
|||
arrange_workspace(ws);
|
||||
workspace_detect_urgent(ws);
|
||||
}
|
||||
|
||||
*/
|
||||
struct sway_seat *seat;
|
||||
wl_list_for_each(seat, &server.input->seats, link) {
|
||||
seat->cursor->image_surface = NULL;
|
||||
|
@ -949,22 +955,12 @@ void view_container_cleanup(struct sway_view *view) {
|
|||
seat_consider_warp_to_focus(seat);
|
||||
}
|
||||
|
||||
transaction_commit_dirty();
|
||||
view->surface = NULL;
|
||||
}
|
||||
|
||||
void view_unmap(struct sway_view *view) {
|
||||
wl_signal_emit_mutable(&view->events.unmap, view);
|
||||
struct sway_workspace *ws = view->container->pending.workspace;
|
||||
if (ws && config->animation_duration > 0) {
|
||||
printf("starting fade out animation\n");
|
||||
node_set_dirty(&view->container->node);
|
||||
view->container->is_fading_out = true;
|
||||
fx_render_container_snapshot(ws->output->renderer, view->container);
|
||||
view->container->target_alpha = 0;
|
||||
wl_event_source_timer_update(view->container->animation_present_timer, 50);
|
||||
} else {
|
||||
view_container_cleanup(view);
|
||||
}
|
||||
transaction_commit_dirty();
|
||||
view->surface = NULL;
|
||||
}
|
||||
|
||||
void view_update_size(struct sway_view *view) {
|
||||
|
|
Loading…
Add table
Reference in a new issue