Skip to content

fix(app): hide WebKit's form bar over the keyboard in the iOS app - #2109

Merged
devswha merged 1 commit into
mainfrom
fix/ios-hide-form-accessory-bar
Oct 28, 2026
Merged

devswha merged 1 commit into
mainfrom
fix/ios-hide-form-accessory-bar

Conversation

@devswha

@devswha devswha commented Oct 28, 2026

Copy link
Copy Markdown
Owner

Change

Fixes #2043, reported by @mikedeanlive. Thanks for the clear write-up and the two proposed ways to fix it.

The iOS app showed WebKit's form accessory bar (the up and down arrows and the check mark) every time the keyboard opened. It sat on top of the client's own key bar, so a phone had two bars stacked over the keyboard and lost another row of screen. A page cannot remove it; only the native shell can.

HerdrBridgeViewController now returns its web view from Capacitor's webView(with:configuration:) factory as a small WKWebView subclass whose inputAccessoryView is nil. WebKit's WKContentView asks its web view for the keyboard's accessory view (return [_webView.get() inputAccessoryView], added by WebKit 47455a2a, "Allow clients to vend custom -inputView and -inputAccessoryView by overriding WKWebView methods", 2019, iOS 13), so this hides the bar through public API. The app's deployment target is iOS 15.

  • No new dependency and no lockfile change: @capacitor/keyboard's hideFormAccessoryBar does the same by swapping a method on WebKit's private WKContentView. An earlier version of this branch did that too; review pointed out the App Review and OS risk of patching a private class, so it uses the public override instead.
  • Only Ovis's own web views change. SFSafariViewController (links opened in Safari) and native controls are untouched.
  • <select> controls keep working: since iOS 15 WebKit shows them as menus that close on a choice or a tap outside, not as a picker wheel whose Done sits in the bar.
  • Android is untouched (no file under app/android).
  • docs/native-app.md notes it, and changelog.d/ios-hide-form-accessory-bar.md has the entry.

This is a native change: it reaches users only with the next iOS app build (TestFlight / App Store). The web client and the servers are unchanged, so no remote bundle is involved.

Validation

On the test MacBook Air (eamac: macOS 27.0.1, Xcode 27.0), in a fresh clone under /tmp, on a lane-owned iPhone 18 Pro simulator (iOS 27.0). Both builds were Debug, unsigned (bun run sync, then xcodebuild -scheme App -sdk iphonesimulator CODE_SIGNING_ALLOWED=NO). Every tap and keystroke was a real touch through WebDriverAgent; the bar was read both from the screenshot and from the accessibility tree (XCUIElementTypeToolbar).

Scenario main (65ffea69) this branch
Connect screen, tap the PC address field bar shown: 1 toolbar, 48 pt above the keyboard no bar: 0 toolbars, keyboard directly under the page
Type abc into that field field reads abc field reads abc
Open a PC that does not answer (http://127.0.0.1:9), Change PC on the cover, tap the field again (two new view controllers and web views) - no bar, 0 toolbars, typing works
Demo, tap the chat composer, type hello - no bar over the key bar, 0 toolbars, composer reads hello
Demo, Settings > Appearance > Language select: open, pick English - opens as an iOS menu (no picker wheel, no toolbar); picking English closes it and the panel switches to English
  • The Swift file built on eamac is byte-identical to this commit (sha256 compared).
  • bun run check fast: green on the change (typecheck, build, 7756 unit tests pass). A second run on the final commit, with the host at load about 100 of 128, had one failure in a file this PR does not touch: scripts/ci-browser.test.ts "keeps only cheap existing screenshots when CHECK_DIR is set" was killed at its 5 s spawn timeout (exit 143; its siblings took 4 to 4.8 s in that run). Alone it passes 7 of 7 (2.2 s for that case).
  • Reviews: omo code reviewer (approve, no HIGH; its LOW wording notes are applied) and Codex (gpt-6.1-sol, xhigh), two rounds. Round 1 raised the private-API patch as MEDIUM, which led to the public override; round 2 on the new code had no findings.
  • Not tested: a physical iPhone, an iOS 15 to 26 runtime (the WebKit forwarding was read in source for those releases), and an external hardware keyboard.

The iOS app showed WebKit's form accessory bar (the up and down arrows
and the check mark) every time the keyboard opened, stacked over the
client's own key bar and taking another row of a phone's screen. A page
cannot remove it.

