summaryrefslogtreecommitdiff
path: root/src/draw.zig
diff options
context:
space:
mode:
Diffstat (limited to 'src/draw.zig')
-rw-r--r--src/draw.zig39
1 files changed, 38 insertions, 1 deletions
diff --git a/src/draw.zig b/src/draw.zig
index 0ea0b35e..9fcbb15f 100644
--- a/src/draw.zig
+++ b/src/draw.zig
@@ -225,7 +225,15 @@ fn glideCursor(p: *Pardes, s: *Surface) void {
s.chrome.cursor_alpha = 1;
s.chrome.cursor_idle_ms = std.math.maxInt(u32);
if (!builtins.capabilities.lift) return;
- const box = focusedCursorBox(p, s) orelse return;
+ const box = focusedCursorBox(p, s) orelse {
+ // No cursor drawn (a PDF or picture took focus, a program hid its
+ // own): a glide under way has nowhere to land, and its springs,
+ // never stepped again, held continuous() and the frames on for
+ // ever. It stops; the next cursor lands where it is.
+ p.cursor_glide = .{};
+ p.cursor_crossing = false;
+ return;
+ };
const motion = animation.Motion.of(p.settings.motion);
var snap = if (s.cursor) |cursor| cursor.bar else false;
var frame: PaneFrame = .{};
@@ -2341,6 +2349,35 @@ test "focus moved to another column glides from where the cursor was drawn" {
try std.testing.expect(!p.cursor_glide.moving() and !p.cursor_crossing);
}
+test "focus moving to a pane with no cursor while the cursor glides lets the session go idle" {
+ if (!builtins.capabilities.lift) return error.SkipZigTest;
+ const p = try Pardes.init(std.testing.allocator, .{ .cols = 120, .rows = 20 });
+ defer p.deinit();
+ var arena: std.heap.ArenaAllocator = .init(std.testing.allocator);
+ defer arena.deinit();
+ p.settings.motion = .smooth;
+ try twoColumns(p, &arena);
+ p.active = 0;
+ p.advance(3 * std.time.ns_per_s);
+ _ = arena.reset(.retain_capacity);
+ _ = try p.render(arena.allocator());
+ p.active = 1;
+ _ = arena.reset(.retain_capacity);
+ _ = try p.render(arena.allocator());
+ try std.testing.expect(p.cursor_glide.moving());
+ // Mid-glide, the pane focused draws no cursor (as a PDF pane does).
+ p.panes[1].?.body.mode = .tty;
+ p.update(.{ .output = .{ .pane = 1, .bytes = "\x1b[?25l" } });
+ p.advance(3 * std.time.ns_per_s + 20 * std.time.ns_per_ms);
+ _ = arena.reset(.retain_capacity);
+ const hidden = try p.render(arena.allocator());
+ try std.testing.expect(hidden.cursor == null);
+ p.advance(5 * std.time.ns_per_s);
+ _ = arena.reset(.retain_capacity);
+ _ = try p.render(arena.allocator());
+ try std.testing.expect(!p.cursor_glide.moving() and !p.continuous());
+}
+
test "a pane focus reaches brightens on the same spring the one it leaves dims on, and Motion off snaps" {
if (!builtins.capabilities.lift) return error.SkipZigTest;
const p = try Pardes.init(std.testing.allocator, .{ .cols = 80, .rows = 24 });