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
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
|
diff -ruN -x _build -x locale a/README.md b/README.md
--- a/README.md 2026-10-29 17:15:58.626080143 -0500
+++ b/README.md 2026-10-29 17:22:15.195422699 -0500
@@ -26,3 +26,14 @@
`rounded_corner_radius = 8`, `shadow_radius = 24`, `shadow_color = 0.0 0.0 0.0 0.35`,
`inactive_shadow_color = 0.0 0.0 0.0 0.25` (unchanged) and `title_font = Inter 11`
(Pango falls back while Inter is not installed). `titlebar` stays `always`.
+
+## Sculpted inner padding (0.1.0_p20261006-r6)
+
+`border_padding` (default 0, Sculpted overlay only) ends the bevel that many pixels
+before the window. The freed space stays flat frame colour and is closed by a
+two-pixel bead at the window edge, lit from the top left like the bevel: one light
+and one dark pixel on every side, scaled by `border_depth`, so the edge reads against
+dark and light applications. Padding is capped at `border_size - 1`; a padding of 1
+keeps only the inner pixel of the bead. With an 11 px border, `border_padding = 7`
+leaves a 4 px bevel, 5 px of flat frame and the bead. At 0 the frame is pixel-identical
+to r5.
diff -ruN -x _build -x locale a/metadata/pixdecor.xml b/metadata/pixdecor.xml
--- a/metadata/pixdecor.xml 2026-10-29 17:15:58.626080143 -0500
+++ b/metadata/pixdecor.xml 2026-10-29 17:22:15.195422699 -0500
@@ -86,6 +86,12 @@
<_long>Color and opacity of the Sculpted overlay's outer rim, independent of border depth.</_long>
<default>#5a718124</default>
</option>
+ <option name="border_padding" type="int">
+ <_short>Inner padding</_short>
+ <_long>Sculpted overlay only: pixels of flat frame between the bevel and the window, closed by a two-pixel bead (one light, one dark pixel) at the window edge. At most the border size minus one; 0 runs the bevel up to the window.</_long>
+ <default>0</default>
+ <min>0</min>
+ </option>
<option name="rounded_corner_radius" type="int">
<_short>Rounded Corner Radius</_short>
<_long>The radius for corners.</_long>
diff -ruN -x _build -x locale a/src/deco-effects.cpp b/src/deco-effects.cpp
--- a/src/deco-effects.cpp 2026-10-29 17:15:58.619080115 -0500
+++ b/src/deco-effects.cpp 2026-10-29 17:18:30.288814448 -0500
@@ -2597,6 +2597,7 @@
GLfloat rim_f[4] = {GLfloat(rim.r), GLfloat(rim.g), GLfloat(rim.b), GLfloat(rim.a)};
GL_CALL(glUniform1f(10, border_depth));
GL_CALL(glUniform4fv(11, 1, rim_f));
+ GL_CALL(glUniform1i(12, int(border_padding) > 0 ? int(border_padding) : 0));
}
}
diff -ruN -x _build -x locale a/src/deco-effects.hpp b/src/deco-effects.hpp
--- a/src/deco-effects.hpp 2026-10-29 17:15:58.617080107 -0500
+++ b/src/deco-effects.hpp 2026-10-29 17:18:30.288814448 -0500
@@ -32,6 +32,7 @@
wf::option_wrapper_t<bool> effect_animate{"pixdecor/animate"};
wf::option_wrapper_t<double> border_depth{"pixdecor/border_depth"};
wf::option_wrapper_t<wf::color_t> pinstripe_color{"pixdecor/pinstripe_color"};
+ wf::option_wrapper_t<int> border_padding{"pixdecor/border_padding"};
wf::option_wrapper_t<int> rounded_corner_radius{"pixdecor/rounded_corner_radius"};
public:
diff -ruN -x _build -x locale a/src/decoration.cpp b/src/decoration.cpp
--- a/src/decoration.cpp 2026-10-29 17:15:58.623080131 -0500
+++ b/src/decoration.cpp 2026-10-29 17:18:30.289814439 -0500
@@ -80,6 +80,7 @@
wf::option_wrapper_t<bool> effect_animate{"pixdecor/animate"};
wf::option_wrapper_t<double> border_depth;
wf::option_wrapper_t<wf::color_t> pinstripe_color;
+ wf::option_wrapper_t<int> border_padding;
wf::option_wrapper_t<int> rounded_corner_radius{"pixdecor/rounded_corner_radius"};
wf::option_wrapper_t<int> shadow_radius{"pixdecor/shadow_radius"};
wf::option_wrapper_t<wf::color_t> shadow_color{"pixdecor/shadow_color"};
@@ -318,6 +319,7 @@
});
border_depth.load_option("pixdecor/border_depth");
pinstripe_color.load_option("pixdecor/pinstripe_color");
+ border_padding.load_option("pixdecor/border_padding");
auto& ol = wf::get_core().output_layout;
ol->connect(&on_output_added);
ol->connect(&on_output_removed);
@@ -564,6 +566,7 @@
};
border_depth.set_callback(repaint_frames);
pinstripe_color.set_callback(repaint_frames);
+ border_padding.set_callback(repaint_frames);
rounded_corner_radius.set_callback([=]
{
for (auto& view : wf::get_core().get_all_views())
diff -ruN -x _build -x locale a/src/sculpted-overlay.hpp b/src/sculpted-overlay.hpp
--- a/src/sculpted-overlay.hpp 2026-10-29 17:15:58.618080111 -0500
+++ b/src/sculpted-overlay.hpp 2026-10-29 17:22:15.195422699 -0500
@@ -19,6 +19,7 @@
layout(location = 9) uniform vec4 shadow_color;
layout(location = 10) uniform float border_depth;
layout(location = 11) uniform vec4 pinstripe_color;
+layout(location = 12) uniform int border_padding;
vec4 over(vec4 base, vec4 tint)
{
@@ -62,7 +63,11 @@
body.rgb *= body.a;
float inset = max(0.0, -d);
float strength = clamp(border_depth, 0.0, 1.0) / 0.65;
- float falloff = border > 0.0 ? clamp(1.0 - inset / border, 0.0, 1.0) : 0.0;
+ // Inner padding: the bevel ends border_padding pixels before the application and
+ // leaves flat frame there, closed by a bead at the application edge.
+ float padding = clamp(float(border_padding), 0.0, max(0.0, border - 1.0));
+ float ramp = border - padding;
+ float falloff = ramp > 0.0 ? clamp(1.0 - inset / ramp, 0.0, 1.0) : 0.0;
vec2 outward = p - clamp(p, lo + radius, hi - radius);
if (dot(outward, outward) < 0.0001)
{
@@ -75,6 +80,29 @@
float shade = max(outward.y, 0.0) * 0.500 + max(outward.x, 0.0) * 0.160;
body = over(body, vec4(1.0, 1.0, 1.0, clamp(light * strength * falloff, 0.0, 1.0)));
body = over(body, vec4(0.0, 0.0, 0.0, clamp(shade * strength * falloff, 0.0, 1.0)));
+ if (padding >= 1.0)
+ {
+ // A rounded bead closes the padding at the application edge, lit from the top
+ // left like the bevel: each side shows one light and one dark pixel, so the
+ // edge stays visible against light and dark applications alike.
+ vec2 well_lo = vec2(float(border_size), float(title_height));
+ vec2 well_hi = vec2(float(width - border_size), float(height - border_size));
+ vec2 from_well = p - clamp(p, well_lo, well_hi);
+ float gap = length(from_well);
+ float bead = min(padding, 2.0);
+ if (gap < bead)
+ {
+ vec2 n = from_well / max(gap, 0.0001);
+ // Facing of this pixel's half of the bead: outward on the outer pixel,
+ // inward on the inner one. A one-pixel bead keeps only the inward half.
+ vec2 facing = (bead >= 2.0 && gap >= 1.0) ? n : -n;
+ float lit = dot(facing, normalize(vec2(-0.35, -1.0)));
+ float bead_light = max(lit, 0.0) * 0.200;
+ float bead_shade = max(-lit, 0.0) * 0.380;
+ body = over(body, vec4(1.0, 1.0, 1.0, clamp(bead_light * strength, 0.0, 1.0)));
+ body = over(body, vec4(0.0, 0.0, 0.0, clamp(bead_shade * strength, 0.0, 1.0)));
+ }
+ }
vec4 rim = pinstripe_color;
rim.a *= 1.0 - smoothstep(0.5, 1.5, inset);
body = over(body, rim);
|