HerdrBridgeViewController now builds its web view as a WKWebView
subclass whose inputAccessoryView is nil. WKContentView asks its web
view for the keyboard's accessory view (WebKit 47455a2a, iOS 13), so
this hides the bar through public API, without @capacitor/keyboard or
its patch of WebKit's private content view.

Fixes #2043
@coderabbitai

coderabbitai Bot commented Oct 28, 2026

Copy link
Copy Markdown

Warning

Review limit reached

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Next included review available in 2 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used all 4 included reviews currently available.

Learn how review limits work.

Review configuration:

Run configuration
Commits

Reviewing files that changed from the base of the PR and between 1953194 and 294ea0c.

Files selected for processing: 3
  • app/ios/App/App/HerdrBridgeViewController.swift
  • changelog.d/ios-hide-form-accessory-bar.md
  • docs/native-app.md
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

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.

@devswha

devswha commented Oct 28, 2026

Copy link
Copy Markdown
Owner Author

Merging 294ea0c: omo-native-code-reviewer and Codex both pass this head, and the required checks are green. CodeRabbit did not review this head. Neither reviewer could run iOS here; both reviewed the Swift by reading. The keyboard-dismiss trade-off they raised goes to a follow-up issue.

@devswha
devswha merged commit a6353f2 into main Oct 28, 2026
11 checks passed
@devswha
devswha deleted the fix/ios-hide-form-accessory-bar branch October 28, 2026 01:09
@coderabbitai coderabbitai Bot mentioned this pull request Oct 29, 2026
5 tasks
devswha added a commit that referenced this pull request Oct 29, 2026
## Release 0.4.20

