detached 0647966

refactor(vulkan): share fillRounded between hint, inner border and ring

commit
06479663a2cc197a631e6954c1b2cc9e67eb890c
author
brice · · 2026-10-21 08:22 UTC
parent
038e199
signature
GPG VerifiedCD88F9E564E0102646FB6077A1A07C7C7C3E349D · arch-gpg Verified for the committer email
2 files · +19 -17
M internal/adapters/vulkan/position_hint.go +1 -6
@@ -42,10 +42,5 @@ func (w *sceneWalk) positionHint() {
4242 // so alpha stays exact.
4343 func (w *sceneWalk) hintRound(r image.Rectangle, radius int, color [3]uint8) {
4444 radius = min(radius, r.Dx()/2, r.Dy()/2)
45- n := len(w.draws)
46- w.fill(r, color)
47- if radius <= 0 || len(w.draws) == n {
48- return
49- }
50- roundedDraw(&w.draws[n], r, float32(radius))
45+ w.fillRounded(r, color, float32(radius))
5146 }
@@ -42,10 +42,5 @@ func (w *sceneWalk) positionHint() {
42 // so alpha stays exact.42 // so alpha stays exact.
43 func (w *sceneWalk) hintRound(r image.Rectangle, radius int, color [3]uint8) {43 func (w *sceneWalk) hintRound(r image.Rectangle, radius int, color [3]uint8) {
44 radius = min(radius, r.Dx()/2, r.Dy()/2)44 radius = min(radius, r.Dx()/2, r.Dy()/2)
45- n := len(w.draws)45+ w.fillRounded(r, color, float32(radius))
46- w.fill(r, color)
47- if radius <= 0 || len(w.draws) == n {
48- return
49- }
50- roundedDraw(&w.draws[n], r, float32(radius))
51 }46 }
M internal/adapters/vulkan/scene.go +18 -11
@@ -92,14 +92,11 @@ func (w *sceneWalk) focusFlash() {
9292 // radius, minus a hole inset by b with radius max(radius-b, 0).
9393 func (w *sceneWalk) roundedInnerBorder(t ports.Rect, b, radius int, col [3]uint8) {
9494 outer := w.physRect(t.X, t.Y, t.W, t.H)
95- n := len(w.draws)
96- w.fill(outer, col)
97- if len(w.draws) == n {
95+ r := float32(math.Round(float64(radius) * w.scale))
96+ dr := w.fillRounded(outer, col, r)
97+ if dr == nil {
9898 return
9999 }
100- r := float32(math.Round(float64(radius) * w.scale))
101- dr := &w.draws[n]
102- roundedDraw(dr, outer, r)
103100 dr.pc.misc[1] |= flagRing
104101 hole := w.physRect(t.X+b, t.Y+b, t.W-2*b, t.H-2*b)
105102 bPhys := min(hole.Min.X-outer.Min.X, hole.Min.Y-outer.Min.Y, outer.Max.X-hole.Max.X, outer.Max.Y-hole.Max.Y)
@@ -196,6 +193,20 @@ func (w *sceneWalk) fill(rect image.Rectangle, c [3]uint8) {
196193 w.draws = append(w.draws, dr)
197194 }
198195
196+// fillRounded is fill with rounded corners of radius (physical pixels). It
197+// returns the new draw, or nil when fill emitted nothing or radius <= 0 (the
198+// plain fill is kept). The pointer is valid only until the next append.
199+func (w *sceneWalk) fillRounded(r image.Rectangle, c [3]uint8, radius float32) *draw {
200+ n := len(w.draws)
201+ w.fill(r, c)
202+ if len(w.draws) == n || radius <= 0 {
203+ return nil
204+ }
205+ dr := &w.draws[n]
206+ roundedDraw(dr, r, radius)
207+ return dr
208+}
209+
199210 // dim paints a translucent black quad over rect (physical), clipped to the
200211 // output, at alpha scaled by the walk's alpha. Damage clipping later limits
201212 // it to the region being repainted, just like other fills.
@@ -293,11 +304,7 @@ func (w *sceneWalk) windows() {
293304 bPhys := min(body.Min.X-outer.Min.X, body.Min.Y-outer.Min.Y, outer.Max.X-body.Max.X, outer.Max.Y-body.Max.Y)
294305 innerRadius = max(radius-float32(max(bPhys, 0)), 0)
295306 if col := w.ringColor(win.ID); col != "" && b > 0 {
296- n := len(w.draws)
297- w.fill(outer, parseColor(col))
298- if len(w.draws) > n {
299- dr := &w.draws[n]
300- roundedDraw(dr, outer, radius)
307+ if dr := w.fillRounded(outer, parseColor(col), radius); dr != nil {
301308 dr.pc.misc[1] |= flagRing
302309 // Opaque, the ring runs 1px under the body so no seam
303310 // shows; faded, that overlap would double up: the hole
@@ -92,14 +92,11 @@ func (w *sceneWalk) focusFlash() {
92 // radius, minus a hole inset by b with radius max(radius-b, 0).92 // radius, minus a hole inset by b with radius max(radius-b, 0).
93 func (w *sceneWalk) roundedInnerBorder(t ports.Rect, b, radius int, col [3]uint8) {93 func (w *sceneWalk) roundedInnerBorder(t ports.Rect, b, radius int, col [3]uint8) {
94 outer := w.physRect(t.X, t.Y, t.W, t.H)94 outer := w.physRect(t.X, t.Y, t.W, t.H)
95- n := len(w.draws)95+ r := float32(math.Round(float64(radius) * w.scale))
96- w.fill(outer, col)96+ dr := w.fillRounded(outer, col, r)
97- if len(w.draws) == n {97+ if dr == nil {
98 return98 return
99 }99 }
100- r := float32(math.Round(float64(radius) * w.scale))
101- dr := &w.draws[n]
102- roundedDraw(dr, outer, r)
103 dr.pc.misc[1] |= flagRing100 dr.pc.misc[1] |= flagRing
104 hole := w.physRect(t.X+b, t.Y+b, t.W-2*b, t.H-2*b)101 hole := w.physRect(t.X+b, t.Y+b, t.W-2*b, t.H-2*b)
105 bPhys := min(hole.Min.X-outer.Min.X, hole.Min.Y-outer.Min.Y, outer.Max.X-hole.Max.X, outer.Max.Y-hole.Max.Y)102 bPhys := min(hole.Min.X-outer.Min.X, hole.Min.Y-outer.Min.Y, outer.Max.X-hole.Max.X, outer.Max.Y-hole.Max.Y)
@@ -196,6 +193,20 @@ func (w *sceneWalk) fill(rect image.Rectangle, c [3]uint8) {
196 w.draws = append(w.draws, dr)193 w.draws = append(w.draws, dr)
197 }194 }
198 195
196+// fillRounded is fill with rounded corners of radius (physical pixels). It
197+// returns the new draw, or nil when fill emitted nothing or radius <= 0 (the
198+// plain fill is kept). The pointer is valid only until the next append.
199+func (w *sceneWalk) fillRounded(r image.Rectangle, c [3]uint8, radius float32) *draw {
200+ n := len(w.draws)
201+ w.fill(r, c)
202+ if len(w.draws) == n || radius <= 0 {
203+ return nil
204+ }
205+ dr := &w.draws[n]
206+ roundedDraw(dr, r, radius)
207+ return dr
208+}
209+
199 // dim paints a translucent black quad over rect (physical), clipped to the210 // dim paints a translucent black quad over rect (physical), clipped to the
200 // output, at alpha scaled by the walk's alpha. Damage clipping later limits211 // output, at alpha scaled by the walk's alpha. Damage clipping later limits
201 // it to the region being repainted, just like other fills.212 // it to the region being repainted, just like other fills.
@@ -293,11 +304,7 @@ func (w *sceneWalk) windows() {
293 bPhys := min(body.Min.X-outer.Min.X, body.Min.Y-outer.Min.Y, outer.Max.X-body.Max.X, outer.Max.Y-body.Max.Y)304 bPhys := min(body.Min.X-outer.Min.X, body.Min.Y-outer.Min.Y, outer.Max.X-body.Max.X, outer.Max.Y-body.Max.Y)
294 innerRadius = max(radius-float32(max(bPhys, 0)), 0)305 innerRadius = max(radius-float32(max(bPhys, 0)), 0)
295 if col := w.ringColor(win.ID); col != "" && b > 0 {306 if col := w.ringColor(win.ID); col != "" && b > 0 {
296- n := len(w.draws)307+ if dr := w.fillRounded(outer, parseColor(col), radius); dr != nil {
297- w.fill(outer, parseColor(col))
298- if len(w.draws) > n {
299- dr := &w.draws[n]
300- roundedDraw(dr, outer, radius)
301 dr.pc.misc[1] |= flagRing308 dr.pc.misc[1] |= flagRing
302 // Opaque, the ring runs 1px under the body so no seam309 // Opaque, the ring runs 1px under the body so no seam
303 // shows; faded, that overlap would double up: the hole310 // shows; faded, that overlap would double up: the hole

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 25

Tags 10

↑↓ moveenter openesc close