Skip to content

[Bug]: macOS: switching threads sometimes requires repeated clicks #22058

Closed

Description

@cornishandy

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

User-observed symptom:
On macOS, clicking a thread in the sidebar to switch threads frequently does not select the thread on the first click, requiring repeated clicks before the thread switch takes effect.

Suggested reproduction (unconfirmed hypothesis):
The steps below describe a suggested, unconfirmed reproduction path based on static inspection of the macOS window configuration rather than a user-confirmed exclusive trigger:

  1. Open the T3 Code desktop app on macOS with multiple threads visible in the sidebar.
  2. Focus another application window so the T3 Code window becomes inactive (unfocused) while remaining visible on screen.
  3. Click directly on a different thread in the T3 Code sidebar.
  4. Record whether that click both activates T3 and selects the target thread, or whether another click is needed. Compare with a single click while T3 is already active.

Expected behavior

Clicking a thread in the sidebar should reliably switch to that thread, including when returning from another app if click-through is the intended macOS behavior.

Actual behavior

Switching threads in the sidebar sometimes requires repeated clicks.

Static inspection of the release's main-window configuration shows that getWindowTitleBarOptions does not set acceptFirstMouse; createWindow spreads those options into the main-window constructor. The release's window wrapper passes them directly to new Electron.BrowserWindow(options). The setting is also absent in DesktopWindow at the inspected upstream main commit linked below.

Electron 44.4.5 documents that acceptFirstMouse controls whether a click on an inactive window also reaches its web contents; the default is false on macOS. This suggests an activation-related explanation worth testing, rather than a confirmed cause of the reported symptom.

Impact

Major degradation or frequent failure

Repeated clicks make routine thread navigation unreliable.

Version or commit

0.1.1-nightly.20261019.3373 (300a35670abc0f73662e17c9ce909bcc106be70f); also verified by static inspection on main @ fb990765a49414a5bfbdc73365455fc8b5fbe691

Environment

macOS 27.2 (26B118), arm64, Electron 44.4.5 (pinned by desktop package in 0.1.1-nightly.20261019.3373)

Logs or stack traces

No relevant runtime logs or stack traces were collected for this report. All 31 local patcher tests passed. A separate original-versus-installed helper comparison confirmed that the patch adds acceptFirstMouse: true only for darwin, preserves the other helper options, leaves win32 and linux options unchanged, and keeps the archive entry's byte length unchanged. These static and VM checks are not native macOS GUI mouse-delivery tests. Furthermore, the local installation where the symptom was reported carries unrelated local UI modifications, and no isolated, matched stock-versus-patched native before/after click experiment has been conducted.

Screenshots, recordings, or supporting files

None attached; evidence is limited to the user-reported symptom and static/VM inspection of window constructor options.

Workaround

Repeating the click eventually switches threads in the reported workflow. For the suspected activation-specific case, focusing T3 before clicking a thread is another workaround to test.

As a candidate fix for maintainer evaluation (not a verified resolution of all repeated-click reports), acceptFirstMouse: true could be added to the existing darwin-only constructor options spread in DesktopWindow (createWindow, alongside disableAutoHideCursor, rather than in getWindowTitleBarOptions whose return type excludes acceptFirstMouse). Because enabling acceptFirstMouse causes the first click on an inactive window to click through to all web contents—not only sidebar thread items—maintainers should evaluate whether window-wide click-through is the desired product behavior on macOS.

