Skip to content

Navigation stack: Ctrl+− / Ctrl+Shift+− back and forward through tab history #52

Closed

Description

@JoshuaRowePhantom

Summary

Maintain a linear navigation history of tabs and top-level views visited. Ctrl+−
navigates backward and Ctrl+Shift+− (Ctrl+_) navigates forward, analogous to
browser back/forward or Visual Studio Ctrl+−/Ctrl+Shift+−.

Design

See docs/design/navigation-stack.md.

Scope

INavigationHistoryService

  • Linear list with current-position pointer (max 200 entries)
  • Push(NavigationEntry) — called by every tab/view activation
  • GoBack / GoForward — move the pointer, activate the entry
  • Deduplication: skip push if entry is identical to the one immediately before current
  • No persistence — stack is in-memory only

NavigationEntry / TabDescriptor

  • Each entry stores: workspace id, tab id, and a TabDescriptor for reopening closed tabs
  • TabDescriptor subclasses per tab kind: entity, agent-session, browser, entity-browser
  • Closed tab reopen: call TabDescriptor.OpenAsync; skip and try next on failure

Push sources

  • MainWindowViewModel.OpenTabAsync
  • MainWindowViewModel top-level view selection
  • Notification click / F7/F8 navigation
  • (AI tool integration tracked separately)

Guard against double-push

  • _navigatingViaHistory bool in MainWindowViewModel suppresses push during GoBack/GoForward activations

Key bindings

  • Ctrl+OemMinus → NavigateBackCommand
  • Ctrl+Shift+OemMinus → NavigateForwardCommand
  • Added to MainWindow.axaml

Acceptance

  • Ctrl+− navigates to the previously active tab/view
  • Ctrl+Shift+− navigates forward after going back
  • Navigating to a new tab while mid-history truncates forward history
  • Navigating to a closed tab reopens it; deleted entities are skipped

Activity

  1. added a commit that references this issue on Jun 26, 2026
    94354f0
  2. JoshuaRowePhantom commented on Jun 30, 2026

    @JoshuaRowePhantom
    OwnerAuthor

    Verification failed

    Checked: Commit 94354f0 (Fix #52) on the features branch — files Phantom.Workspaces/Services/Navigation/INavigationHistoryService.cs, NavigationHistoryService.cs, NavigationEntry.cs, MainWindowViewModel.cs, MainWindow.axaml, and test file Phantom.Workspaces.Tests/NavigationStackTests.cs. Also checked the full features branch tree for any subsequent commits adding the missing pieces.

    Found:

    • INavigationHistoryService with Push, GoBack, GoForward, CanGoBack, CanGoForward
    • NavigationHistoryService: linear list, max 200 entries, deduplication, truncation on new push
    • _navigatingViaHistory guard in MainWindowViewModel
    • Key bindings Ctrl+OemMinus / Ctrl+Shift+OemMinus wired in MainWindow.axaml
    • Push calls from OpenTabAsync, top-level view selection, and F7/F8 notification navigation
    • Tests for basic Push, GoBack, GoForward, ClearsForwardHistory behaviour

    Missing: behaviour not implemented + tests missing

    1. TabDescriptor abstract base class — Phantom.Workspaces/Services/Navigation/TabDescriptor.cs with virtual OpenAsync(mainWindowViewModel) is absent. No EntityTabDescriptor, AgentSessionTabDescriptor, or BrowserTabDescriptor subclasses exist in the Navigation folder.
    2. NavigationEntry.TabDescriptor? field — the current record is sealed record NavigationEntry(string TabId, string? WorkspacePaneId) with no TabDescriptor? for closed-tab reopening.
    3. Closed-tab reopen in ActivateTabById — when a tab is not found in any pane, ActivateTabById silently returns without calling TabDescriptor.OpenAsync. The acceptance criterion "Navigating to a closed tab reopens it; deleted entities are skipped" is not satisfied.
    4. Tests for closed-tab reopen — NavigationStackTests.cs has no test for the reopen-on-closed-tab or skip-deleted-entity paths.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions