Skip to content

Remove top search bar on iOS Workspaces and Notifications tabs - #9129

Merged
azooz2003-bit merged 1 commit into
mainfrom
feat-ios-no-top-search
Jul 29, 2026
Merged

azooz2003-bit merged 1 commit into
mainfrom
feat-ios-no-top-search

Conversation

@azooz2003-bit

@azooz2003-bit azooz2003-bit commented Jul 29, 2026 •

Copy link
Copy Markdown
Collaborator

The .searchable modifier sat on the primary TabView in MobilePrimaryTabScaffold, so on iOS 26 every tab's NavigationStack inherited it and rendered a second search field pinned to the top of the Workspaces and Notifications tabs, duplicating the bottom tab-bar search. This moves .searchable and its .onSubmit(of: .search) onto the search tab's destination, making the bottom search pill the only search entrypoint. Tab(role: .search) and .tabViewSearchActivation(.searchTabSelection) are unchanged, so pill activation, scope switching (workspaces vs notifications prompt), and submit-to-tab behavior all keep working.

Verified on an iOS 26.5 iPhone 17 Pro Max simulator: Workspaces and Notifications tabs no longer show a top search field; tapping the search pill from either tab presents the bottom search field with the matching scope prompt and keyboard. No automated test added: the field placement is system-rendered chrome with no practical behavior-level assertion, and the search coordinator logic is unchanged and already covered by MobilePrimarySearchCoordinatorTests.

🤖 Generated with Claude Code


View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need. Autofix is disabled.


Summary by cubic

Removed the duplicate top search field on iOS by scoping .searchable to the Search tab content. The bottom search pill is now the only entry point, with activation and submit behavior unchanged.

  • Bug Fixes
    • Moved .searchable and .onSubmit(of: .search) from the TabView to the Search tab destination to prevent inherited nav bar fields on Workspaces and Notifications.
    • Kept Tab(role: .search) and .tabViewSearchActivation(.searchTabSelection) so pill activation, scope prompts, and submit-to-tab still work.
    • Verified on iOS 26.5: no top search field on Workspaces or Notifications; tapping the pill shows the bottom search with the correct scope.

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

Review in cubic

Summary by CodeRabbit

  • Bug Fixes
    • Improved the iOS search experience by ensuring the search field appears only on the Search tab.
    • Prevented duplicate search fields from appearing in other tabs’ navigation bars.
    • Search submissions continue to update results as expected.

The .searchable modifier sat on the primary TabView, so every tab's
NavigationStack inherited it and rendered a second search field at the
top of the Workspaces and Notifications tabs, on top of the iOS 26
bottom search tab. Attach .searchable (and its .onSubmit) to the search
tab's destination instead, so the only search entrypoint is the bottom
tab-bar search pill.

Verified on an iOS 26.5 simulator: no top search field on Workspaces or
Notifications; tapping the search pill from either tab still presents
the bottom search field with the matching scope prompt and keyboard.

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

coderabbitai Bot commented Jul 29, 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 Plus

Run ID: 5346eb61-3d7e-4234-a03b-dbca976f2293

📥 Commits

Reviewing files that changed from the base of the PR and between 4eee8ce and dcca52e.

📒 Files selected for processing (1)
  • Packages/iOS/CmuxMobileShellUI/Sources/CmuxMobileShellUI/MobilePrimaryTabScaffold.swift

📝 Walkthrough

Walkthrough

The iOS 26+ search configuration now applies within the .search tab content instead of the overall TabView, while preserving search submission selection updates.

Changes

iOS search tab scope

Layer / File(s) Summary
Scope search modifiers to the search tab
Packages/iOS/CmuxMobileShellUI/Sources/CmuxMobileShellUI/MobilePrimaryTabScaffold.swift
The .searchable(...) modifier and search submission handler now attach to the search tab’s content, with comments documenting the scoped behavior.

Estimated code review effort: 2 (Simple) | ~10 minutes

Possibly related PRs

Suggested reviewers: austinywang

