Skip to content

Make the pairing QR bigger and faster to scan - #5863

Closed
azooz2003-bit wants to merge 2 commits into
mainfrom
feat-pairing-qr-scan
Closed

azooz2003-bit wants to merge 2 commits into
mainfrom
feat-pairing-qr-scan

Conversation

@azooz2003-bit

@azooz2003-bit azooz2003-bit commented Jun 11, 2026 •

Copy link
Copy Markdown
Collaborator

Scanning the pairing QR from the iOS app was slow to lock on.

Two changes, one per side of the scan:

  • macOS pairing window: the QR rendered at 220pt and the bitmap was generated at 1x, so Retina screens showed a nearest-neighbor 2x upscale. It now renders at 340pt (window grown 640 -> 760 to fit) and the bitmap is generated at the display's backing scale with samplingNearest() through the scale transform, so modules are both physically larger and hard-edged.
  • iOS scanner (QRCodeCaptureController): restrict autoFocusRangeRestriction to .near when supported. Pairing codes are scanned off a screen at arm's length; the near restriction stops the lens from hunting through far focus, which is the usual cause of a slow QR lock. Best-effort and guarded by isAutoFocusRangeRestrictionSupported.

No payload change (the compact short-key ticket coder already minimizes QR version). No new user-facing strings, so no localization changes. A meaningful automated test is not practical for either change (render size and camera focus optics); verified by dogfood.

🤖 Generated with Claude Code


View with Codesmith Autofix with Codesmith
Need help on this PR? Tag /codesmith with what you need. Autofix is disabled.


Summary by cubic

Superseded by the minimal pairing QR redesign on main. After merging main, this branch no longer changes macOS QR rendering or iOS scanner behavior.

Written for commit bd4c9e5. Summary will update on new commits.

Review in cubic

Summary by CodeRabbit

  • Improvements
    • Enhanced QR code autofocus during capture for improved scanning reliability
    • Improved QR code rendering quality with better pixel scaling
    • Increased QR code display size to improve scanning distance and speed
    • Enlarged pairing window for better visibility

The Mac pairing window rendered the QR at 220pt and at 1x, so on Retina
screens the phone saw a small, nearest-neighbor-doubled code. Render it
at 340pt at the display's backing scale (nearest sampling through the
scale so modules stay hard-edged) and grow the window to fit. On iOS,
restrict the scanner's autofocus to the near range so the lens stops
hunting through far focus when pointed at a screen at arm's length.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@vercel

vercel Bot commented Jun 11, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
cmux Ready Ready Preview, Comment Jun 11, 2026 4:14am
cmux-staging Building Building Preview, Comment Jun 11, 2026 4:14am

@coderabbitai

coderabbitai Bot commented Jun 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: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 9a5a9c5d-cdea-4032-9ddc-0e2b98857ca2

📥 Commits

Reviewing files that changed from the base of the PR and between 0254e79 and f59baef.

📒 Files selected for processing (4)
  • Packages/CmuxMobileCamera/Sources/CmuxMobileCamera/QRCodeCaptureController.swift
  • Sources/Mobile/Pairing/MobilePairingQRImageView.swift
  • Sources/Mobile/Pairing/MobilePairingView.swift
  • Sources/Mobile/Pairing/MobilePairingWindowController.swift

📝 Walkthrough

Walkthrough

The PR improves QR code pairing by enhancing both the capture and display sides: the camera now restricts autofocus to the near range for better scanning reliability, while the QR image rendering incorporates device pixel scaling and sharp-edge sampling, and the displayed code is enlarged with corresponding window resizing.

Changes

QR Pairing Display and Capture Optimization

Layer / File(s) Summary
Camera autofocus range restriction
Packages/CmuxMobileCamera/Sources/CmuxMobileCamera/QRCodeCaptureController.swift
QRCodeCaptureController applies best-effort autofocus range restriction to .near during capture session configuration to optimize focus for near-range QR scanning.
QR image rendering with displayScale and sampling
Sources/Mobile/Pairing/MobilePairingQRImageView.swift
MobilePairingQRImageView adds @Environment(\.displayScale) dependency to account for screen backing-store scale, incorporates it into the QR scaling calculation, and applies nearest-neighbor sampling to preserve sharp QR module edges instead of feathering.
QR display dimension and window sizing
Sources/Mobile/Pairing/MobilePairingView.swift, Sources/Mobile/Pairing/MobilePairingWindowController.swift
MobilePairingView increases the QR code dimension from 220 to 340 with documentation explaining the improved scanning distance and speed, and MobilePairingWindowController raises the pairing window height from 640 to 760 to accommodate the larger code.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Possibly related PRs

  • manaflow-ai/cmux#5493: Introduces the iOS pairing window UI components (MobilePairingWindowController, MobilePairingView, MobilePairingQRImageView) that this PR refines with sizing and rendering improvements.

Poem

📱 A rabbit hops to scan QR codes so fine,
With sharper edges and a scale divine,
The window grows, the focus comes near,
Better scanning distance, crystal clear! ✨