The release PR, prepared by step 1 of
[docs/development.md#releasing](https://github.com/devswha/ovis/blob/main/docs/development.md#releasing),
initially on main `bd676637a16471e8744d62c7311026ddb43a39eb` (#2335,
xterm 6), then merged with final-scope main
`ef482f2e66b3344658fb548fa1110744a92929c9` (#2338) and test-only
follow-up main `269e9ce19558b8d197959250075da56b25b9668f` (#2345):

- **Version:** `version` is 0.4.20 in `package.json` and
`herdr-plugin.toml`.
- **Changelog:** `bun scripts/changelog-fold.ts 0.4.20` initially folded
122 fragments into the 2026-10-29 section of `CHANGELOG.md`, linked
their PRs, and deleted the fragments. After merging main, the modified
`letta-native-chat.md` from #2338 was folded by hand with its current
wording and PR link. No other late fragment landed; `changelog.d` holds
only `README.md`. Four additional entries for external PRs without their
own fragments bring the section to 157 entries.
- Added 22 `by @login` credits across all 19 outside-contributor PRs in
the release range. Preserved the existing credit to @Yoonwoo-Ha for
#1634. See the complete ancestry-based audit below.
- **Release summaries:** en, ko, ja and zh each have 5 new, 5 improved
and 5 fixed lines, matching 0.4.19's shape. They include the xterm 6
improvement: terminal frames no longer mix old and new output. Every
English line is at most 80 characters.
- **Remote bundle:** `REMOTE_BUNDLE_VERSION` rises from 38 to 39 because
the bundle inputs changed since remote-v38.
- **Telemetry:** the guard confirms no Worker deploy or deployed
fingerprint update is needed.
- **iOS upload note:** CURRENT_PROJECT_VERSION raised to 3 for App and
OvisNotifications (last uploaded: 2, source: `docs/native-app.md:99`,
commit `54fdadc1c65da5d50a6afef411e3ed8f23b6c255`). Both targets inherit
project-level Debug and Release settings, and every
`CURRENT_PROJECT_VERSION` entry is 3. `app/store/ios.md` now records the
prepared build. This is the last documented upload, not a live App Store
Connect query; check for later uploads before uploading. The marketing
version remains 1.0.
- The changelog explicitly distinguishes delivery: removing WebKit's
form bar (#2109) requires the new iOS app build, while Korean
composition (#2307) comes with the PC update and needs no new iOS build.
The Korean-input summary says the same in all four languages, with no
change to list counts.

## Validation

- Final `dori heavy release-check -- bun run check fast`: passed, exit
0; workflow syntax, generated types/themes, typecheck, build and unit
suite (8,591 pass, 0 fail, 34 platform skips in 549 files). This is the
merged tree containing #2338, #2345, the contributor corrections and iOS
build 3.
- `bun test scripts/changelog-fold.test.ts
server/release-notes.test.ts`: 33 pass, 0 fail.
- `bun scripts/release-notes.ts 0.4.20`: passed, with all patch-note
lists and the full changelog.
- `bun scripts/release-guards.ts` and CI mode with `--base
ef482f2`: passed on the final merged
tree: "Release 0.4.20: remote bundle, telemetry Worker and release
metadata are in order."
- `bun scripts/release-guards.ts --release 0.4.20`: expected exit 1 only
because "remote-v39 is not published." The merge pass publishes it after
merging.

## Merge pass

**Do not merge before the owner's OK.**

- [ ] Merge only after the owner's OK and required checks pass.
- [ ] After merging, push `remote-v39` on the merged commit and wait for
the **Remote PC bundles** workflow to publish the manifest and all
archives.
- [ ] Then run **Release** on `main` with version `0.4.20`, without `v`.
The Release workflow creates the app tag; do not push it by hand.
- [ ] From this PR's merge until the Release run is done, merge nothing
touching `server/`, `shared/`, `bun.lock` or `patches/`.
- [ ] A changelog fragment merged after this PR must be moved into
0.4.20 by hand.

This lane stops at the open PR. No tag, workflow dispatch, merge or
telemetry deploy was performed.

**Completed release follow-up:** merged main `ef482f2e` including #2338
(`fix/letta-no-live-box`), folded its revised fragment into 0.4.20, and
retained the contributor-credit commit `184dc120` and iOS-build commit
`0ffa3d45`. The Letta summary already describes conversation support
without promising a live-terminal box, so it needs no change.

Merged test-only #2345 from main `269e9ce1`: the two usage browser
checks now wait for the earlier shared account-order save and start the
sign-in check from a cleared order. No product behavior or late fragment
was added; `changelog.d` still contains only `README.md`. The iOS
delivery clarification and resolved review thread are retained.

## Complete external-contributor audit

Checked every merged PR whose merge commit is in `git log
v0.4.19..origin/main`: 133 PRs through final-scope main `ef482f2e`, or
134 including test-only #2345 on `269e9ce1`, with 19 PRs by 12 external
non-bot authors. Both rescans found no additional external-author gaps;
#2345 is by the maintainer. Added the four missing entries: #2271 and
#2274 by @CharleoYang, #2290 by @DravenDou, and #2282 by @fivetaku. The
tab-reopening summary now includes the history-page improvement in all
four languages; list counts remain 5/5/5.

Full external PR list checked: #1911 @jjsteffen; #2068 @YuuuXie; #2072
@Noobear; #2087 @JJLiebig; #2145 @mattmarcin; #2176 @jpcarranza94; #2231
@philipprass-prog; #2235 @vuongnmhvn; #2270, #2271, #2274 @CharleoYang;
#2278 @jpcarranza94; #2282 @fivetaku; #2283, #2292, #2293 @YuuuXie;
#2301 @jpcarranza94; #2321 @kilhyeonjun. Every PR has a linked `by
@login` credit in 0.4.20.

---------

Co-authored-by: sisyphus-dev-ai <sisyphus-dev-ai@users.noreply.github.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.

iOS app: hide the keyboard form accessory bar (⌃ ⌄ ✓) above the keyboard

1 participant