···128 offset: u16 = 0,
129 /// Message offset into the list of messages. We use this to lock the viewport if we have a
130 /// scroll. Otherwise, when offset == 0 this is effectively ignored (and should be 0)
131- msg_offset: u32 = 0,
132133 /// Pending scroll we have to handle while drawing. This could be up or down. By convention
134 /// we say positive is a scroll up.
135- pending: i17 = 0,
136 } = .{},
137138 pub const Member = struct {
···466467 /// Consumes any pending scrolls and schedules another tick if needed
468 fn doScroll(self: *Channel, ctx: *vxfw.EventContext) anyerror!void {
00000000000469 const animation_tick: u32 = 30;
470 // No pending scroll. Return early
471 if (self.scroll.pending == 0) return;
···526527 var children = std.ArrayList(vxfw.SubSurface).init(ctx.arena);
528529- // Row is the row we are printing on.
530 var row: i17 = max.height + self.scroll.offset;
531- var iter = std.mem.reverseIterator(self.messages.items);
000532 const gutter_width = 6;
533 while (iter.next()) |msg| {
534 // Break if we have gone past the top of the screen
···128 offset: u16 = 0,
129 /// Message offset into the list of messages. We use this to lock the viewport if we have a
130 /// scroll. Otherwise, when offset == 0 this is effectively ignored (and should be 0)
131+ msg_offset: ?u16 = null,
132133 /// Pending scroll we have to handle while drawing. This could be up or down. By convention
134 /// we say positive is a scroll up.
135+ pending: i16 = 0,
136 } = .{},
137138 pub const Member = struct {
···466467 /// Consumes any pending scrolls and schedules another tick if needed
468 fn doScroll(self: *Channel, ctx: *vxfw.EventContext) anyerror!void {
469+ defer {
470+ // At the end of this function, we anchor our msg_offset if we have any amount of
471+ // scroll. This prevents new messages from automatically scrolling us
472+ if (self.scroll.offset > 0 and self.scroll.msg_offset == null) {
473+ self.scroll.msg_offset = @intCast(self.messages.items.len);
474+ }
475+ // If we have no offset, we reset our anchor
476+ if (self.scroll.offset == 0) {
477+ self.scroll.msg_offset = null;
478+ }
479+ }
480 const animation_tick: u32 = 30;
481 // No pending scroll. Return early
482 if (self.scroll.pending == 0) return;
···537538 var children = std.ArrayList(vxfw.SubSurface).init(ctx.arena);
539540+ // Row is the row we are printing on. We add the offset to achieve our scroll location
541 var row: i17 = max.height + self.scroll.offset;
542+543+ const offset = self.scroll.msg_offset orelse self.messages.items.len;
544+545+ var iter = std.mem.reverseIterator(self.messages.items[0..offset]);
546 const gutter_width = 6;
547 while (iter.next()) |msg| {
548 // Break if we have gone past the top of the screen