perf(core): drop the veil at once when a float closes or hides
The veil under a leaving float faded with it, which changed Scene.Dim on every frame of the fade and forced a full redraw of the output for about 300 ms, where the float's own fade redraws only its rect. floatDim now ignores leaving floats: the veil goes when the float starts to leave. Deliberate spec change (C0 pinned the fading veil): the veil vanishing at once is acceptable visually and restores partial redraws during float close and stash hide. publish keeps a leaving window's configure only when its workspace still holds it (a hidden stash window), as the comment always said; a closed one stays forgotten.
- commit
- 512d7fcf140f045de6467300cbef4a99887a9df4
- author
- brice · · 2026-10-05 02:45 UTC
- parent
- 724a3a0
- signature
- GPG Verified
CD88F9E564E0102646FB6077A1A07C7C7C3E349D· arch-gpg Verified for the committer email
2 files · +31 -32
M internal/core/core.go +14 -15
| @@ -424,24 +424,20 @@ func onScreen(p Placement, o Rect) bool { | |||
| 424 | 424 | ||
| 425 | 425 | // floatDim is the veil opacity of a layout: dim only when a float is | |
| 426 | 426 | // drawn above the tiles, never for a demoted covering float alone nor for | |
| 427 | - | // an overview preview. | |
| 428 | - | // A leaving float (fading out after it closed or hid) keeps the veil, | |
| 429 | - | // scaled by what is left of it, so the veil fades with the last float. | |
| 427 | + | // an overview preview. A leaving float (fading out after it closed or hid) | |
| 428 | + | // drops the veil at once: a veil that fades changes Scene.Dim every frame, | |
| 429 | + | // which redraws the whole output for the length of the fade, where the | |
| 430 | + | // float's own fade redraws only its rect. | |
| 430 | 431 | func floatDim(layout []Placement, o Rect, dim float64) float64 { | |
| 431 | - | k := 0.0 | |
| 432 | 432 | for _, p := range layout { | |
| 433 | - | if p.Floating && !p.Below && p.Preview == 0 && (onScreen(p, o) || p.Leaving && p.Rect.Overlaps(o)) { | |
| 433 | + | if p.Floating && !p.Below && p.Preview == 0 && onScreen(p, o) { | |
| 434 | 434 | if p.Fullscreen { | |
| 435 | 435 | return 0 | |
| 436 | 436 | } | |
| 437 | - | if p.Leaving { | |
| 438 | - | k = max(k, 1-p.Fade) | |
| 439 | - | } else { | |
| 440 | - | k = 1 | |
| 441 | - | } | |
| 437 | + | return dim | |
| 442 | 438 | } | |
| 443 | 439 | } | |
| 444 | - | return dim * k | |
| 440 | + | return 0 | |
| 445 | 441 | } | |
| 446 | 442 | ||
| 447 | 443 | // visible reports whether the window, layer surface or popup is on screen | |
| @@ -636,10 +632,13 @@ func (c *Core) publishFrame(ctx context.Context, only *screen) error { | |||
| 636 | 632 | // hidden to everything else, its configures included. | |
| 637 | 633 | sw.Hidden = false | |
| 638 | 634 | scene.Windows = append(scene.Windows, sw) | |
| 639 | - | // A window the layout still holds keeps its last configure | |
| 640 | - | // (prune would forget it, and its next one would start from | |
| 641 | - | // nothing). | |
| 642 | - | c.configures.keep(p.ID) | |
| 635 | + | // A window the workspace still holds (a hidden stash | |
| 636 | + | // window) keeps its last configure: prune would forget it, | |
| 637 | + | // and its next one would start from nothing. A closed one | |
| 638 | + | // was forgotten at its unmap and stays so. | |
| 639 | + | if w, _ := sc.mon.find(p.ID); w != nil { | |
| 640 | + | c.configures.keep(p.ID) | |
| 641 | + | } | |
| 643 | 642 | continue | |
| 644 | 643 | } | |
| 645 | 644 | if focused && p.ID == c.pulse.target && !alone && !p.Fullscreen && !p.Hidden && p.Preview == 0 && !sc.mon.ov.open { | |
| @@ -424,24 +424,20 @@ func onScreen(p Placement, o Rect) bool { | |||||
| 424 | 424 | ||||
| 425 | // floatDim is the veil opacity of a layout: dim only when a float is | 425 | // floatDim is the veil opacity of a layout: dim only when a float is | ||
| 426 | // drawn above the tiles, never for a demoted covering float alone nor for | 426 | // drawn above the tiles, never for a demoted covering float alone nor for | ||
| 427 | - | // an overview preview. | 427 | + | // an overview preview. A leaving float (fading out after it closed or hid) |
| 428 | - | // A leaving float (fading out after it closed or hid) keeps the veil, | 428 | + | // drops the veil at once: a veil that fades changes Scene.Dim every frame, |
| 429 | - | // scaled by what is left of it, so the veil fades with the last float. | 429 | + | // which redraws the whole output for the length of the fade, where the |
| 430 | + | // float's own fade redraws only its rect. | |||
| 430 | func floatDim(layout []Placement, o Rect, dim float64) float64 { | 431 | func floatDim(layout []Placement, o Rect, dim float64) float64 { | ||
| 431 | - | k := 0.0 | |||
| 432 | for _, p := range layout { | 432 | for _, p := range layout { | ||
| 433 | - | if p.Floating && !p.Below && p.Preview == 0 && (onScreen(p, o) || p.Leaving && p.Rect.Overlaps(o)) { | 433 | + | if p.Floating && !p.Below && p.Preview == 0 && onScreen(p, o) { |
| 434 | if p.Fullscreen { | 434 | if p.Fullscreen { | ||
| 435 | return 0 | 435 | return 0 | ||
| 436 | } | 436 | } | ||
| 437 | - | if p.Leaving { | 437 | + | return dim |
| 438 | - | k = max(k, 1-p.Fade) | |||
| 439 | - | } else { | |||
| 440 | - | k = 1 | |||
| 441 | - | } | |||
| 442 | } | 438 | } | ||
| 443 | } | 439 | } | ||
| 444 | - | return dim * k | 440 | + | return 0 |
| 445 | } | 441 | } | ||
| 446 | 442 | ||||
| 447 | // visible reports whether the window, layer surface or popup is on screen | 443 | // visible reports whether the window, layer surface or popup is on screen | ||
| @@ -636,10 +632,13 @@ func (c *Core) publishFrame(ctx context.Context, only *screen) error { | |||||
| 636 | // hidden to everything else, its configures included. | 632 | // hidden to everything else, its configures included. | ||
| 637 | sw.Hidden = false | 633 | sw.Hidden = false | ||
| 638 | scene.Windows = append(scene.Windows, sw) | 634 | scene.Windows = append(scene.Windows, sw) | ||
| 639 | - | // A window the layout still holds keeps its last configure | 635 | + | // A window the workspace still holds (a hidden stash |
| 640 | - | // (prune would forget it, and its next one would start from | 636 | + | // window) keeps its last configure: prune would forget it, |
| 641 | - | // nothing). | 637 | + | // and its next one would start from nothing. A closed one |
| 642 | - | c.configures.keep(p.ID) | 638 | + | // was forgotten at its unmap and stays so. |
| 639 | + | if w, _ := sc.mon.find(p.ID); w != nil { | |||
| 640 | + | c.configures.keep(p.ID) | |||
| 641 | + | } | |||
| 643 | continue | 642 | continue | ||
| 644 | } | 643 | } | ||
| 645 | if focused && p.ID == c.pulse.target && !alone && !p.Fullscreen && !p.Hidden && p.Preview == 0 && !sc.mon.ov.open { | 644 | if focused && p.ID == c.pulse.target && !alone && !p.Fullscreen && !p.Hidden && p.Preview == 0 && !sc.mon.ov.open { | ||
M internal/core/transition_fade_internal_test.go +17 -17
| @@ -41,7 +41,7 @@ func TestAppearDerivesFadeAndZoom(t *testing.T) { | |||
| 41 | 41 | drainConfigures(cmds) | |
| 42 | 42 | settled := sc.settledLayout[slices.IndexFunc(sc.settledLayout, func(p Placement) bool { return p.ID == 2 })] | |
| 43 | 43 | ||
| 44 | - | c.appear(sc, 2, ic.now) | |
| 44 | + | c.appearAt(sc, settledOf(t, sc, 2), ic.now) | |
| 45 | 45 | s := indicatorScene(t, c) | |
| 46 | 46 | w := sceneWindow(t, s, 2) | |
| 47 | 47 | if w.Fade != 1 || w.Hidden { | |
| @@ -98,7 +98,7 @@ func TestAppearOffIsInstant(t *testing.T) { | |||
| 98 | 98 | sc := c.cur() | |
| 99 | 99 | sc.mon.AddWindow(1) | |
| 100 | 100 | settleShown(t, c) | |
| 101 | - | c.appear(sc, 1, ic.now) | |
| 101 | + | c.appearAt(sc, settledOf(t, sc, 1), ic.now) | |
| 102 | 102 | if len(sc.rects) != 0 || c.animating() { | |
| 103 | 103 | t.Fatal("appear started a motion with animations off") | |
| 104 | 104 | } | |
| @@ -122,7 +122,7 @@ func TestLeavingEntryLifecycle(t *testing.T) { | |||
| 122 | 122 | ||
| 123 | 123 | // Close window 2: the layout re-flows; its last placement leaves. | |
| 124 | 124 | sc.mon.RemoveWindow(2) | |
| 125 | - | c.leave(sc, left, ic.now) | |
| 125 | + | c.leaveFrom(sc, left, nil, ic.now) | |
| 126 | 126 | s := indicatorScene(t, c) | |
| 127 | 127 | if len(sc.settledLayout) != len(sc.shown) { | |
| 128 | 128 | t.Fatalf("settled %d and shown %d entries", len(sc.settledLayout), len(sc.shown)) | |
| @@ -188,7 +188,7 @@ func TestLeavingEntryDroppedWhenShownAgain(t *testing.T) { | |||
| 188 | 188 | settleShown(t, c) | |
| 189 | 189 | left := sc.settledLayout[1] | |
| 190 | 190 | sc.mon.RemoveWindow(2) | |
| 191 | - | c.leave(sc, left, ic.now) | |
| 191 | + | c.leaveFrom(sc, left, nil, ic.now) | |
| 192 | 192 | if s := indicatorScene(t, c); len(s.Windows) != 2 || !sc.shown[1].Leaving { | |
| 193 | 193 | t.Fatalf("no leaving entry: %+v", s.Windows) | |
| 194 | 194 | } | |
| @@ -219,7 +219,7 @@ func TestLeavingEntryDroppedByStopRects(t *testing.T) { | |||
| 219 | 219 | settleShown(t, c) | |
| 220 | 220 | left := sc.settledLayout[1] | |
| 221 | 221 | sc.mon.RemoveWindow(2) | |
| 222 | - | c.leave(sc, left, ic.now) | |
| 222 | + | c.leaveFrom(sc, left, nil, ic.now) | |
| 223 | 223 | if s := indicatorScene(t, c); len(s.Windows) != 2 { | |
| 224 | 224 | t.Fatalf("%d windows, want the tile and the leaving entry", len(s.Windows)) | |
| 225 | 225 | } | |
| @@ -238,7 +238,7 @@ func TestLeaveOffIsInstant(t *testing.T) { | |||
| 238 | 238 | settleShown(t, c) | |
| 239 | 239 | left := sc.settledLayout[0] | |
| 240 | 240 | sc.mon.RemoveWindow(1) | |
| 241 | - | c.leave(sc, left, ic.now) | |
| 241 | + | c.leaveFrom(sc, left, nil, ic.now) | |
| 242 | 242 | if s := indicatorScene(t, c); len(s.Windows) != 0 || len(sc.rects) != 0 { | |
| 243 | 243 | t.Fatalf("leaving entry with animations off: %+v", s.Windows) | |
| 244 | 244 | } | |
| @@ -302,7 +302,7 @@ func TestSnapshotSkipsLeavingEntries(t *testing.T) { | |||
| 302 | 302 | settleShown(t, c) | |
| 303 | 303 | left := sc.settledLayout[1] | |
| 304 | 304 | sc.mon.RemoveWindow(2) | |
| 305 | - | c.leave(sc, left, ic.now) | |
| 305 | + | c.leaveFrom(sc, left, nil, ic.now) | |
| 306 | 306 | settleShown(t, c) | |
| 307 | 307 | shots := c.snapshot(ic.now) | |
| 308 | 308 | if len(shots) != 1 || len(shots[0].rects) != 1 || shots[0].rects[0].id != 1 { | |
| @@ -331,7 +331,7 @@ func TestLeavingPaintOrder(t *testing.T) { | |||
| 331 | 331 | ||
| 332 | 332 | // Close the tile: its entry sits before the float. | |
| 333 | 333 | sc.mon.RemoveWindow(2) | |
| 334 | - | c.leave(sc, tile, ic.now) | |
| 334 | + | c.leaveFrom(sc, tile, nil, ic.now) | |
| 335 | 335 | s := indicatorScene(t, c) | |
| 336 | 336 | order := func(s ports.Scene) []WindowID { | |
| 337 | 337 | ids := make([]WindowID, 0, len(s.Windows)) | |
| @@ -352,23 +352,23 @@ func TestLeavingPaintOrder(t *testing.T) { | |||
| 352 | 352 | t.Fatalf("veil %v with the float still shown, want 0.4", s.Dim) | |
| 353 | 353 | } | |
| 354 | 354 | ||
| 355 | - | // Close the float too: its entry goes last and keeps the veil, which | |
| 356 | - | // fades with it. | |
| 355 | + | // Close the float too: its entry goes last, and the veil goes at | |
| 356 | + | // once (a fading veil would redraw the whole output every frame of | |
| 357 | + | // the fade; the float's own fade redraws only its rect). | |
| 357 | 358 | sc.mon.RemoveWindow(3) | |
| 358 | - | c.leave(sc, float, ic.now) | |
| 359 | + | c.leaveFrom(sc, float, nil, ic.now) | |
| 359 | 360 | s = indicatorScene(t, c) | |
| 360 | 361 | if got := order(s); !slices.Equal(got, []WindowID{1, 2, 3}) { | |
| 361 | 362 | t.Fatalf("order with a leaving float %v, want [1 2 3] (float last)", got) | |
| 362 | 363 | } | |
| 363 | - | if s.Dim != 0.4 { | |
| 364 | - | t.Fatalf("veil %v right after the float left, want 0.4", s.Dim) | |
| 364 | + | if s.Dim != 0 { | |
| 365 | + | t.Fatalf("veil %v right after the float left, want none", s.Dim) | |
| 365 | 366 | } | |
| 366 | 367 | ic.now = ic.now.Add(60 * time.Millisecond) | |
| 367 | 368 | c.animate(ic.now, nil) | |
| 368 | 369 | s = indicatorScene(t, c) | |
| 369 | - | f := sceneWindow(t, s, 3) | |
| 370 | - | if !(s.Dim > 0 && s.Dim < 0.4) || math.Abs(s.Dim-0.4*(1-f.Fade)) > 1e-9 { | |
| 371 | - | t.Fatalf("veil %v mid-fade (float fade %v), want 0.4*(1-fade)", s.Dim, f.Fade) | |
| 370 | + | if f := sceneWindow(t, s, 3); s.Dim != 0 || !(f.Fade > 0 && f.Fade < 1) { | |
| 371 | + | t.Fatalf("veil %v mid-fade (float fade %v), want none while the float fades", s.Dim, f.Fade) | |
| 372 | 372 | } | |
| 373 | 373 | ic.now = ic.now.Add(5 * time.Second) | |
| 374 | 374 | c.animate(ic.now, nil) | |
| @@ -386,7 +386,7 @@ func TestRetargetClearsScaleKeepsFade(t *testing.T) { | |||
| 386 | 386 | sc := c.cur() | |
| 387 | 387 | sc.mon.AddWindow(1) | |
| 388 | 388 | settleShown(t, c) | |
| 389 | - | c.appear(sc, 1, ic.now) | |
| 389 | + | c.appearAt(sc, settledOf(t, sc, 1), ic.now) | |
| 390 | 390 | settleShown(t, c) | |
| 391 | 391 | if rm := sc.rects[1]; !rm.scale || !rm.fade.on { | |
| 392 | 392 | t.Fatalf("setup: %+v", rm) | |
| @@ -41,7 +41,7 @@ func TestAppearDerivesFadeAndZoom(t *testing.T) { | |||||
| 41 | drainConfigures(cmds) | 41 | drainConfigures(cmds) | ||
| 42 | settled := sc.settledLayout[slices.IndexFunc(sc.settledLayout, func(p Placement) bool { return p.ID == 2 })] | 42 | settled := sc.settledLayout[slices.IndexFunc(sc.settledLayout, func(p Placement) bool { return p.ID == 2 })] | ||
| 43 | 43 | ||||
| 44 | - | c.appear(sc, 2, ic.now) | 44 | + | c.appearAt(sc, settledOf(t, sc, 2), ic.now) |
| 45 | s := indicatorScene(t, c) | 45 | s := indicatorScene(t, c) | ||
| 46 | w := sceneWindow(t, s, 2) | 46 | w := sceneWindow(t, s, 2) | ||
| 47 | if w.Fade != 1 || w.Hidden { | 47 | if w.Fade != 1 || w.Hidden { | ||
| @@ -98,7 +98,7 @@ func TestAppearOffIsInstant(t *testing.T) { | |||||
| 98 | sc := c.cur() | 98 | sc := c.cur() | ||
| 99 | sc.mon.AddWindow(1) | 99 | sc.mon.AddWindow(1) | ||
| 100 | settleShown(t, c) | 100 | settleShown(t, c) | ||
| 101 | - | c.appear(sc, 1, ic.now) | 101 | + | c.appearAt(sc, settledOf(t, sc, 1), ic.now) |
| 102 | if len(sc.rects) != 0 || c.animating() { | 102 | if len(sc.rects) != 0 || c.animating() { | ||
| 103 | t.Fatal("appear started a motion with animations off") | 103 | t.Fatal("appear started a motion with animations off") | ||
| 104 | } | 104 | } | ||
| @@ -122,7 +122,7 @@ func TestLeavingEntryLifecycle(t *testing.T) { | |||||
| 122 | 122 | ||||
| 123 | // Close window 2: the layout re-flows; its last placement leaves. | 123 | // Close window 2: the layout re-flows; its last placement leaves. | ||
| 124 | sc.mon.RemoveWindow(2) | 124 | sc.mon.RemoveWindow(2) | ||
| 125 | - | c.leave(sc, left, ic.now) | 125 | + | c.leaveFrom(sc, left, nil, ic.now) |
| 126 | s := indicatorScene(t, c) | 126 | s := indicatorScene(t, c) | ||
| 127 | if len(sc.settledLayout) != len(sc.shown) { | 127 | if len(sc.settledLayout) != len(sc.shown) { | ||
| 128 | t.Fatalf("settled %d and shown %d entries", len(sc.settledLayout), len(sc.shown)) | 128 | t.Fatalf("settled %d and shown %d entries", len(sc.settledLayout), len(sc.shown)) | ||
| @@ -188,7 +188,7 @@ func TestLeavingEntryDroppedWhenShownAgain(t *testing.T) { | |||||
| 188 | settleShown(t, c) | 188 | settleShown(t, c) | ||
| 189 | left := sc.settledLayout[1] | 189 | left := sc.settledLayout[1] | ||
| 190 | sc.mon.RemoveWindow(2) | 190 | sc.mon.RemoveWindow(2) | ||
| 191 | - | c.leave(sc, left, ic.now) | 191 | + | c.leaveFrom(sc, left, nil, ic.now) |
| 192 | if s := indicatorScene(t, c); len(s.Windows) != 2 || !sc.shown[1].Leaving { | 192 | if s := indicatorScene(t, c); len(s.Windows) != 2 || !sc.shown[1].Leaving { | ||
| 193 | t.Fatalf("no leaving entry: %+v", s.Windows) | 193 | t.Fatalf("no leaving entry: %+v", s.Windows) | ||
| 194 | } | 194 | } | ||
| @@ -219,7 +219,7 @@ func TestLeavingEntryDroppedByStopRects(t *testing.T) { | |||||
| 219 | settleShown(t, c) | 219 | settleShown(t, c) | ||
| 220 | left := sc.settledLayout[1] | 220 | left := sc.settledLayout[1] | ||
| 221 | sc.mon.RemoveWindow(2) | 221 | sc.mon.RemoveWindow(2) | ||
| 222 | - | c.leave(sc, left, ic.now) | 222 | + | c.leaveFrom(sc, left, nil, ic.now) |
| 223 | if s := indicatorScene(t, c); len(s.Windows) != 2 { | 223 | if s := indicatorScene(t, c); len(s.Windows) != 2 { | ||
| 224 | t.Fatalf("%d windows, want the tile and the leaving entry", len(s.Windows)) | 224 | t.Fatalf("%d windows, want the tile and the leaving entry", len(s.Windows)) | ||
| 225 | } | 225 | } | ||
| @@ -238,7 +238,7 @@ func TestLeaveOffIsInstant(t *testing.T) { | |||||
| 238 | settleShown(t, c) | 238 | settleShown(t, c) | ||
| 239 | left := sc.settledLayout[0] | 239 | left := sc.settledLayout[0] | ||
| 240 | sc.mon.RemoveWindow(1) | 240 | sc.mon.RemoveWindow(1) | ||
| 241 | - | c.leave(sc, left, ic.now) | 241 | + | c.leaveFrom(sc, left, nil, ic.now) |
| 242 | if s := indicatorScene(t, c); len(s.Windows) != 0 || len(sc.rects) != 0 { | 242 | if s := indicatorScene(t, c); len(s.Windows) != 0 || len(sc.rects) != 0 { | ||
| 243 | t.Fatalf("leaving entry with animations off: %+v", s.Windows) | 243 | t.Fatalf("leaving entry with animations off: %+v", s.Windows) | ||
| 244 | } | 244 | } | ||
| @@ -302,7 +302,7 @@ func TestSnapshotSkipsLeavingEntries(t *testing.T) { | |||||
| 302 | settleShown(t, c) | 302 | settleShown(t, c) | ||
| 303 | left := sc.settledLayout[1] | 303 | left := sc.settledLayout[1] | ||
| 304 | sc.mon.RemoveWindow(2) | 304 | sc.mon.RemoveWindow(2) | ||
| 305 | - | c.leave(sc, left, ic.now) | 305 | + | c.leaveFrom(sc, left, nil, ic.now) |
| 306 | settleShown(t, c) | 306 | settleShown(t, c) | ||
| 307 | shots := c.snapshot(ic.now) | 307 | shots := c.snapshot(ic.now) | ||
| 308 | if len(shots) != 1 || len(shots[0].rects) != 1 || shots[0].rects[0].id != 1 { | 308 | if len(shots) != 1 || len(shots[0].rects) != 1 || shots[0].rects[0].id != 1 { | ||
| @@ -331,7 +331,7 @@ func TestLeavingPaintOrder(t *testing.T) { | |||||
| 331 | 331 | ||||
| 332 | // Close the tile: its entry sits before the float. | 332 | // Close the tile: its entry sits before the float. | ||
| 333 | sc.mon.RemoveWindow(2) | 333 | sc.mon.RemoveWindow(2) | ||
| 334 | - | c.leave(sc, tile, ic.now) | 334 | + | c.leaveFrom(sc, tile, nil, ic.now) |
| 335 | s := indicatorScene(t, c) | 335 | s := indicatorScene(t, c) | ||
| 336 | order := func(s ports.Scene) []WindowID { | 336 | order := func(s ports.Scene) []WindowID { | ||
| 337 | ids := make([]WindowID, 0, len(s.Windows)) | 337 | ids := make([]WindowID, 0, len(s.Windows)) | ||
| @@ -352,23 +352,23 @@ func TestLeavingPaintOrder(t *testing.T) { | |||||
| 352 | t.Fatalf("veil %v with the float still shown, want 0.4", s.Dim) | 352 | t.Fatalf("veil %v with the float still shown, want 0.4", s.Dim) | ||
| 353 | } | 353 | } | ||
| 354 | 354 | ||||
| 355 | - | // Close the float too: its entry goes last and keeps the veil, which | 355 | + | // Close the float too: its entry goes last, and the veil goes at |
| 356 | - | // fades with it. | 356 | + | // once (a fading veil would redraw the whole output every frame of |
| 357 | + | // the fade; the float's own fade redraws only its rect). | |||
| 357 | sc.mon.RemoveWindow(3) | 358 | sc.mon.RemoveWindow(3) | ||
| 358 | - | c.leave(sc, float, ic.now) | 359 | + | c.leaveFrom(sc, float, nil, ic.now) |
| 359 | s = indicatorScene(t, c) | 360 | s = indicatorScene(t, c) | ||
| 360 | if got := order(s); !slices.Equal(got, []WindowID{1, 2, 3}) { | 361 | if got := order(s); !slices.Equal(got, []WindowID{1, 2, 3}) { | ||
| 361 | t.Fatalf("order with a leaving float %v, want [1 2 3] (float last)", got) | 362 | t.Fatalf("order with a leaving float %v, want [1 2 3] (float last)", got) | ||
| 362 | } | 363 | } | ||
| 363 | - | if s.Dim != 0.4 { | 364 | + | if s.Dim != 0 { |
| 364 | - | t.Fatalf("veil %v right after the float left, want 0.4", s.Dim) | 365 | + | t.Fatalf("veil %v right after the float left, want none", s.Dim) |
| 365 | } | 366 | } | ||
| 366 | ic.now = ic.now.Add(60 * time.Millisecond) | 367 | ic.now = ic.now.Add(60 * time.Millisecond) | ||
| 367 | c.animate(ic.now, nil) | 368 | c.animate(ic.now, nil) | ||
| 368 | s = indicatorScene(t, c) | 369 | s = indicatorScene(t, c) | ||
| 369 | - | f := sceneWindow(t, s, 3) | 370 | + | if f := sceneWindow(t, s, 3); s.Dim != 0 || !(f.Fade > 0 && f.Fade < 1) { |
| 370 | - | if !(s.Dim > 0 && s.Dim < 0.4) || math.Abs(s.Dim-0.4*(1-f.Fade)) > 1e-9 { | 371 | + | t.Fatalf("veil %v mid-fade (float fade %v), want none while the float fades", s.Dim, f.Fade) |
| 371 | - | t.Fatalf("veil %v mid-fade (float fade %v), want 0.4*(1-fade)", s.Dim, f.Fade) | |||
| 372 | } | 372 | } | ||
| 373 | ic.now = ic.now.Add(5 * time.Second) | 373 | ic.now = ic.now.Add(5 * time.Second) | ||
| 374 | c.animate(ic.now, nil) | 374 | c.animate(ic.now, nil) | ||
| @@ -386,7 +386,7 @@ func TestRetargetClearsScaleKeepsFade(t *testing.T) { | |||||
| 386 | sc := c.cur() | 386 | sc := c.cur() | ||
| 387 | sc.mon.AddWindow(1) | 387 | sc.mon.AddWindow(1) | ||
| 388 | settleShown(t, c) | 388 | settleShown(t, c) | ||
| 389 | - | c.appear(sc, 1, ic.now) | 389 | + | c.appearAt(sc, settledOf(t, sc, 1), ic.now) |
| 390 | settleShown(t, c) | 390 | settleShown(t, c) | ||
| 391 | if rm := sc.rects[1]; !rm.scale || !rm.fade.on { | 391 | if rm := sc.rects[1]; !rm.scale || !rm.fade.on { | ||
| 392 | t.Fatalf("setup: %+v", rm) | 392 | t.Fatalf("setup: %+v", rm) | ||