diff --git a/include/sway/desktop/fx_renderer/fx_renderer.h b/include/sway/desktop/fx_renderer/fx_renderer.h index 410e3d94..8feb9753 100644 --- a/include/sway/desktop/fx_renderer/fx_renderer.h +++ b/include/sway/desktop/fx_renderer/fx_renderer.h @@ -8,6 +8,7 @@ #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 }; @@ -124,6 +125,8 @@ 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 @@ -214,4 +217,6 @@ 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_view_snapshot(struct fx_renderer *renderer, struct sway_view *view); + #endif diff --git a/include/sway/output.h b/include/sway/output.h index 6e9f26e4..c4ce36d4 100644 --- a/include/sway/output.h +++ b/include/sway/output.h @@ -185,6 +185,8 @@ 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); diff --git a/include/sway/tree/container.h b/include/sway/tree/container.h index 7fb0286f..ed2b1114 100644 --- a/include/sway/tree/container.h +++ b/include/sway/tree/container.h @@ -4,6 +4,7 @@ #include #include #include "list.h" +#include "sway/desktop/fx_renderer/fx_framebuffer.h" #include "sway/tree/node.h" struct sway_view; @@ -124,6 +125,7 @@ struct sway_container { float target_alpha; float max_alpha; + struct fx_framebuffer close_animation_fb; struct wl_event_source *animation_present_timer; int corner_radius; diff --git a/include/sway/tree/view.h b/include/sway/tree/view.h index 7b52aa4b..c78d17d0 100644 --- a/include/sway/tree/view.h +++ b/include/sway/tree/view.h @@ -328,6 +328,7 @@ void view_map(struct sway_view *view, struct wlr_surface *wlr_surface, bool fullscreen, struct wlr_output *fullscreen_output, bool decoration); void view_unmap(struct sway_view *view); +void view_unmap_finish(struct sway_view *view); void view_update_size(struct sway_view *view); void view_center_surface(struct sway_view *view); diff --git a/sway/desktop/fx_renderer/fx_renderer.c b/sway/desktop/fx_renderer/fx_renderer.c index d2fef6f1..ac3bec83 100644 --- a/sway/desktop/fx_renderer/fx_renderer.c +++ b/sway/desktop/fx_renderer/fx_renderer.c @@ -19,6 +19,7 @@ #include "sway/desktop/fx_renderer/fx_texture.h" #include "sway/desktop/fx_renderer/matrix.h" #include "sway/server.h" +#include "sway/output.h" // shaders #include "blur1_frag_src.h" @@ -29,6 +30,8 @@ #include "quad_frag_src.h" #include "quad_round_frag_src.h" #include "stencil_mask_frag_src.h" +#include "sway/tree/node.h" +#include "sway/tree/workspace.h" #include "tex_frag_src.h" static const GLfloat verts[] = { @@ -269,6 +272,7 @@ 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(); @@ -871,5 +875,36 @@ void fx_render_blur(struct fx_renderer *renderer, const float matrix[static 9], glDisableVertexAttribArray(shader->pos_attrib); glDisableVertexAttribArray(shader->tex_attrib); - +} + +void fx_create_view_snapshot(struct fx_renderer *renderer, struct sway_view *view) { + assert(view); + + // 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_container *con = view->container; + 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); + + // TODO: add check to see if container is fading out in render_container + // TODO: render without blur? + render_container(output, &damage, con, con->current.focused); + + // rebind the main fb + //fx_framebuffer_bind(&renderer->wlr_buffer); } diff --git a/sway/desktop/render.c b/sway/desktop/render.c index ab7f919b..469b1fe0 100644 --- a/sway/desktop/render.c +++ b/sway/desktop/render.c @@ -1398,9 +1398,6 @@ 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. * @@ -1685,7 +1682,7 @@ static void render_containers(struct sway_output *output, } } -static void render_container(struct sway_output *output, +void render_container(struct sway_output *output, pixman_region32_t *damage, struct sway_container *con, bool focused) { struct parent_data data = { .layout = con->current.layout, diff --git a/sway/tree/container.c b/sway/tree/container.c index dc51559b..f114d53e 100644 --- a/sway/tree/container.c +++ b/sway/tree/container.c @@ -51,7 +51,6 @@ static int animation_timer(void *data) { if (con->alpha != con->target_alpha) { wl_event_source_timer_update(con->animation_present_timer, fastest_output_refresh_s * 1000); } else if (is_closing && con->view->impl->close) { - con->view->impl->close(con->view); } container_damage_whole(con); @@ -75,6 +74,7 @@ struct sway_container *container_create(struct sway_view *view) { c->shadow_enabled = config->shadow_enabled; c->blur_enabled = config->blur_enabled; c->corner_radius = config->corner_radius; + c->close_animation_fb = fx_framebuffer_create(); if (!view) { c->pending.children = create_list(); @@ -96,6 +96,7 @@ struct sway_container *container_create(struct sway_view *view) { } void container_destroy(struct sway_container *con) { + printf("destroying container\n"); if (!sway_assert(con->node.destroying, "Tried to free container which wasn't marked as destroying")) { return; @@ -135,6 +136,7 @@ void container_destroy(struct sway_container *con) { } void container_begin_destroy(struct sway_container *con) { + printf("beginning container destroy\n"); if (con->view) { ipc_event_window(con, "close"); } diff --git a/sway/tree/view.c b/sway/tree/view.c index d37cfb40..12c14e80 100644 --- a/sway/tree/view.c +++ b/sway/tree/view.c @@ -428,8 +428,9 @@ void view_set_tiled(struct sway_view *view, bool tiled) { } void view_close(struct sway_view *view) { - view->container->target_alpha = 0; - wl_event_source_timer_update(view->container->animation_present_timer, 1); + if (view->impl->close) { + view->impl->close(view); + } } void view_close_popups(struct sway_view *view) { @@ -906,6 +907,13 @@ void view_map(struct sway_view *view, struct wlr_surface *wlr_surface, } void view_unmap(struct sway_view *view) { + printf("unmap view\n"); + // take a snapshot for fade-out animation + struct sway_workspace *ws = view->container->pending.workspace; + if (ws) { + fx_create_view_snapshot(ws->output->renderer, view); + } + wl_signal_emit_mutable(&view->events.unmap, view); wl_list_remove(&view->surface_new_subsurface.link); @@ -921,7 +929,6 @@ void view_unmap(struct sway_view *view) { } struct sway_container *parent = view->container->pending.parent; - struct sway_workspace *ws = view->container->pending.workspace; container_begin_destroy(view->container); if (parent) { container_reap_empty(parent);