Important

Pre-merge checks failed

Please resolve all errors before merging. Addressing warnings is optional.

❌ Failed checks (2 errors, 1 warning)

Check name Status Explanation Resolution
Cmux Full Internationalization ❌ Error Resources/Localizable.xcstrings additions: 30 new mobile.pairing keys have only 2 locales (en, ja) but catalog supports 20 locales, missing 18. Add translated entries for all 20 supported locales (ar, bs, da, de, es, fr, it, km, ko, nb, pl, pt-BR, ru, th, tr, uk, zh-Hans, zh-Hant) to each of the 30 mobile.pairing.* keys in Resources/Localizable.xcstrings.
Cmux Swift Auxiliary Window Close Shortcuts ❌ Error PR adds user-visible NSWindow in MobilePairingWindowController with identifier "cmux.mobilePairingWindow" but doesn't register it in cmuxAuxiliaryWindowIdentifiers in Sources/cmuxApp.swift. Register "cmux.mobilePairingWindow" in cmuxAuxiliaryWindowIdentifiers in Sources/cmuxApp.swift so Cmd+W closes this pairing window correctly.
Docstring Coverage ⚠️ Warning Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (18 passed)
Check name Status Explanation
Title check ✅ Passed The title 'Make the pairing QR bigger and faster to scan' directly and clearly summarizes the main objectives: increasing QR size for better visibility and restricting autofocus for faster scanning.
Description check ✅ Passed The description comprehensively covers what changed, why, and notes that automated testing is impractical with dogfooding verification mentioned, but lacks the testing section structure and demo video from the template.
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.
Cmux Swift Actor Isolation ✅ Passed All changes properly handle Swift 6 actor isolation. SwiftUI View types allowed implicitly on MainActor, @MainActor class properly marked, and no new shared mutable Sendable or background context v...
Cmux Swift Blocking Runtime ✅ Passed PR introduces no blocking/timing-based synchronization. AVCaptureDevice.lockForConfiguration() in QRCodeCaptureController is an Apple AVFoundation framework synchronization primitive for device con...
Cmux Expensive Synchronous Load ✅ Passed PR adds no expensive synchronous loaders. Changes are device configuration (autofocus), QR image generation (computational, not I/O), and UI dimension constants. No disk/sysctl/loader operations ma...
Cmux Cache Substitution Correctness ✅ Passed PR contains no cache substitutions in persistence/history/undo/snapshot paths. Changes are UI rendering and device configuration updates with fresh environment reads, not cached value substitutions.
Cmux No Hacky Sleeps ✅ Passed Custom check applies only to non-Swift code (TypeScript, JavaScript, shell, build/runtime scripts), but this PR contains only Swift file changes in pairing and QR camera modules with no sleep/timin...
Cmux Algorithmic Complexity ✅ Passed The PR contains only configuration changes, UI dimension updates, and Core Image operations with no nested collection scans, batch rescans, or algorithmic complexity issues. NSApp.windows.first is...
Cmux Swift Concurrency ✅ Passed DispatchQueue usage in QRCodeCaptureController is required for AVFoundation API boundary (OS-level requirement), not for ordinary async work. No Combine, fire-and-forget Tasks, or completion-handle...
Cmux Swift @Concurrent ✅ Passed All Swift changes are new files with no async/concurrent isolation violations. The only async work properly inherits the caller's @MainActor context (intentional UI-bound coordination).
Cmux Swift File And Package Boundaries ✅ Passed All four new Swift files are under 400 lines with clear single responsibilities, have proper package/app boundaries, and do not mix unrelated concerns—conforming to `.github/review-bot-rules/swift-...
Cmux Swift Logging ✅ Passed No logging violations found. The PR changes QR code rendering and window sizing without introducing print, debugPrint, dump, NSLog, or ad hoc file logging in any modified files.
Cmux User-Facing Error Privacy ✅ Passed PR contains no new user-facing error messages, alerts, or text that exposes sensitive information. Changes are technical implementations for QR rendering/autofocus improvements with only implementa...
Cmux Swiftui State Layout ✅ Passed All SwiftUI changes comply with state layout rules: no new ObservableObject/@published state, no GeometryReader layout changes, no lazy row store references, and no render-time mutations. Existing...
Cmux Architecture Rethink ✅ Passed PR introduces small correctness fixes with clear owners and required platform bridges. lockForConfiguration() is documented AVFoundation API usage, not a symptom patch. No timing hacks, observers,...
Cmux Source Artifacts ✅ Passed All four changed files are hand-written Swift source code in proper source directories with no artifact patterns or generated file markers, representing intentional product functionality improvements.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat-pairing-qr-scan

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 and usage tips.

@greptile-apps

greptile-apps Bot commented Jun 11, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR improves QR-code scan speed on both sides of the pairing handshake — the macOS window now generates a Retina-native bitmap at the display's backing scale with hard module edges (samplingNearest), and the iOS scanner restricts autofocus to the near range to prevent the lens hunting past the screen distance.

  • macOS renderer (MobilePairingQRImageView): @Environment(\.displayScale) drives a higher-resolution CIImage pipeline (dimension × scale pixels) with samplingNearest() before the scale transform; the window grows 640→760pt to fit the enlarged 340pt QR.
  • iOS scanner (QRCodeCaptureController): autoFocusRangeRestriction = .near is applied once during session configuration, guarded by isAutoFocusRangeRestrictionSupported, so devices that don't support it fall through gracefully.

Confidence Score: 4/5

Safe to merge; both changes are narrowly scoped, best-effort on the iOS side, and leave the payload and scan protocol untouched.

The only notable issue is that CIContext() is created fresh on each qrImage evaluation — now at up to 680×680 pixels — rather than reusing a shared context. In practice SwiftUI struct-equality prevents frequent recomputation, so this is unlikely to be user-visible, but it is an avoidable allocation. Everything else — the autofocus guard, the samplingNearest pipeline, the window resize arithmetic — is well-reasoned and correct.

Sources/Mobile/Pairing/MobilePairingQRImageView.swift — the CIContext allocation pattern is worth a second look.

Important Files Changed

Filename Overview
Packages/CmuxMobileCamera/Sources/CmuxMobileCamera/QRCodeCaptureController.swift Adds autofocus near-restriction for iOS scanner; correctly guarded by capability check and best-effort lock pattern. No new actor isolation, blocking, or concurrency issues.
Sources/Mobile/Pairing/MobilePairingQRImageView.swift Adds @Environment(.displayScale) and scales the CIContext bitmap to native pixels; correctly uses samplingNearest(). A new CIContext() is allocated on every body evaluation without caching, and the 2× bitmap makes each allocation more expensive.
Sources/Mobile/Pairing/MobilePairingView.swift QR dimension bumped 220→340pt; comment correctly explains the motivation. No state or layout concerns introduced.
Sources/Mobile/Pairing/MobilePairingWindowController.swift Window height increased 640→760 to accommodate larger QR (+120pt matches QR delta exactly). No other changes.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    subgraph macOS_side["macOS – MobilePairingWindowController"]
        A["show()"] --> B["NSWindow 460x760"]
        B --> C["MobilePairingView\ndimension: 340pt"]
        C --> D["MobilePairingQRImageView"]
        D --> E["displayScale env\ne.g. 2.0 Retina"]
        E --> F["CIQRCodeGenerator\ncorrectionLevel L"]
        F --> G["samplingNearest\nscale = 340 x 2 / extent\n-> 680x680 px bitmap"]
        G --> H["NSImage size=340x340pt\nnative @2x"]
    end

    subgraph ios_side["iOS – QRCodeCaptureController"]
        I["viewDidLoad"] --> J["configureSession"]
        J --> K{"isAutoFocusRange\nRestrictionSupported?"}
        K -- Yes --> L["lock / set .near / unlock"]
        K -- No --> M["skip, scan still works"]
        L --> N["AVCaptureMetadataOutput\nQR scanning"]
        M --> N
    end

    H -- shown on screen --> ios_side
Loading

Reviews (1): Last reviewed commit: "Make the pairing QR bigger and faster to..." | Re-trigger Greptile

Comment on lines 71 to 72
let context = CIContext()
guard let cgImage = context.createCGImage(scaled, from: scaled.extent) else {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P2 A new CIContext() is allocated on every invocation of qrImage. CIContext initialization involves GPU pipeline setup and is one of the more expensive Core Image operations — Apple's documentation explicitly recommends reusing a single context. With the resolution now at dimension * displayScale (up to 680 × 680 pixels), each call is heavier than before. Because qrImage is a plain computed var called from body, SwiftUI's struct-equality diffing prevents redundant calls in practice, but any parent state update that causes the view's inputs to change (payload refresh, display-scale change) will recreate the context from scratch. A static or lazily-initialized shared context would avoid the allocation entirely.

Suggested change
let context = CIContext()
guard let cgImage = context.createCGImage(scaled, from: scaled.extent) else {
let context = CIContext.shared
guard let cgImage = context.createCGImage(scaled, from: scaled.extent) else {

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

Main landed #5872 (full-width
native-module QR render, routes-only payload) and scanner tuning that is
a superset of this branch's near-focus restriction, so this merge takes
main's side everywhere. The branch now carries no changes.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@azooz2003-bit

Copy link
Copy Markdown
Collaborator Author

Superseded by #5872, which landed a strictly better version of both halves: full-width native-module QR render on macOS (vs this PR's fixed 340pt) and iOS scanner tuning (multi-lens camera selection + near-range autofocus + exposure tuning, a superset of this PR's near-focus restriction). Branch merged to main's state; diff is empty.

This branch was successfully deployed

1 active deployment
Preview – cmux — bd4c9e56 Deployed Jun 12, 2026 by vercel[bot]
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