╭──────────╮ │← previous│ ╰──────────╯ ╭ changed ────────╮ │src/ui/widget.zig│ ╰─────────────────╯ ╭────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │1264 - self.box.deinit(allocator); │ │1334 + self.scroll.deinit(allocator); │ │1335 } │ │1336 │ │1337 pub fn build(self: *SearchHeader, allocator: std.mem.Allocator, constraint: layout.Constraint, root_focus: *Focus) !void {│ ╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭───────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │1338 self.clearGrid(); │ │1269 - try self.box.build(allocator, constraint, root_focus); │ │1339 + try self.scroll.build(allocator, constraint, root_focus); │ │1340 } │ │1341 │ │1342 pub fn input(self: *SearchHeader, allocator: std.mem.Allocator, key: Key, root_focus: *Focus) !void {│ ╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────╮ │1273 - const current = self.box.getFocus().child_id orelse return; │ │1343 + const current = self.scroll.row().getFocus().child_id orelse return;│ │1344 if (self.searchBox()) |search_box| { │ │1345 if (current == search_box.getFocus().id) { │ │1346 // tab, and right-arrow past the last character, step to the│ ╰──────────────────────────────────────────────────────────────────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────────────╮ │1368 // focus. the caller owns the returned text. │ │1369 pub fn submittedText(self: *SearchHeader, allocator: std.mem.Allocator) !?[]u8 { │ │1370 const search_box = self.searchBox() orelse return null; │ │1301 - if (self.box.getFocus().child_id != search_box.getFocus().id) return null; │ │1371 + if (self.scroll.row().getFocus().child_id != search_box.getFocus().id) return null;│ │1372 return try search_box.text(allocator); │ │1373 } │ │1374 │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────────────────────────────────────────────────╮ │1388 } │ │1389 │ │1390 fn cloneUrl(self: *SearchHeader) ?*CopyableText { │ │1321 - for (self.box.children.values()) |*child| switch (child.widget) { │ │1391 + for (self.scroll.row().children.values()) |*child| switch (child.widget) {│ │1392 .copyable_text => |*copyable_text| return copyable_text, │ │1393 else => {}, │ │1394 }; │ ╰────────────────────────────────────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────────────────────────────────────────────────╮ │1396 } │ │1397 │ │1398 fn searchBox(self: *SearchHeader) ?*SearchBox { │ │1329 - for (self.box.children.values()) |*child| switch (child.widget) { │ │1399 + for (self.scroll.row().children.values()) |*child| switch (child.widget) {│ │1400 .search_box => |*search_box| return search_box, │ │1401 else => {}, │ │1402 }; │ ╰────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────╮ │1404 } │ │1405 │ │1406 pub fn clearGrid(self: *SearchHeader) void {│ │1337 - self.box.clearGrid(); │ │1407 + self.scroll.clearGrid(); │ │1408 } │ │1409 │ │1410 pub fn getGrid(self: SearchHeader) ?Grid { │ ╰──────────────────────────────────────────────────────╯ ╭───────────────────────────────────────────────────────╮ │1341 - return self.box.getGrid(); │ │1411 + return self.scroll.getGrid(); │ │1412 } │ │1413 │ │1414 pub fn getFocus(self: *SearchHeader) *Focus {│ ╰───────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────╮ │1345 - return self.box.getFocus(); │ │1415 + return self.scroll.getFocus();│ │1416 } │ │1417 }; │ │1418 │ ╰────────────────────────────────────────────╯ ╭ changed ───────────────╮ │src/ui/widget/thread.zig│ ╰────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────╮ │490 // the common sub-header used by each thread page: the search box, then the │ │491 // tab strip │ │492 pub const Header = struct { │ │493 - box: wgt.Box(Widget), │ │493 + scroll: widget.HeaderScroll, │ │494 // focus id -> semantic stack index; some pages omit unavailable tabs │ │495 tab_ids: std.AutoArrayHashMapUnmanaged(usize, usize), │ │496 // the tab whose view the stack shows. focus lands on the search box too,│ ╰──────────────────────────────────────────────────────────────────────────────────╯ ╭──────╮ │next →│ ╰──────╯