╭ changed ─╮ │src/ui.zig│ ╰──────────╯ ╭───────────╮ │← all files│ ╰───────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────╮ │1946 focus: *Focus, │ │1947 grid: ?Grid, │ │1948 text_boxes: std.ArrayList(wgt.TextBox(Widget)), │ │1949 - // backs the per-item strings the text boxes borrow: each box's `content` │ │1950 - // and, for link items, its `.custom` focus kind (e.g. "a:/user/foo"). reset│ │1949 + // backs each link item's `.custom` focus kind (e.g. "a:/user/foo"). reset │ │1950 // wholesale on each setItems so there's no per-string ownership to track. │ │1951 arena: std.heap.ArenaAllocator, │ │1952 // column count from the last build — FlowBox.Scroll.input uses it so arrow │ ╰──────────────────────────────────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────────────────────────────────────────────────────────────╮ │1988 // the web renderer turns into an anchor. │ │1989 pub const Item = struct { text: []const u8, link: []const u8 = "" }; │ │1990 │ │1992 - // both the item text and the link are copied into the arena, so the caller's │ │1993 - // slices needn't outlive this call. │ │1991 + // the text box copies the item text; links are copied into the arena, so the │ │1992 + // caller's slices needn't outlive this call. │ │1993 pub fn setItems(self: *FlowBox, allocator: std.mem.Allocator, items: []const Item) !void {│ │1994 for (self.text_boxes.items) |*tb| tb.deinit(allocator); │ │1995 self.text_boxes.clearAndFree(allocator); │ ╰────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭───────────────────────────────────────────────────────────────────────────────────────╮ │1996 │ │1998 - // the old text boxes (and their borrowed content/links) are gone now, so│ │1999 - // the arena that backed those strings can be reclaimed. │ │1997 + // the old text boxes and their borrowed links are gone now, so the link │ │1998 + // arena can be reclaimed. │ │1999 _ = self.arena.reset(.retain_capacity); │ │2000 const aa = self.arena.allocator(); │ │2001 │ ╰───────────────────────────────────────────────────────────────────────────────────────╯ ╭───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │2003 self.focus.child_id = null; │ │2004 │ │2005 for (items) |item| { │ │2007 - const line = try aa.dupe(u8, item.text); │ │2008 - │ │2009 - var text_box = try wgt.TextBox(Widget).init(allocator, line, .{ .border_style = .hidden, .rounded_corners = true, .wrap_kind = .word }); │ │2006 + var text_box = try wgt.TextBox(Widget).init(allocator, item.text, .{ .border_style = .hidden, .rounded_corners = true, .wrap_kind = .word });│ │2007 errdefer text_box.deinit(allocator); │ │2008 text_box.getFocus().focusable = true; │ │2009 │ ╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────────────╮ │2222 // last build's item rects (content space), for vertical navigation and│ │2223 // scroll-into-view. │ │2224 rects: std.ArrayList(layout.IRect), │ │2228 - // backs the per-item strings the text boxes borrow. │ │2225 + // backs each link item's `.custom` focus kind. │ │2226 arena: std.heap.ArenaAllocator, │ │2227 │ │2228 pub const Item = struct { text: []const u8, link: []const u8 = "" }; │ ╰─────────────────────────────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────────────────────────────────────────────────────────────╮ │2249 self.arena.deinit(); │ │2250 } │ │2251 │ │2255 - // both the item text and the link are copied into the arena, so the caller's │ │2256 - // slices needn't outlive this call. │ │2252 + // the text box copies the item text; links are copied into the arena, so the │ │2253 + // caller's slices needn't outlive this call. │ │2254 pub fn setItems(self: *TagFlow, allocator: std.mem.Allocator, items: []const Item) !void {│ │2255 for (self.text_boxes.items) |*tb| tb.deinit(allocator); │ │2256 self.text_boxes.clearAndFree(allocator); │ ╰────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │2262 self.focus.child_id = null; │ │2263 │ │2264 for (items) |item| { │ │2268 - const line = try aa.dupe(u8, item.text); │ │2269 - │ │2270 - var text_box = try wgt.TextBox(Widget).init(allocator, line, .{ .border_style = .single, .rounded_corners = true, .wrap_kind = .none }); │ │2265 + var text_box = try wgt.TextBox(Widget).init(allocator, item.text, .{ .border_style = .single, .rounded_corners = true, .wrap_kind = .none });│ │2266 errdefer text_box.deinit(allocator); │ │2267 text_box.getFocus().focusable = true; │ │2268 │ ╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