summaryrefslogtreecommitdiff
path: root/src/pardes.zig
diff options
context:
space:
mode:
authorGabriel Schneider <[email protected]>2026-09-28 17:56:10 -0300
committerGabriel Schneider <[email protected]>2026-10-01 00:12:15 -0300
commitb4781b334a06d16aedb0b6a3d604cb249eb619de (patch)
tree6c95db55cbd6bf7dde4bc89d1e76e6c1556223b1 /src/pardes.zig
parentdeeb8ac54f71d4322a778336db9a7aec411c23ce (diff)
downloadpardes-b4781b334a06d16aedb0b6a3d604cb249eb619de.tar.gz
pardes-b4781b334a06d16aedb0b6a3d604cb249eb619de.zip
Lift moves at the display's rate: render-time animation
Review (and the coordinator): Lift stepped with the core's 16 ms ticks, so a 144 Hz display held each shadow for 2-3 refreshes. The lift springs are now sampled at each frame's own time (p.now_ns), and Pardes.continuous() reports a render-time animation in motion: while it is, the pump draws every loop (a 1 ms wait takes only the input there is) and the present's vsync paces it at the display's rate. They left nextWake; the stepped, frame-indexed animations (transitions, message fades, the theme fade) and every golden are unchanged. With PARDES_TEST_CLOCK, each loop of a moving render-time animation moves the virtual clock by a display frame at PARDES_TEST_HZ (default 60), so a 144 Hz series is deterministic: a focus switch is 51 distinct frames at 144 Hz. Test: renders 6.9 ms apart give rising lifts; settled, no frames. The tty never lifts (GUI capability). Shared files touched: pardes.zig (continuous, pump), gui.zig.
Diffstat (limited to 'src/pardes.zig')
-rw-r--r--src/pardes.zig18
1 files changed, 14 insertions, 4 deletions
diff --git a/src/pardes.zig b/src/pardes.zig
index 449ef798..04ef4b36 100644
--- a/src/pardes.zig
+++ b/src/pardes.zig
@@ -5040,7 +5040,9 @@ pub const Pardes = struct {
if (v.wait_input) |f| {
// Asleep until input or until core animation next needs a
// frame; 0 is no timeout at all.
- const timeout: u32 = if (p.nextWake()) |due| wake: {
+ // A render-time animation draws every loop: the wait only takes
+ // what input is there.
+ const timeout: u32 = if (p.continuous()) 1 else if (p.nextWake()) |due| wake: {
const now = if (v.now) |clock| clock(h.ctx) else p.now_ns;
const ms = ((due -| now) + std.time.ns_per_ms - 1) / std.time.ns_per_ms;
break :wake @intCast(std.math.clamp(ms, 1, std.math.maxInt(u32)));
@@ -5059,7 +5061,7 @@ pub const Pardes = struct {
// rendering and nothing else.
// A shell with a clock draws what `advance` stepped; one without
// steps its own `.tick`s and draws while anything animates.
- if (!p.needs_frame and (v.now != null or !p.animationActive())) return;
+ if (!p.needs_frame and !p.continuous() and (v.now != null or !p.animationActive())) return;
_ = p.frame_arena.reset(.retain_capacity);
const surface = try p.render(p.frame_arena.allocator());
if (v.present) |f| f(h.ctx, surface);
@@ -6217,7 +6219,6 @@ pub const Pardes = struct {
pub fn nextWake(p: *const Pardes) ?u64 {
const next = p.stepped_ns + animation.frame_ns;
if (p.chrome_animation.isActive() or p.presentation.animating()) return next;
- for (p.lifts) |spring| if (!spring.settled) return next;
var frames: ?u64 = null;
if (p.look_hover_wait) |waiting| {
const delay = config.look_preview_delay_frames orelse return next;
@@ -6230,10 +6231,19 @@ pub const Pardes = struct {
return if (frames) |n| p.stepped_ns + n * animation.frame_ns else null;
}
+ /// A render-time animation is moving (a pane's lift): it is sampled at
+ /// each frame's own `now`, so while it moves the shell draws every loop
+ /// and its present (vsync) paces it, at the display's rate. `nextWake`
+ /// is for the stepped animations, which count frames of `frame_ns`.
+ pub fn continuous(p: *const Pardes) bool {
+ for (p.lifts) |spring| if (!spring.settled) return true;
+ return false;
+ }
+
/// For shells that only need a yes or no: macOS and the board, which
/// keep their own frame banks.
pub fn animationActive(p: *const Pardes) bool {
- return p.nextWake() != null;
+ return p.nextWake() != null or p.continuous();
}
/// Bring core animation up to `now_ns`, the shell's monotonic clock: one