Activity

  1. juliusmarminge commented on Oct 20, 2026

    @juliusmarminge
    Member

    Note

    Grok responding on behalf of Julius.

    Thanks for the report. Main doesn't set acceptFirstMouse anywhere, so on macOS the first click on an inactive window only activates it. That's the standard macOS default, not a bug. If the extra clicks only happen when T3 Code isn't the active window, that's the cause, and changing it would be an enhancement.

    The report doesn't establish that, though. The hypothesis is marked unconfirmed, the build has local UI modifications, and there's no before and after on a stock build. Two open issues produce the same symptom while the window is active: #15572, where live sidebar updates move rows under the pointer, and #11066, where sidebar clicks stop registering.

    To narrow it down, could you:

    1. Reproduce on a stock nightly with no local modifications.
    2. Say whether the extra clicks happen only when another app was focused just before, or also when T3 Code is already the active window.
    3. Say whether the sidebar was reordering or updating at the moment the click was missed.
  2. charleshimmer commented on Oct 21, 2026

    @charleshimmer

    Seeing this too, and it also happens when T3 Code is already the focused window, so it doesn't look like an acceptFirstMouse / window-activation issue for me.

  3. samunderwood commented on Oct 21, 2026

    @samunderwood

    Seeing this too.

    • App: T3 Code (Nightly) 0.1.1-nightly.20261019.3360, macOS 27.0.1
    • Input: Apple Magic Mouse. I ruled out the mouse with a click logger: no double clicks, and the pointer stays still while pressed. Clicks register fine everywhere else.
    • Symptom: clicking a thread in the sidebar sometimes does nothing. It's intermittent, and another click or two gets it to switch.
    • Window focus: happens with T3 already the active window, so it isn't acceptFirstMouse.
    • Sidebar activity: rows weren't moving or updating when the click missed, so it doesn't look like [Bug]: Live sidebar updates move row action targets under the pointer #15572.

    Happy to grab logs or test a build if that helps.

  4. cornishandy commented on Oct 26, 2026

    @cornishandy
    Author

    Thanks. To answer the three questions:

    1. Stock build: My install has sidebar title layout patches, an add-on loader, and acceptFirstMouse enabled. I haven't rerun on a clean stock nightly.
    2. Focus: It happens with T3 already active, including on 0.1.3-nightly.20261025.3682.
    3. Reordering: I haven't established whether rows were moving in my own case. Both reports above describe stationary rows.

    I found a candidate event sequence in upstream Sidebar.pointer.ts at d1f7018. An eligible primary-button press on a draggable row initializes the sensor in pending, before drag activation. A matching-pointer move with buttons=0 cancels even in that phase. finish(true) then installs document-capture click suppression, which stops a following click before the row's React onClick.

    #17373 documents a zero-button move before pointerup during dragging. I haven't captured that sequence during an affected click, so this is a candidate cause rather than a confirmed diagnosis.

    A Node stand-in, with imports stubbed and the TypeScript constructor adapted, reproduced the suppression call after a 2px wobble ending with buttons=0. Still clicks and 2px moves with buttons=1 did not invoke suppression. This harness does not render a row or exercise native input.

    A possible focused fix is:

    if ((event.buttons & 1) === 0) {
      if (this.phase === "pending") return this.finish(false);
      if (this.phase === "dragging") this.props.options.onDrop?.(coordinates);
      return this.cancel();
    }

    This gives pending gestures the existing pre-activation pointerup path: onAbort, then onEnd, without click suppression. Stand-in checks also covered missed releases and sweep callbacks; pending sweeps have no keys to commit, and active-drag cancellation remains unchanged. I haven't validated this in the desktop app.

    Proposed regression for Sidebar.pointer.browser.test.tsx (not run in the browser runner):

    it("keeps the click when a zero-button move precedes pointerup before activation", () => {
      using _environment = setup();
      const press = gesture();
      document.dispatchEvent(pointer("pointermove", { clientX: 11 }));
      document.dispatchEvent(pointer("pointermove", { buttons: 0, clientX: 12 }));
      document.dispatchEvent(pointer("pointerup", { buttons: 0, clientX: 12 }));
      const onClick = vi.fn();
      document.body.addEventListener("click", onClick);
      document.body.dispatchEvent(new MouseEvent("click", { bubbles: true }));
      document.body.removeEventListener("click", onClick);
      expect(press.onCancel).not.toHaveBeenCalled();
      expect(onClick).toHaveBeenCalledOnce();
    });

    With these helpers, both moves remain below the 6px activation distance. On current main, onCancel fires and document capture stops the body click; the proposed pending branch should avoid both.

    Separately, handleThreadClick ignores unmodified clicks with detail > 1, so a retry can also be ignored if the browser groups it into a multi-click sequence. Double-click rename needs consideration too; I'd leave that guard unchanged in this focused fix.

  5. bartdudzic commented on Oct 27, 2026

    @bartdudzic

    Another contributing cause, which also explains why retrying often fails several times in a row: the row click handler drops every click with event.detail > 1, and on macOS detail follows the system double-click interval.

    Mechanism

    • isTrailingDoubleClick returns detail > 1, and the thread row click handler skips navigation when it is true (Sidebar.tsx#L1366, same in LegacySidebar.tsx#L1792).
    • Chromium on macOS takes detail from NSEvent.clickCount. That count keeps growing for every click at roughly the same spot within the system double-click interval (System Settings > Mouse > Double-Click Speed, com.apple.mouse.doubleClickThreshold).
    • So if the first click on a row is lost for any reason (for example the pending-drag click suppression described above), each quick retry arrives with detail 2, 3, 4... and is silently dropped too. The thread only opens once the user pauses longer than the double-click interval and clicks again.
    • With a slow double-click setting this gets much worse. My machine had doubleClickThreshold = 1.4 s (default is 0.5 s), so every retry within 1.4 s was ignored. That matches the "needs 2-3 clicks" reports here. It also explains why it shows up more with a Magic Mouse: clicks are quicker and the pointer stays on the same spot, so the retries stay inside the interval. With a trackpad, the retries are usually slower.

    How to confirm

    1. Set Double-Click Speed to one of the slowest values.
    2. In DevTools, log event.detail for clicks on the sidebar, e.g. document.addEventListener("click", e => console.log(e.detail), true).
    3. Click the same thread row several times quickly. Every click after the first within the interval reports detail 2, 3, 4..., so isTrailingDoubleClick skips it. When the first click was lost, the row needs a pause and then another click before it opens.

    Possible fix

    Only skip the trailing click when it is really the second half of a double-click on the row that is already open, e.g. skip when detail > 1 && the row is the active route, and otherwise navigate. Navigation to the same thread is a no-op, and onDoubleClick can still start rename. A click with detail > 1 on a row that is not active should always navigate.

    Environment

    T3 Code (Beta) 0.1.3, macOS 27.0.1 (26A434), arm64, Apple Magic Mouse 2 (firmware 3.1.1). The trackpad was unaffected in practice. Workaround: set Double-Click Speed back to the default. I just did that and will report back if the issue still happens.

  6. guus-peaky commented on Oct 30, 2026

    @guus-peaky

    Also experiencing this since a few days, also on MacOS (Version 0.1.3 d2c4403).

  7. rileymahoney95 commented on Oct 30, 2026

    @rileymahoney95

    Also experiencing this on T3 Code Desktop 0.1.5, macOS arm64 (Darwin 25.6.0), connected to a local 0.1.5 server. Thread clicks frequently do nothing. No specific preceding action is required; sometimes simply clicking another thread triggers it. Escape or refocusing appears to restore clicking, although reliability is not established.

    Static inspection of v0.1.5 confirms that pending pointer cancellation can install click suppression, and thread navigation ignores event.detail > 1. No native input trace was captured, so neither mechanism is confirmed as the cause here. No changes were applied.

    Investigated with Codex, GPT-6 Astra, via T3 triage.

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

    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