🚥 Pre-merge checks | ✅ 25
✅ Passed checks (25 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly describes the main change: removing the duplicate top search bar from the affected iOS tabs.
Description check ✅ Passed The description covers the change, rationale, and manual verification, though it omits the demo video, review trigger block, and checklist.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
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 PASS: The patch only relocates SwiftUI .searchable/.onSubmit inside an existing View on the main actor; no new protocols, Sendable refs, or background store access.
Cmux Swift Blocking Runtime ✅ Passed The commit only moves .searchable/.onSubmit within MobilePrimaryTabScaffold; no semaphores, sleeps, sync waits, or locks were added.
Cmux Browser Automation Off-Main ✅ Passed Diff only changes MobilePrimaryTabScaffold.swift; no browser.* routing, worker-lane, or WebKit/AppKit automation code was touched.
Cmux Expensive Synchronous Load ✅ Passed The diff only relocates SwiftUI search modifiers; it adds no disk/JSON/history load, and the @MainActor coordinator remains in-memory state only.
Cmux Cache Substitution Correctness ✅ Passed UI-only search-scaffold change; no fresh-authoritative read was replaced by a cache in any persistence/history/undo/snapshot path.
Cmux No Hacky Sleeps ✅ Passed PASS: the touched file is Swift, the rule excludes Swift timing/blocking primitives, and the diff only moves searchable/onSubmit UI with no sleeps/timers.
Cmux Algorithmic Complexity ✅ Passed PASS: The diff only relocates .searchable/submit handlers in MobilePrimaryTabScaffold; it adds no collection scans, sorting, batching, or hot-path loops.
Cmux Swift Concurrency ✅ Passed Diff only scopes SwiftUI search modifiers; no DispatchQueue, Combine, completion handlers, or fire-and-forget Tasks were introduced or expanded.
Cmux Swift @Concurrent ✅ Passed Diff only relocates .searchable/.onSubmit into the search tab; no async or @concurrent changes were introduced.
Cmux Swift Package Boundaries ✅ Passed The diff only moves SwiftUI search modifiers in MobilePrimaryTabScaffold, a UI/composition view in CmuxMobileShellUI; no reusable domain logic is kept in an app target.
Cmux Swiftpm Lockfiles ✅ Passed Only MobilePrimaryTabScaffold.swift changed; no Package.swift, Package.resolved, .gitignore, workflow, or Xcode package-reference files were touched.
Cmux Swift Logging ✅ Passed The diff adds no print/debugPrint/dump/NSLog/Logger usage; it only relocates .searchable and adds comments.
Cmux User-Facing Error Privacy ✅ Passed Diff only moves .searchable and adds developer comments; no user-facing errors or sensitive provider details are introduced.
Cmux Full Internationalization ✅ Passed The change only re-scopes existing .searchable logic and adds developer comments; no new user-facing strings or locale entries were introduced.
Cmux Swiftui State Layout ✅ Passed Diff only moves .searchable/.onSubmit into the search tab; no new ObservableObject/@Published/GeometryReader/lazy-row store refs or render-time state writes.
Cmux Architecture Rethink ✅ Passed Small local fix: searchable moved to the search tab, no sleeps/observers/extra owners introduced, and MobilePrimarySearchCoordinator stays the source of truth.
Cmux Swift Auxiliary Window Close Shortcuts ✅ Passed MobilePrimaryTabScaffold only moves SwiftUI search modifiers on a TabView/Tab; no NSWindow/WindowGroup/WindowController or cmuxAuxiliaryWindowIdentifiers changes.
Cmux Source Artifacts ✅ Passed Only a Swift source file changed; no logs, screenshots, caches, build output, or artifact directories appear in the diff.
Cmux No Test Or Debug Seam In Production Source ✅ Passed The diff only moves .searchable/.onSubmit into the search tab; no DEBUG guards or test/debug-only hooks were added to the production Sources file.
Cmux No Ambient Global State ✅ Passed Diff only relocates .searchable/onSubmit inside an existing View struct; no new top-level funcs, mutable vars, or singletons were added.
✨ 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-ios-no-top-search

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.

@azooz2003-bit
azooz2003-bit merged commit 058dc30 into main Jul 29, 2026
6 checks passed
@azooz2003-bit
azooz2003-bit deleted the feat-ios-no-top-search branch July 29, 2026 06:34
azooz2003-bit added a commit that referenced this pull request Aug 1, 2026
Since search became its own tab (#9129), the workspaces/notifications
NavigationStack is unmounted while search is active. The eager
onChange consume mutated the navigation path with no registered
destination, SwiftUI popped it back, and the pending ID was already
cleared, so the mount-time onAppear retry found nothing: selecting a
search result landed on the tab root without opening the workspace.
Instrumented run 30688718660 proved the select action fires and search
dismisses while the push vanishes.

Keep the pending ID armed through consume and clear it from the pushed
destination's onAppear instead, so the stack's onAppear re-issues the
path once the tab content is mounted. Split layout clears immediately
(no push involved). The layout-preview fixture mirrors the same change.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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