Skip to content

Reclaim the tmux viewport during active Remux use - #62

Merged
h3nock merged 2 commits into
mainfrom
fix/client-viewport-claim
Aug 11, 2026
Merged

Reclaim the tmux viewport during active Remux use#62
h3nock merged 2 commits into
mainfrom
fix/client-viewport-claim

Conversation

@h3nock

@h3nock h3nock commented Aug 11, 2026

Copy link
Copy Markdown
Owner

Summary

  • Reclaim Remux’s viewport when returning to the foreground or switching back to a retained session.
  • Reclaim a mismatched viewport before terminal input and relevant tmux interactions, including opening Windows or Panes.
  • Coalesce repeated claims while one is settling and batch the claim with the user action in the same outbound write.
  • Publish viewport-size changes and the corresponding claim together without polling or additional tmux queries.

Testing

  • Ran 68 focused controller and adapter tests covering exact outbound bytes, batching, duplicate suppression, command completion, and topology settlement.
  • Verified on a physical iPhone.
  • Verified end to end in the iOS Simulator against the existing Mac mini tmux session: after a desktop client changed the server window to 189×49, interacting from Remux restored it to 50×41.

Summary by CodeRabbit

  • Bug Fixes

    • Improved terminal session recovery when the app returns to the foreground.
    • Kept the active terminal viewport aligned when switching selected terminals or presenting window and pane selectors.
    • Improved viewport handling during resizing, navigation, input, copy mode, and other terminal actions.
    • Added recovery for viewport mismatches and prevented duplicate viewport requests.
  • Tests

    • Added coverage for viewport claiming, reclaiming, resizing, ordering, and stale responses.

@coderabbitai

coderabbitai Bot commented Aug 11, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: a43c746c-a2bf-4c9e-aa84-8287717d8bc6

📥 Commits

Reviewing files that changed from the base of the PR and between 3edd122 and eb39225.

📒 Files selected for processing (2)
  • RemuxApp/Sources/Tmux/TmuxScreenModel.swift
  • RemuxAppTests/TmuxScreenModelForegroundActiveCheckTests.swift
🚧 Files skipped from review as they are similar to previous changes (1)
  • RemuxApp/Sources/Tmux/TmuxScreenModel.swift

📝 Walkthrough

Walkthrough

The change adds active tmux viewport claim and reclaim operations. Claims propagate through viewport sizing, input, navigation, mutation, and selection commands. Lifecycle and selection events reclaim or claim the viewport. Tests cover ordering, deduplication, stale replies, resizing, and cleanup.

Changes

Active viewport ownership

Layer / File(s) Summary
Controller claim admission and settlement
RemuxApp/Sources/Tmux/TmuxSessionController.swift
The controller tracks pending viewport claims, admits claims before relevant commands, settles claims from topology updates, and resets claim state during cleanup.
Viewport claim API and lifecycle wiring
RemuxApp/Sources/Ghostty/GhosttyTerminalScreenModeling.swift, RemuxApp/Sources/Ghostty/GhosttySurfaceScreen.swift, RemuxApp/Sources/Tmux/TmuxScreenModel.swift, RemuxApp/Sources/Tmux/TmuxTerminalScreenAdapter.swift, RemuxApp/Sources/App/RemuxRootModel.swift
The viewport APIs accept claim flags and expose claim and reclaim actions. Screen selection, scene activation, lifecycle activation, and sheet presentation invoke the required viewport operation.
Viewport claim behavior tests
RemuxAppTests/TmuxSessionControllerClientSizeTests.swift, RemuxAppTests/TmuxTerminalScreenAdapterTests.swift, RemuxAppTests/TmuxScreenModelForegroundActiveCheckTests.swift
Tests cover claim and reclaim behavior, command ordering, duplicate suppression, stale replies, resize handling, unchanged-size claims, and updated callback signatures.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant RemuxRootModel
  participant GhosttySurfaceScreen
  participant TmuxTerminalScreenAdapter
  participant TmuxSessionController
  participant tmux
  RemuxRootModel->>TmuxTerminalScreenAdapter: reclaimActiveTmuxViewport()
  GhosttySurfaceScreen->>TmuxTerminalScreenAdapter: prepareInitialViewport(..., claimActiveViewport)
  TmuxTerminalScreenAdapter->>TmuxSessionController: setClientSize(..., claimActiveViewport)
  TmuxSessionController->>tmux: refresh-client and select-window
  tmux-->>TmuxSessionController: topology update
Loading

Possibly related PRs

  • h3nock/remux#21: Related session-switching and terminal-sheet changes invoke active viewport claim and reclaim operations.
  • h3nock/remux#23: Related terminal input and viewport lifecycle handling changes the same screen and session-control paths.
  • h3nock/remux#49: Related multi-pane viewport and client-size handling uses the same screen model, adapter, and session controller paths.
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 12.50% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the PR's main change: reclaiming the tmux viewport during active Remux use.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/client-viewport-claim

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Aug 11, 2026

Copy link
Copy Markdown

Deploying getremux with  Cloudflare Pages  Cloudflare Pages

Latest commit: eb39225
Status: ✅  Deploy successful!
Preview URL: https://a0360869.getremux.pages.dev
Branch Preview URL: https://fix-client-viewport-claim.getremux.pages.dev

View logs

@h3nock
h3nock marked this pull request as ready for review August 11, 2026 14:52

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 3edd1220af

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines 240 to 244
_ size: TmuxSessionController.ClientSize,
claimActiveViewport: Bool = false
) -> Bool {
guard !stopped, let controller = session?.controller else { return false }
guard size != lastSubmittedClientSize else { return false }

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Honor same-size viewport claims

When an active viewport observation resolves to the previously submitted grid, this guard drops claimActiveViewport before it reaches the controller. For example, if another tmux client has enlarged the active window and a Remux geometry update does not cross a cell boundary, prepareInitialViewport(..., claimActiveViewport: true) returns here and the window remains at the other client's size until some later input or topology action triggers a claim. Forward the request when claimActiveViewport is true even if no refresh-client size change is required; setClientSize now explicitly supports that same-size claim path.

Useful? React with 👍 / 👎.

@cloudflare-workers-and-pages

Copy link
Copy Markdown

Deploying remux with  Cloudflare Pages  Cloudflare Pages

Latest commit: eb39225
Status: ✅  Deploy successful!
Preview URL: https://512583af.remux-agx.pages.dev
Branch Preview URL: https://fix-client-viewport-claim.remux-agx.pages.dev

View logs

@h3nock
h3nock merged commit d661591 into main Aug 11, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant