╭──────────╮ │← previous│ ╰──────────╯ ╭ changed ────────────╮ │src/ui/Repo/Files.zig│ ╰─────────────────────╯ ╭───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │759 tb.getFocus().kind = .{ .custom = link }; │ │760 try box.children.put(allocator, tb.getFocus().id, .{ .widget = .{ .text_box = tb }, .rect = null, .min_size = null });│ │761 + return tb.getFocus().id; │ │762 } │ │763 │ │764 pub fn input(self: *View, allocator: std.mem.Allocator, key: Key, root_focus: *Focus) !void { │ ╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │809 // the list, a click on a row opens it like enter. the row was just │ │810 // selected, so the detail is swapped to it ahead of the build. │ │811 .mouse => |mouse| if (self.contentBox().children.values()[detail_index].rect == null and ui.widget.clickOnSelectedRow(self.listBox(), root_focus, mouse)) {│ │787 - try self.refreshDetail(allocator); │ │812 + try self.refreshDetail(allocator, true); │ │813 try self.focusDetail(root_focus); │ │814 }, │ │815 else => {}, │ ╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │834 } │ │835 │ │836 fn detailInput(self: *View, allocator: std.mem.Allocator, key: Key, root_focus: *Focus) !void { │ │837 + // the way back to the list, by enter or a click │ │838 + if (self.back_id) |id| { │ │839 + if ((key == .enter and root_focus.grandchild_id == id) or (key == .mouse and inp.leftClickOn(root_focus, id, key.mouse))) return self.focusList(root_focus);│ │840 + } │ │841 const sc = self.detailScroll(); │ │842 const on_content = self.focusOnContent(root_focus); │ │843 // the "next" link sits above the content scroll. on the link, left returns │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────────────────────────────────────────────────╮ │844 // to the file list and down drops into the content. in the content, the │ │816 - // terminal scrolls by offset and reaching the top then pressing up crosses│ │817 - // back up to the link; on the web vertical scrolling is the browser's job │ │818 - // so up just crosses to the link. │ │845 + // terminal scrolls by offset (the wheel five rows at a time) and reaching │ │846 + // the top then pressing up crosses back up to the link; on the web │ │847 + // vertical scrolling is the browser's job so up just crosses to the link. │ │848 + const step: isize = if (key == .mouse) 5 else 1; │ │849 + switch (inp.vertDirection(key)) { │ │850 + .up => { │ │851 + if (!on_content) return; │ │852 + if (self.session.is_terminal and sc.y > 0) { │ │853 + sc.y -= step; │ │854 + self.detailScroll().clampToContent(); │ │855 + } else self.focusNav(root_focus); │ │856 + return; │ │857 + }, │ │858 + .down => { │ │859 + if (!on_content) return self.focusContent(root_focus); │ │860 + if (self.session.is_terminal) { │ │861 + sc.y += step; │ │862 + self.detailScroll().clampToContent(); │ │863 + } │ │864 + return; │ │865 + }, │ │866 + .none => {}, │ │867 + } │ │868 switch (key) { │ │869 .arrow_left => { │ │870 if (on_content) { │ ╰────────────────────────────────────────────────────────────────────────────────────────╯ ╭───────────────────────────────────────────────────────────────────────────────────╮ │881 sc.x += 1; │ │882 self.detailScroll().clampToContent(); │ │883 } else _ = self.moveNav(root_focus, 1); │ │835 - }, │ │836 - .arrow_up => { │ │837 - if (on_content) { │ │838 - if (self.session.is_terminal and sc.y > 0) { │ │839 - sc.y -= 1; │ │840 - self.detailScroll().clampToContent(); │ │841 - } else self.focusNav(root_focus); // cross up to the links│ │842 - } │ │843 - }, │ │844 - .arrow_down => { │ │845 - if (on_content) { │ │846 - if (self.session.is_terminal) { │ │847 - sc.y += 1; │ │848 - self.detailScroll().clampToContent(); │ │849 - } │ │850 - } else self.focusContent(root_focus); // links -> content │ │884 }, │ │885 .page_up => if (on_content and self.session.is_terminal) { │ │886 sc.y -= 10; │ ╰───────────────────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │898 sc.y = std.math.maxInt(isize); │ │899 self.detailScroll().clampToContent(); │ │900 }, │ │868 - .mouse => |mouse| switch (mouse.action) { │ │869 - .scroll => |dir| if (on_content and self.session.is_terminal) { │ │870 - sc.y += if (dir == .up) -5 else 5; │ │871 - self.detailScroll().clampToContent(); │ │872 - }, │ │873 - else => {}, │ │874 - }, │ │901 // step between the rendered markdown's links; the web leaves tab to the browser │ │902 .tab, .back_tab => if (on_content and self.session.is_terminal) if (self.markdownView()) |view| {│ │903 try view.stepLink(allocator, root_focus, sc, 0, 0, key == .tab); │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