detached fc1ff4f

fix(layout): preserve live-paint allocation budget

commit
fc1ff4f514e5bdec27989d0347183ceb4084d522
author
brice · · 2026-07-24 15:12 UTC
committer
brice · · 2026-07-25 04:08 UTC
parent
44c9bd0
signature
GPG VerifiedCD88F9E564E0102646FB6077A1A07C7C7C3E349D · arch-gpg Verified for the committer email
2 files · +9 -11
M internal/app/transport_observability_test.go +1 -0
@@ -203,6 +203,7 @@ type runtimeObserverFunc func(ports.RuntimeMark)
203203 func (f runtimeObserverFunc) ObserveRuntime(mark ports.RuntimeMark) { f(mark) }
204204
205205 func TestRunAttachPropagatesOneObserverToRemoteTransportFactory(t *testing.T) {
206+ t.Setenv("VEV", "")
206207 t.Setenv("XDG_STATE_HOME", t.TempDir())
207208 t.Setenv("XDG_RUNTIME_DIR", t.TempDir())
208209 t.Setenv(envRemoteTransport, string(ports.RemoteTransportStdio))
@@ -203,6 +203,7 @@ type runtimeObserverFunc func(ports.RuntimeMark)
203 func (f runtimeObserverFunc) ObserveRuntime(mark ports.RuntimeMark) { f(mark) }203 func (f runtimeObserverFunc) ObserveRuntime(mark ports.RuntimeMark) { f(mark) }
204 204
205 func TestRunAttachPropagatesOneObserverToRemoteTransportFactory(t *testing.T) {205 func TestRunAttachPropagatesOneObserverToRemoteTransportFactory(t *testing.T) {
206+ t.Setenv("VEV", "")
206 t.Setenv("XDG_STATE_HOME", t.TempDir())207 t.Setenv("XDG_STATE_HOME", t.TempDir())
207 t.Setenv("XDG_RUNTIME_DIR", t.TempDir())208 t.Setenv("XDG_RUNTIME_DIR", t.TempDir())
208 t.Setenv(envRemoteTransport, string(ports.RemoteTransportStdio))209 t.Setenv(envRemoteTransport, string(ports.RemoteTransportStdio))
M internal/usecase/layout/geometry.go +8 -11
@@ -185,13 +185,13 @@ func distribute(total int, minimums []int, weights []float64) ([]int, bool) {
185185 remaining := total
186186
187187 for {
188- normalized, sum := normalizedActiveWeights(weights, active)
188+ largest, sum := activeWeightScale(weights, active)
189189 var pinned []int
190190 for i := range active {
191191 if !active[i] {
192192 continue
193193 }
194- quota := float64(remaining) * normalized[i] / sum
194+ quota := float64(remaining) * (effectiveWeight(weights[i]) / largest) / sum
195195 if quota < float64(minimums[i]) {
196196 pinned = append(pinned, i)
197197 }
@@ -206,7 +206,7 @@ func distribute(total int, minimums []int, weights []float64) ([]int, bool) {
206206 }
207207 }
208208
209- normalized, sum := normalizedActiveWeights(weights, active)
209+ largest, sum := activeWeightScale(weights, active)
210210 type remainder struct {
211211 index int
212212 fraction float64
@@ -217,7 +217,7 @@ func distribute(total int, minimums []int, weights []float64) ([]int, bool) {
217217 if !active[i] {
218218 continue
219219 }
220- quota := float64(remaining) * normalized[i] / sum
220+ quota := float64(remaining) * (effectiveWeight(weights[i]) / largest) / sum
221221 whole := int(math.Floor(quota))
222222 allocations[i] = whole
223223 allocated += whole
@@ -232,23 +232,20 @@ func distribute(total int, minimums []int, weights []float64) ([]int, bool) {
232232 return allocations, true
233233 }
234234
235-func normalizedActiveWeights(weights []float64, active []bool) ([]float64, float64) {
235+func activeWeightScale(weights []float64, active []bool) (float64, float64) {
236236 largest := 0.0
237237 for i, weight := range weights {
238238 if active[i] {
239239 largest = math.Max(largest, effectiveWeight(weight))
240240 }
241241 }
242- normalized := make([]float64, len(weights))
243242 sum := 0.0
244243 for i, weight := range weights {
245- if !active[i] {
246- continue
244+ if active[i] {
245+ sum += effectiveWeight(weight) / largest
247246 }
248- normalized[i] = effectiveWeight(weight) / largest
249- sum += normalized[i]
250247 }
251- return normalized, sum
248+ return largest, sum
252249 }
253250
254251 func solveStack(n *Node, r domain.Rect, out *[]Placement) bool {
@@ -185,13 +185,13 @@ func distribute(total int, minimums []int, weights []float64) ([]int, bool) {
185 remaining := total185 remaining := total
186 186
187 for {187 for {
188- normalized, sum := normalizedActiveWeights(weights, active)188+ largest, sum := activeWeightScale(weights, active)
189 var pinned []int189 var pinned []int
190 for i := range active {190 for i := range active {
191 if !active[i] {191 if !active[i] {
192 continue192 continue
193 }193 }
194- quota := float64(remaining) * normalized[i] / sum194+ quota := float64(remaining) * (effectiveWeight(weights[i]) / largest) / sum
195 if quota < float64(minimums[i]) {195 if quota < float64(minimums[i]) {
196 pinned = append(pinned, i)196 pinned = append(pinned, i)
197 }197 }
@@ -206,7 +206,7 @@ func distribute(total int, minimums []int, weights []float64) ([]int, bool) {
206 }206 }
207 }207 }
208 208
209- normalized, sum := normalizedActiveWeights(weights, active)209+ largest, sum := activeWeightScale(weights, active)
210 type remainder struct {210 type remainder struct {
211 index int211 index int
212 fraction float64212 fraction float64
@@ -217,7 +217,7 @@ func distribute(total int, minimums []int, weights []float64) ([]int, bool) {
217 if !active[i] {217 if !active[i] {
218 continue218 continue
219 }219 }
220- quota := float64(remaining) * normalized[i] / sum220+ quota := float64(remaining) * (effectiveWeight(weights[i]) / largest) / sum
221 whole := int(math.Floor(quota))221 whole := int(math.Floor(quota))
222 allocations[i] = whole222 allocations[i] = whole
223 allocated += whole223 allocated += whole
@@ -232,23 +232,20 @@ func distribute(total int, minimums []int, weights []float64) ([]int, bool) {
232 return allocations, true232 return allocations, true
233 }233 }
234 234
235-func normalizedActiveWeights(weights []float64, active []bool) ([]float64, float64) {235+func activeWeightScale(weights []float64, active []bool) (float64, float64) {
236 largest := 0.0236 largest := 0.0
237 for i, weight := range weights {237 for i, weight := range weights {
238 if active[i] {238 if active[i] {
239 largest = math.Max(largest, effectiveWeight(weight))239 largest = math.Max(largest, effectiveWeight(weight))
240 }240 }
241 }241 }
242- normalized := make([]float64, len(weights))
243 sum := 0.0242 sum := 0.0
244 for i, weight := range weights {243 for i, weight := range weights {
245- if !active[i] {244+ if active[i] {
246- continue245+ sum += effectiveWeight(weight) / largest
247 }246 }
248- normalized[i] = effectiveWeight(weight) / largest
249- sum += normalized[i]
250 }247 }
251- return normalized, sum248+ return largest, sum
252 }249 }
253 250
254 func solveStack(n *Node, r domain.Rect, out *[]Placement) bool {251 func solveStack(n *Node, r domain.Rect, out *[]Placement) bool {

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 12

Tags 11

↑↓ moveenter openesc close