╭ changed ───────────────╮ │src/ui/widget/thread.zig│ ╰────────────────────────╯ ╭───────────╮ │← all files│ ╰───────────╯ ╭────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │2267 const lead: usize = if (win.prev_id != null) 1 else 0; │ │2268 if (idx < lead or idx - lead >= win.items.len) return null; │ │2269 return idx - lead; │ │2270 + } │ │2271 + │ │2272 + // swap the detail pane to the selected thread when it changes │ │2273 + fn refreshDetail(self: *This, allocator: std.mem.Allocator, index: usize) !void { │ │2274 + const selected = self.selectedThreadIndex(index) orelse return; │ │2275 + const entry = self.window(index).items[selected]; │ │2276 + const changed = if (self.detail(index).entry) |current| !std.mem.eql(u8, current.id, entry.id) else true; │ │2277 + if (changed) try self.detail(index).setEntry(allocator, entry); │ │2278 } │ │2279 │ │2280 pub fn build(self: *This, allocator: std.mem.Allocator, constraint: layout.Constraint, root_focus: *Focus) !void {│ ╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │2287 } │ │2288 │ │2289 if (self.selectedSplitIndex()) |i| { │ │2282 - // swap the detail pane to the selected thread when it changes. │ │2283 - if (self.selectedThreadIndex(i)) |selected| { │ │2284 - const entry = self.window(i).items[selected]; │ │2285 - const changed = if (self.detail(i).entry) |current| !std.mem.eql(u8, current.id, entry.id) else true;│ │2286 - if (changed) { │ │2287 - try self.detail(i).setEntry(allocator, entry); │ │2288 - } │ │2289 - } │ │2290 + try self.refreshDetail(allocator, i); │ │2291 │ │2292 // the selected list row shows a border (the focused TextBox │ │2293 // upgrades it to a double border itself); the rest stay borderless. │ ╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────────────────────────────────╮ │2397 .header => self.focusHeader(root_focus), │ │2398 } │ │2399 } else { │ │2399 - self.listInput(i, key, root_focus); │ │2400 + try self.listInput(allocator, i, key, root_focus);│ │2401 } │ │2402 } │ │2403 │ ╰────────────────────────────────────────────────────────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │2430 } │ │2431 } │ │2432 │ │2432 - fn listInput(self: *This, index: usize, key: Key, root_focus: *Focus) void { │ │2433 + fn listInput(self: *This, allocator: std.mem.Allocator, index: usize, key: Key, root_focus: *Focus) !void {│ │2434 // up/down (and the scroll wheel) move the selection a row; page up/down │ │2435 // jump a fixed amount. right/Enter cross into the detail pane. up from │ │2436 // the top row crosses into the header tabs. │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │2443 } │ │2444 switch (key) { │ │2445 .enter, .arrow_right => _ = self.detail(index).focusFirst(root_focus), │ │2446 + // when the window is too narrow to lay out the detail pane beside │ │2447 + // the list, a click on a row opens it like enter. the row was just │ │2448 + // selected, so the detail is swapped to it ahead of the build. │ │2449 + .mouse => |mouse| if (self.resultsBox(index).children.values()[detail_index].rect == null and widget.clickOnSelectedRow(self.listBox(index), root_focus, mouse)) {│ │2450 + try self.refreshDetail(allocator, index); │ │2451 + _ = self.detail(index).focusFirst(root_focus); │ │2452 + }, │ │2453 else => {}, │ │2454 } │ │2455 } │ ╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