summaryrefslogtreecommitdiff
path: root/gui-libs/pixdecor/files/pixdecor-shade-input.patch
blob: cc5d842331eff09454a4c55d28c78fefc9cc7fc2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
--- a/src/shade.hpp
+++ b/src/shade.hpp
@@ -1,5 +1,8 @@
 #pragma once
 
+#include <algorithm>
+#include <cmath>
+
 #include <wayfire/output.hpp>
 #include <wayfire/opengl.hpp>
 #include <wayfire/core.hpp>
@@ -36,8 +39,17 @@
     wf::option_wrapper_t<wf::animation_description_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<double>(titlebar_height, 0, box.height);
+        box.height = std::clamp<double>(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<transformer_base_node_t>
     {
         wf::signal::connection_t<node_damage_signal> 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<transformer_base_node_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<double>(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<wf::scene::input_node_t> 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);
         }