Skip to content

[Bug]: preview_click steals focus from the desktop composer #21954

Open
azatakmyradov/t3code
#48

Description

@gregbartell

Written by a human: per Julius' / Grok's request on #3715 (#3715 (comment)), I'm opening the "agents' use of preview_click steals focus from the human in the composer" bug as a separate issue.


Written by an agent:

Agent preview_click calls interrupt a user typing in the composer by moving focus into the browser preview. Reproduced with both a non-editable heading and a text input.

This follows the closing comment on #3715, which says #18556 addresses agent keystrokes reaching the composer and requests a separate issue if preview clicks still steal focus.

Before submitting

  • I searched existing issues and did not find a duplicate.
  • I included enough detail to reproduce or investigate the problem.

Area

apps/desktop

Steps to reproduce

Use a disposable draft because typing can be redirected into the preview.

  1. Open a thread in T3 Code Desktop with the collaborative browser tools available.

  2. Have the agent open a blank preview and retain its returned tabId:

    preview_open({
      open: true,
      reuseExistingTab: false,
      profileId: "incognito"
    })
  3. Install a minimal fixture through preview_evaluate, targeting that tab:

    (() => {
      document.title = "T3 click focus probe";
      document.body.innerHTML = `
        <h1>Click focus probe</h1>
        <label>Name <input id="name" aria-label="Name"></label>
      `;
    })()
  4. Focus the thread’s composer and keep typing a disposable draft.

  5. Have the agent click the heading:

    preview_click({
      tabId,
      locator: "role=heading[name='Click focus probe']"
    })
  6. Check whether typing still reaches the composer.

  7. Refocus the composer and resume typing. Repeat with the preview’s input:

    preview_click({
      tabId,
      locator: "role=textbox[name='Name']"
    })

Expected behavior

The automated click reaches its target in the preview while the user retains keyboard focus in the composer. Subsequent human typing continues editing the draft.

Actual behavior

Both clicks returned success and reached their intended preview targets, but the user reported that each stole composer focus.

Page instrumentation independently recorded trusted click events and subsequent keyboard/input events. The agent sent no keyboard or text-input commands during this click test.

Impact

Major degradation or frequent failure

Version or commit

b34501a

Environment

  • Reproduced October 19, 2026. - Linux x86_64, T3 Code Desktop. - Preview user agent reported T3CodeBeta/0.0, Electron 44.4.5, and Chromium 152.0.7977.130. - Incognito browser preview opened with open: true. - Agent: GPT-6.1-Sol through the Codex harness.

Logs or stack traces

Sanitized page-side click records:


[
  {
    "at": "2026-10-19T21:38:23.246Z",
    "target": "probe-heading",
    "trusted": true
  },
  {
    "at": "2026-10-19T21:38:42.522Z",
    "target": "name",
    "trusted": true
  }
]

Screenshots, recordings, or supporting files

No response

Workaround

No focus-preserving workaround was verified during this reproduction.

Related issues

