Skip to content

fix(launcher): Modal focus stealing during polling-induced re-renders - #569

Open
chundaoketa wants to merge 1 commit into
openagents-org:developfrom
chundaoketa:develop
Open

fix(launcher): Modal focus stealing during polling-induced re-renders#569
chundaoketa wants to merge 1 commit into
openagents-org:developfrom
chundaoketa:develop

Conversation

@chundaoketa

Copy link
Copy Markdown

Problem

In any dialog (New Agent, Configure, Connect, Delete confirmation, etc.), clicking an input field that is not the first one causes focus to jump back to the first input after a few seconds. This happens on all pages with open dialogs.

Root Cause

The Modal component useEffect had [open, onClose] as dependencies. When parent components pass inline arrow functions as onClose (the common pattern across all pages), any parent re-render changes onClose reference identity. This triggers:

  1. Effect cleanup -> calls previouslyFocused.focus() - restores focus to the element outside the dialog
  2. Effect re-runs -> detects activeElement is no longer inside the panel -> focuses the first focusable child

Pages like agents (5s polling), workspaces (8s), and logs (3s) all have setInterval that triggers re-renders, making the dialog focus jump back to the first input every few seconds while a dialog is open.

Fix

  1. Store onClose in a ref (onCloseRef) so the effect no longer depends on its reference identity
  2. Remove onClose from the effect dependency array ([open] only)
  3. Also deduplicate modalStack.push to avoid accumulating duplicate entries on effect re-runs

Files Changed

  • packages/launcher/src/renderer/components/ui/Modal.tsx

The Modal useEffect had [open, onClose] as dependencies. When parent
components pass inline arrow functions as onClose (which is the common
pattern across all pages), any parent re-render changes onClose's
reference identity. This triggers the useEffect cleanup function which
calls previouslyFocused?.focus() — restoring focus to the element
outside the dialog — then re-runs the effect which detects
activeElement is no longer inside the panel and forcibly focuses the
first focusable child.

Pages like agents (5s polling), workspaces (8s), and logs (3s) all
have setInterval that triggers re-renders, making the dialog's focus
jump back to the first input every few seconds while a dialog is open.

Fix: Store onClose in a ref (onCloseRef) so the effect no longer
depends on its identity. Also deduplicate modalStack pushes to avoid
accumulation on effect re-runs.
@vercel

vercel Bot commented Jul 27, 2026

Copy link
Copy Markdown

@chundaoketa is attempting to deploy a commit to the Raphael's projects Team on Vercel.

A member of the Team first needs to authorize it.

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