--- a/src/shade.hpp +++ b/src/shade.hpp @@ -1,5 +1,8 @@ #pragma once +#include +#include + #include #include #include @@ -36,8 +39,17 @@ wf::option_wrapper_t shade_duration{"pixdecor/shade_duration"}; public: - bool last_direction; + bool last_direction = false; shade_animation_t progression{shade_duration}; + + wf::geometry_t visible_box() + { + auto box = get_children_bounding_box(); + const auto retained = std::clamp(titlebar_height, 0, box.height); + box.height = std::clamp(std::ceil(box.height - + double(progression.shade) * (box.height - retained)), retained, box.height); + return box; + } class simple_node_render_instance_t : public wf::scene::transformer_render_instance_t { wf::signal::connection_t on_node_damaged = @@ -84,36 +96,34 @@ float(src_box.x + src_box.width), float(src_box.y + src_box.height)}; auto src_tex = wf::scene::transformer_render_instance_t::get_texture( 1.0); - auto shade_region = data.damage; - int height = src_box.height; - auto titlebar = self->titlebar_height + self->get_shadow_margin(); - src_box.y += self->titlebar_height; - src_box.height *= 1.0 - - (self->progression.shade * - ((src_box.height - titlebar) / float(src_box.height))); - auto progress_height = src_box.height; - shade_region &= src_box; + const auto visible = self->visible_box(); + const auto titlebar = std::clamp(self->titlebar_height, 0, visible.height); + const auto offset = src_box.height - visible.height; + auto body = visible; + body.y += titlebar; + body.height -= titlebar; + auto shade_region = data.damage & body; wf::gles::run_in_context([&] { wf::gles::bind_render_buffer(data.target); data.pass->custom_gles_subpass(data.target, [&] { - wf::gles::for_each_scissor_rect(data.target, data.damage, [=] () + wf::gles::for_each_scissor_rect(data.target, shade_region, [=] () { OpenGL::render_transformed_texture(wf::gles_texture_t{src_tex}, - {src_geometry.x1, src_geometry.y1 - float(height - progress_height), src_geometry.x2, - src_geometry.y2 - float(height - progress_height)}, {}, + {src_geometry.x1, src_geometry.y1 - float(offset), src_geometry.x2, + src_geometry.y2 - float(offset)}, {}, wf::gles::render_target_orthographic_projection(data.target), glm::vec4(1.0), 0); }); }); shade_region = data.damage; src_box = self->get_children_bounding_box(); - src_box.height = self->titlebar_height; + src_box.height = titlebar; shade_region &= src_box; data.pass->custom_gles_subpass(data.target, [&] { - wf::gles::for_each_scissor_rect(data.target, data.damage, [=] () + wf::gles::for_each_scissor_rect(data.target, shade_region, [=] () { OpenGL::render_transformed_texture(wf::gles_texture_t{src_tex}, src_geometry, {}, wf::gles::render_target_orthographic_projection(data.target), glm::vec4(1.0), 0); @@ -207,12 +217,7 @@ std::optional find_node_at(const wf::pointf_t& at) override { - auto bbox = this->get_children_bounding_box(); - if (((at.y - bbox.y) < - ((1.0 - - (this->progression.shade * ((bbox.height - this->titlebar_height) / float(bbox.height)))) * - bbox.height)) && - ((at.y - bbox.y) > 0.0)) + if (visible_box() & at) { return floating_inner_node_t::find_node_at(at); }