╭ changed ─╮ │src/ui.zig│ ╰──────────╯ ╭───────────╮ │← all files│ ╰───────────╯ ╭───────────────────────────────────────────────────────────────────────────────────────────────────────╮ │347 // inputs. web/wasm form handling looks widgets up here by focus id. │ │348 text_inputs: std.AutoHashMapUnmanaged(usize, *wgt.TextInput(Widget)) = .empty, │ │349 nav_back: bool = false, // set by input (escape) to request the native TUI pop a page; see Nav│ │350 + // a requested forward navigation. set this (via navigate) to move to a new │ │351 + // page; Nav.sync builds it and then copies it into current_page, clearing │ │352 + // this back to null. setting current_page directly only updates the url and │ │353 + // does not navigate. │ │354 + next_page: ?RoutablePage = null, │ │355 is_terminal: bool = false, // true on remote SSH and local TUI │ │356 quit_requested: bool = false, │ │357 │ ╰───────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭───────────────────────────────────────────────────────────────────────────────────╮ │441 } │ │442 } │ │443 │ │439 - // record the requested page. `route` may borrow a name slice from the │ │440 - // current page's widget tree, which stays alive until Nav.sync runs (this│ │441 - // frame); sync re-anchors the name into the new page's arena. │ │444 + // request a forward navigation to `route`; Nav.sync builds it next │ │445 fn navigate(self: *Session, route: RoutablePage) !void { │ │443 - self.data.current_page = route; │ │446 + self.next_page = route; │ │447 } │ │448 }; │ │449 │ ╰───────────────────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────────────────╮ │665 return; │ │666 } │ │667 │ │665 - // forward navigation: a different parent page, or — within the repo page │ │666 - // — a different files directory (each directory is its own page, while │ │667 - // settings/auth tab switches stay in-page and are not pushed here). │ │668 - const cp = session.data.current_page; │ │669 - if (cp.parent() != self.route.parent() or RoutablePage.repoPageChanged(cp, self.route)) {│ │668 + // forward navigation: navigate() set next_page to the page to move to (a │ │669 + // cross-page link or tab change crossing pages) │ │670 + if (session.next_page) |route| { │ │671 + session.next_page = null; │ │672 if (session.haxy_moment == null) return; │ │673 + // the page we navigated to becomes the current page │ │674 + session.data.current_page = route; │ │675 + │ │676 const arena = try allocator.create(std.heap.ArenaAllocator); │ │677 arena.* = std.heap.ArenaAllocator.init(allocator); │ │678 errdefer freeArena(allocator, arena); │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭─────────────────────────────────────────────────────────────────╮ │679 │ │680 session.page_arena = arena; │ │676 - const route = session.data.current_page; │ │681 │ │682 const page = try arena.allocator().create(Page);│ │683 page.* = try Page.init(arena, session, route); │ ╰─────────────────────────────────────────────────────────────────╯