[PR #6407] Fix iOS 18.2 keyboard dismissal by deferring setSelectionRange #6499

Closed
opened 2026-02-28 21:29:12 -06:00 by GiteaMirror · 0 comments
Owner

Original Pull Request: https://github.com/actualbudget/actual/pull/6407

State: closed
Merged: No


Description

iOS 18.2 introduced an issue where calling setSelectionRange() synchronously after focusing an input causes the virtual keyboard to dismiss immediately.

Changes

Root fix in useProperFocus.tsx:

Deferred setSelectionRange() call to the next event loop tick to allow the keyboard to fully appear:

if (el instanceof HTMLInputElement) {
  // Use setTimeout to avoid iOS keyboard issues
  // On iOS 18.2, calling setSelectionRange synchronously can cause the keyboard to dismiss
  setTimeout(() => {
    try {
      el.setSelectionRange(0, 10000);
    } catch {
      // Ignore errors on inputs that don't support selection ranges (e.g., number inputs)
    }
  }, 0);
}

Additional defensive measures in table.tsx:

  • Added timestamp-based protection in the InputValue component to ignore blur events within 150ms of focus
  • Updated fireBlur() function to check e.relatedTarget in addition to document.hasFocus()
  • Applied same logic to CustomCell.onBlur_() for consistency

The fix prevents the keyboard from dismissing on iOS 18.2 while preserving normal behavior for:

  • User interactions (clicking away, tabbing)
  • App backgrounding
  • Navigation between fields
  • Text selection (just deferred by a few milliseconds)

Testing

  • All existing tests pass (20 tests)
  • TypeScript compilation passes
  • Linting passes
  • Security scan passes

The 150ms protection window is extracted as a named constant (IOS_KEYBOARD_BLUR_PROTECTION_MS) for maintainability and future adjustments.

Original prompt

This section details on the original issue you should resolve

<issue_title>[Bug]: iOS26.2 Update</issue_title>
<issue_description>### Verified issue does not already exist?

  • I have searched and found no existing issue

What happened?

I upgraded to iOS 26.2 this morning. Following some reports on Discord, I tested Actual. I have not experienced all the issues that others have BUT:
Specifically if I try to edit the assignment to a budget the keyboard comes up and then immediately disappears again. This happens to me in Safari and Firefox (and of course in the PWA).

How can we reproduce the issue?

Upgrade to iOs26.2 and try Actual.

Where are you hosting Actual?

Fly.io

What browsers are you seeing the problem on?

Safari

Operating System

Mobile Device</issue_description>

Comments on the Issue (you are @copilot in this section)

@MatissJanis Can reproduce on 26.2. Could not reproduce on 26.1.

https://github.com/user-attachments/assets/b5e9e05e-15af-4c3c-951d-e435eb3d2eaf</comment_new>


Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

**Original Pull Request:** https://github.com/actualbudget/actual/pull/6407 **State:** closed **Merged:** No --- ## Description iOS 18.2 introduced an issue where calling `setSelectionRange()` synchronously after focusing an input causes the virtual keyboard to dismiss immediately. ### Changes **Root fix in `useProperFocus.tsx`:** Deferred `setSelectionRange()` call to the next event loop tick to allow the keyboard to fully appear: ```typescript if (el instanceof HTMLInputElement) { // Use setTimeout to avoid iOS keyboard issues // On iOS 18.2, calling setSelectionRange synchronously can cause the keyboard to dismiss setTimeout(() => { try { el.setSelectionRange(0, 10000); } catch { // Ignore errors on inputs that don't support selection ranges (e.g., number inputs) } }, 0); } ``` **Additional defensive measures in `table.tsx`:** - Added timestamp-based protection in the `InputValue` component to ignore blur events within 150ms of focus - Updated `fireBlur()` function to check `e.relatedTarget` in addition to `document.hasFocus()` - Applied same logic to `CustomCell.onBlur_()` for consistency The fix prevents the keyboard from dismissing on iOS 18.2 while preserving normal behavior for: - User interactions (clicking away, tabbing) - App backgrounding - Navigation between fields - Text selection (just deferred by a few milliseconds) ### Testing - ✅ All existing tests pass (20 tests) - ✅ TypeScript compilation passes - ✅ Linting passes - ✅ Security scan passes The 150ms protection window is extracted as a named constant (`IOS_KEYBOARD_BLUR_PROTECTION_MS`) for maintainability and future adjustments. <!-- START COPILOT ORIGINAL PROMPT --> <details> <summary>Original prompt</summary> > > ---- > > *This section details on the original issue you should resolve* > > <issue_title>[Bug]: iOS26.2 Update</issue_title> > <issue_description>### Verified issue does not already exist? > > - [x] I have searched and found no existing issue > > ### What happened? > > I upgraded to iOS 26.2 this morning. Following some reports on Discord, I tested Actual. I have not experienced all the issues that others have BUT: > Specifically if I try to edit the assignment to a budget the keyboard comes up and then immediately disappears again. This happens to me in Safari and Firefox (and of course in the PWA). > > ### How can we reproduce the issue? > > Upgrade to iOs26.2 and try Actual. > > ### Where are you hosting Actual? > > Fly.io > > ### What browsers are you seeing the problem on? > > Safari > > ### Operating System > > Mobile Device</issue_description> > > ## Comments on the Issue (you are @copilot in this section) > > <comments> > <comment_new><author>@MatissJanis</author><body> > Can reproduce on 26.2. Could not reproduce on 26.1. > > https://github.com/user-attachments/assets/b5e9e05e-15af-4c3c-951d-e435eb3d2eaf</body></comment_new> > </comments> > </details> <!-- START COPILOT CODING AGENT SUFFIX --> - Fixes actualbudget/actual#6387 <!-- START COPILOT CODING AGENT TIPS --> --- ✨ Let Copilot coding agent [set things up for you](https://github.com/actualbudget/actual/issues/new?title=✨+Set+up+Copilot+instructions&body=Configure%20instructions%20for%20this%20repository%20as%20documented%20in%20%5BBest%20practices%20for%20Copilot%20coding%20agent%20in%20your%20repository%5D%28https://gh.io/copilot-coding-agent-tips%29%2E%0A%0A%3COnboard%20this%20repo%3E&assignees=copilot) — coding agent works faster and does higher quality work when set up for your repo.
GiteaMirror added the pull-request label 2026-02-28 21:29:12 -06:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/actual#6499