╭ changed ───────────────╮ │src/ui/widget/thread.zig│ ╰────────────────────────╯ ╭───────────╮ │← all files│ ╰───────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────────────╮ │1041 } │ │1042 │ │1043 fn descriptionInput(self: *This, key: Key, root_focus: *Focus) void { │ │1044 - const detail_scroll = &self.scroll; │ │1044 switch (key) { │ │1045 .arrow_left => self.exit = .list, │ │1047 - .arrow_up => { │ │1048 - if (!self.session.is_terminal) { │ │1049 - _ = self.moveVertical(root_focus, false); │ │1050 - return; │ │1051 - } │ │1052 - if (self.focusAdjacentVisible(root_focus, false)) return; │ │1053 - const before = detail_scroll.y; │ │1054 - detail_scroll.y -= 1; │ │1055 - detail_scroll.clampToContent(); │ │1056 - if (detail_scroll.y == before) _ = self.moveVertical(root_focus, false);│ │1057 - }, │ │1058 - .arrow_down => { │ │1059 - if (!self.session.is_terminal) { │ │1060 - _ = self.moveVertical(root_focus, true); │ │1061 - return; │ │1062 - } │ │1063 - if (self.focusAdjacentVisible(root_focus, true)) return; │ │1064 - const before = detail_scroll.y; │ │1065 - detail_scroll.y += 1; │ │1066 - detail_scroll.clampToContent(); │ │1067 - if (detail_scroll.y == before) _ = self.moveVertical(root_focus, true); │ │1068 - }, │ │1046 + .arrow_up => _ = self.moveVertical(root_focus, false), │ │1047 + .arrow_down => _ = self.moveVertical(root_focus, true), │ │1048 else => {}, │ │1049 } │ │1050 } │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────╮ │1136 return false; │ │1137 } │ │1138 │ │1160 - fn focusAdjacentVisible(self: *This, root_focus: *Focus, down: bool) bool {│ │1161 - const inner_box = self.inner(); │ │1162 - var next = self.focusedChild(root_focus) orelse return false; │ │1163 - while (true) { │ │1164 - if (down) { │ │1165 - next += 1; │ │1166 - if (next >= inner_box.children.count()) return false; │ │1167 - } else { │ │1168 - if (next == 0) return false; │ │1169 - next -= 1; │ │1170 - } │ │1171 - if (self.focusVisibleChild(next, root_focus, !down)) { │ │1172 - self.focusChild(next, !down, root_focus); │ │1173 - return true; │ │1174 - } │ │1175 - } │ │1176 - } │ │1177 - │ │1139 fn focusedChild(self: *This, root_focus: *Focus) ?usize { │ │1140 const inner_box = self.inner(); │ │1141 var id = root_focus.grandchild_id orelse return null; │ ╰─────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │1194 fn moveVertical(self: *This, root_focus: *Focus, down: bool) bool { │ │1195 const inner_box = self.inner(); │ │1196 const current = self.focusedChild(root_focus) orelse return false; │ │1197 + // a tall description or comment body is scrolled through before focus │ │1198 + // leaves it │ │1199 + if (self.focusedRect(current)) |rect| if (widget.scrollThroughRow(&self.scroll, rect, if (down) 1 else -1)) return true;│ │1200 if (inner_box.children.values()[current].widget == .repo_comment) { │ │1201 const comment = &inner_box.children.values()[current].widget.repo_comment; │ │1202 if (down and !comment.bodyFocused()) { │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────────────────────────────────────────────────────╮ │1224 } │ │1225 } │ │1226 │ │1227 + // the focused part of child `child_index`, in the scroll's content: a │ │1228 + // comment's metadata or body row, else the whole child │ │1229 + fn focusedRect(self: *This, child_index: usize) ?layout.IRect { │ │1230 + const child = &self.inner().children.values()[child_index]; │ │1231 + var rect = child.rect orelse return null; │ │1232 + if (child.widget == .repo_comment) { │ │1233 + const comment = &child.widget.repo_comment; │ │1234 + const row = comment.rowRect(comment.bodyFocused()) orelse return null;│ │1235 + rect.x += row.x; │ │1236 + rect.y += row.y; │ │1237 + rect.size = row.size; │ │1238 + } │ │1239 + return rect; │ │1240 + } │ │1241 + │ │1242 fn moveHorizontal(self: *This, root_focus: *Focus, right: bool) bool { │ │1243 const inner_box = self.inner(); │ │1244 const current = self.focusedChild(root_focus) orelse return false; │ ╰────────────────────────────────────────────────────────────────────────────────────────────╯