Activity

  1. added
    bugSomething is broken or behaving incorrectly.
    needs-triageIssue needs maintainer review and initial categorization.
    on Oct 19, 2026
  2. juliusmarminge commented on Oct 19, 2026

    @juliusmarminge
    Member

    Note

    Grok responding on behalf of Julius.

    Thanks for splitting this out with a clean repro.

    This looks like a regression. #15008 fixed the same symptom in early October: the web host remembered what had focus before each agent click and gave it back afterwards. That code lived in the old preview automation host, and it was removed when the preview browser moved to the environment server a few days later. I couldn't find a replacement on current main. The focus handling that exists now covers agent keyboard input reaching the app (apps/desktop/src/preview/GuestInput.ts:1-42), not clicks.

    Clicking a page element does focus it in the page, which is expected, but the app's own focus shouldn't move away from the composer when the agent is the one clicking.

    Accepting this as a bug.

  3. added
    acceptedfeature request accepted
    via-triageFiled through npx t3 triage
    and removed
    needs-triageIssue needs maintainer review and initial categorization.
    on Oct 19, 2026
  4. juliusmarminge commented on Oct 21, 2026

    @juliusmarminge
    Member

    Triage checkout: main at 70e5e384da. This Linux VM has no desktop display. The available collaborative preview reports Chrome 154 on Linux, not Electron. I opened the requested incognito tab and installed the exact heading/input fixture. Both preview_click calls succeeded; instrumentation recorded trusted clicks on H1 and INPUT, with the input active afterward. This exercised the available preview service, not a desktop build of the checkout, and cannot establish whether the desktop composer loses focus.

    Current-main verification still needs a Linux Electron client with a focused composer while both clicks run. Leaving this accepted bug open; desktop verification is unavailable in this environment.

  5. gilitos92 commented on Oct 22, 2026

    @gilitos92
    Contributor

    Desktop reproduction on macOS, current Nightly, since the triage VM couldn't run the Electron client.

    Environment: T3 Code Nightly 0.1.2-nightly.20261022.3541, macOS 27.0.1, Apple Silicon.

    Method: A small Swift tool set AXManualAccessibility on the T3 Code process, polled kAXFocusedUIElementAttribute every 100 ms, and logged each change.

    Steps (same fixture as the issue body):

    1. An agent ran preview_open({ open: false, reuseExistingTab: false, profileId: "incognito" }), so the preview tab was not visible.
    2. It installed the heading/input/button fixture with preview_evaluate.
    3. I clicked into the composer and left it alone.
    4. The agent ran preview_click on #h, then #i, then #b.

    Result: The first click moved app focus out of the composer into the hidden guest:

    16:51:21.449  AXTextArea[Message]                                  composer focused
    16:52:02.292  preview_click #h starts
    16:52:04.546  AXWebArea[T3 click focus probe]                      focus now in the hidden guest
    16:52:12.153  AXTextField[Name] < AXWebArea[T3 click focus probe]  after preview_click #i
    

    The click on #b didn't move focus further; macOS Chrome doesn't focus buttons on click.

    Also seen in real use on 0.1.1-nightly.20261020.3438: a delegated agent working in a hidden Notion tab pulled focus out of the composer on 11 of 11 preview_click calls. Each move came 30–320 ms after the call finished, while I was typing in another thread.

    No commits between those builds touch agent mouse input or apps/desktop/src/preview/GuestInput.ts. This matches the cause described in #22042. Happy to test a build of that PR.

  6. hodeinavarro commented on Oct 26, 2026

    @hodeinavarro

    Reproduced on macOS with a cross-thread variant: focus leaves the composer of a different thread, and the human's keystrokes land in the other thread's preview.

    What happened

    Thread 1's agent was doing UI verification in the T3 Code Browser (clicking and typing). I was typing in thread 2's composer, with the sidebar open and thread 1 not visible. Repeatedly, the thread 2 composer lost focus, my next keystrokes went into thread 1's browser page, and the page got typos.

    Diagnosis

    An agent Input.dispatchMouseEvent click is a trusted click, so Chromium gives keyboard focus to the <webview> guest inside the main window, even when another thread hides the panel. After that, webContents.focusedFrame is set, so sendPageCommand (apps/desktop/src/preview/GuestInput.ts:108) sends the agent's key events through CDP, and real OS keystrokes also go to the guest. The unfocused-guest rerouting covers only agent keyboard input, not the focus change from a click.

    Evidence

    desktop.trace.ndjson, 14:44–14:56 local time: each PreviewManager.emitAgentPointer comes within about 1 s of PreviewManager.handleHumanInput (trusted pointerdown/keydown from PickPreload), with bursts of 6–10/s (for example 14:55:03, 14:55:09). Agent CDP input is also isTrusted, so the trace cannot separate human keys from agent keys.

    Environment

    • T3 Code (Nightly) desktop, local server 0.1.3-nightly.20261026.3717 (tag commit 1316d48). No later commits touch GuestInput.ts or DesktopBrowserHost.ts.
    • macOS 27.0 (Darwin 27.0.0), arm64 (M1 Max).
    • Triage CLI 0.1.0 (npx t3 triage).

    Workaround

    Don't type in other threads while an agent uses the browser, or turn off "Agent browser access".


    Produced by Claude Opus 5.5 (1M context) in Claude Code, through t3 triage.

  7. fixfon commented on Oct 26, 2026

    @fixfon
    Contributor

    Thanks for the trace. I think #22042 should cover most of this: agent mouse events on a guest that isn't focused note the app window's focused element first and give it back afterwards, regardless of which thread's panel is showing. There is still a short window between the click and the focus being returned where a key press can reach the page, and I haven't tried it with a hidden panel in a second thread. If you can try a build of the PR, that would help.

  8. hnavarro-kernet commented on Oct 26, 2026

    @hnavarro-kernet

    Thank you @fixfon, verified!

    Agent notes:

    Tested #22042 at `e20f321ab0475e99e1462ba310f9b022ae325700` (before `b7c9129` and
    `e29edac`) with the same cross-thread scenario on macOS 27.0 (arm64): thread 1's agent
    clicked and typed in the T3 Code browser (a text input in a web form) while I typed
    continuously in thread 2's composer.
    
    In 3 runs (up to ~37 s and 50 agent key presses, plus 4 agent clicks in the last run),
    thread 2's composer kept focus the whole time. The page's text input got only the
    agent's `A` presses, with no stray characters from my typing. The bug did not reproduce
    at that commit. I have not tested the current PR head (`e29edac`).
    
    Details: https://github.com/pingdotgg/t3code/pull/22042#issuecomment-6419513060
    
    
  9. sensslen commented on Oct 27, 2026

    @sensslen

    Same on Windows: T3 Code (Beta) 0.1.3, Windows 11 Pro (build 26300).

    Any time an agent works in the built-in browser, focus leaves whatever field I'm typing in, both the composer and other fields in the app. It happens often enough that I can't type while an agent is using the browser.

  10. NachoooLK commented on Oct 29, 2026

    @NachoooLK

    Additional triage on T3 Code Desktop 0.1.4-nightly.20261028.3824, macOS 26.7.2, arm64, with a local server.

    The user reports intermittent composer focus loss, requiring another click to continue typing.

    Desktop traces show agent browser pointer activity at 10:31:47–10:32:17 UTC on October 29, immediately before triage. The installed source (eb751fa) forwards mouse commands through CDP without restoring host focus. This is consistent with #21954, but the exact trigger has not been reproduced or confirmed by the user.

    No settings or source changes were applied.

    Triage by gpt-6.1-sol via Codex in T3 Code.

  11. santissimoo commented on Oct 29, 2026

    @santissimoo

    Additional triage on T3 Code Desktop (Nightly) 0.1.4-nightly.20261029.3853, macOS 27.0 (darwin arm64), local server, same version.

    The user reports that the thread composer intermittently stops accepting keystrokes, with no obvious trigger, several times today. No preview pane was open in the UI, so this matches the hidden/background-tab case.

    Evidence:

    • desktop.trace.ndjson shows sustained agent browser activity from background threads throughout the day: PreviewManager.emitAgentPointer bursts on 2026-10-29 at about 11:05–11:09, 12:38–13:09, 13:30–13:40 and 14:10–14:32 UTC (up to about 117/min), each paired with PreviewManager.handleHumanInput spans.
    • At this tag, apps/desktop/src/preview/DesktopBrowserHost.ts enables Emulation.setFocusEmulationEnabled for hidden guests that the server is driving, and nothing restores host or composer focus after CDP mouse input.
    • Ruled out: there are no pending user-input requests in the DB (today's three resolved as live within about 2 min). There were no connection-probe failures or reconnects today, and no event-loop stalls today.
    • fix(desktop): agent preview clicks no longer steal the composer's focus #22042 was closed unmerged, and main (28 commits ahead of this tag) has no focus-related preview change.

    The exact moment of each occurrence wasn't captured, so this is correlation, not a confirmed repro.

    Triage by Claude Opus 5.5 via Claude Code (t3 triage).

    — Claude, Santi's agent

  12. gilitos92 commented on Oct 29, 2026

    @gilitos92
    Contributor

    Note

    Written by Claude Opus 5.5 on behalf of Gil.

    With #22042 closed, I'd like to ask about the direction for a full fix before anyone starts on one.

    What I see on main (960d5761):

    • Keyboard input already avoids focus: sendPageCommand in GuestInput.ts sends keys straight to a guest that doesn't have focus.
    • Agent clicks still go through Input.dispatchMouseEvent. Chromium treats them as real clicks, so the <webview> takes focus from the composer.
    • fix(desktop): agent preview clicks no longer steal the composer's focus #22042 restored focus after each click. As @fixfon found, that breaks typing into cross-site frames: with no focusedFrame, Input.insertText on the root session crashes the guest.

    So restoring focus after a click can't work while guests are <webview> elements in the app's own window.

    A possible design:

    1. Host the guests of hidden tabs in a separate hidden window. Focus is per window, so agent clicks there can't reach the composer. Most reports in this issue, including mine, are about hidden tabs.
    2. To make that possible, move guests from <webview> to WebContentsView, which can move between windows. A tab moves into the visible panel when the user opens it.
    3. For a tab that is visible while the agent drives it, send typed text to a cross-site frame through that frame's own CDP session (auto-attached out-of-process frame target), so the guest never needs focus. I haven't tested this part.

    This is a large change to the preview code, so I don't want to open a PR without agreement.

    Questions:

    • Is a redesign like this already planned, or would you prefer a different approach?
    • Would you accept a PR for steps 1 and 2, or is moving off <webview> off the table?
  13. delete commented on Oct 30, 2026

    @delete

    Additional report on macOS, T3 Code Nightly 0.1.6-nightly.20261029.3892.

    User-observed behavior

    The chat composer loses focus while the user is typing, interrupting message entry. The user confirmed this happens on this Mac while browser preview is being used.

    The exact triggering browser action has not been isolated. Whether the preview is visible or hidden, whether it belongs to the same thread, and where keyboard focus lands have not yet been established.

    Environment

    • T3 Code Desktop: 0.1.6-nightly.20261029.3892
    • Local server: running the same version
    • Platform: macOS, Apple Silicon (darwin arm64, kernel 27.0.0)
    • Matching source tag: v0.1.6-nightly.20261029.3892
    • Source commit: 08a463e29976617134de01e9341f898bc881d0eb
    • Report date: October 30, 2026

    Local evidence

    An initial bounded sample of the latest 60,000 server trace records contained:

    • 57 PreviewToolkit.invoke spans
    • 92 PreviewAutomationBroker.invoke spans
    • 3 PreviewAgentActivity.begin spans

    These establish browser automation activity in the sampled logs. They do not establish which browser action caused a particular focus loss. No synchronized composer-focus recording was captured.

    Source findings at the installed tag

    The installed build still distinguishes keyboard input from mouse input:

    • GuestInput.ts, lines 3–7 lists keyboard and IME methods for special routing to unfocused guests.
    • Lines 108–109 forward other methods, including mouse events, directly through the debugger.
    • DesktopBrowserHost.ts, line 178 manages focus emulation for browser guests. In the inspected relay path, no composer-focus restoration surrounds agent mouse commands.

    This is consistent with the mechanism already discussed here, but is not an independently captured reproduction.

    Fix status and verification limits

    #22042 is closed without merging. Comparing the installed commit with the latest published nightly, 0.1.6-nightly.20261030.3917, found no changes to the desktop preview files identified above.

    No local patch, settings change, restart, or controlled focus-stealing test was performed. The user’s draft was not manipulated.

    Triage by GPT-6.1-Sol through the Codex harness in T3 Code.

  14. sharad-ritu commented on Oct 30, 2026

    @sharad-ritu

    Still occurring on T3 Code desktop 0.1.5 with local server 0.1.5, Ubuntu GNOME on Wayland.

    While an agent runs browser checks in thread A, typing in thread B repeatedly loses keyboard focus. Clicking the input restores typing temporarily. The interruptions stop when browser automation stops.

    Desktop and server versions were checked locally. Proactive panels and SnapShots are disabled; automatic floating previews are enabled.

    Prepared through T3 triage with Codex, gpt-6.1-sol.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    acceptedfeature request acceptedbugSomething is broken or behaving incorrectly.via-triageFiled through npx t3 triage

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions