Skip to content

[Bug]: SnapShots keep triggering while typing even though the feature is turned off (stable 0.0.42, macOS) #12769

Description

@gabbywelson

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

  1. Install the stable desktop build (0.0.42) on macOS.
  2. Set up SnapShots once with the default both Shift keys shortcut, then turn SnapShots off in Settings.
  3. Keep using the app normally and type in the composer (including text that uses both Shift keys).

I don't have a fully deterministic repro; it recurs during ordinary typing.

Expected behavior

With SnapShots disabled, the shortcut listener should be torn down. Nothing SnapShot-related (flash, sound, animation, capture) should ever fire.

Actual behavior

The SnapShot flash / sound / animation keeps triggering repeatedly while I'm typing, even though the feature is turned off. It appears to be the both-Shift-keys shortcut still being live after the feature is disabled.

Persisted settings at the time (~/.t3/userdata/client-settings.json):

"snapShotEnabled": false,
"snapShotIncludeAccessibility": true,
"snapShotShortcut": { "kind": "both-shift-keys" },
"snapShotPlaySound": true,
"snapShotSound": "soft-pop",
"snapShotFlash": true,
"snapShotAnimations": true

Impact

Major degradation or frequent failure

Version or commit

0.0.42 (stable channel, com.t3tools.t3code)

Environment

macOS 27.0 (26A428), T3 Code desktop 0.0.42, stable update channel (updateChannelConfiguredByUser: true)

Logs or stack traces

SnapShot spans from ~/.t3/userdata/logs/desktop.trace.ndjson* for today (local time), polling spans (listPending / ensureTrustedSender) omitted:

10:27:08  desktop.snapShot.applySettings      Success
10:27:18  desktop.snapShot.setup              Success
10:27:21  desktop.snapShot.shortcutActivated  Success
10:27:21  desktop.snapShot.capture            Success
10:27:21  desktop.snapShot.persistCapture     Success
10:29:44  desktop.snapShot.applySettings      Success
11:11:44  desktop.snapShot.applySettings      Success
11:14:09  desktop.snapShot.checkShortcut      Success
11:14:09  desktop.snapShot.shortcutActivated  Success
11:14:09  desktop.snapShot.capture            Success
11:14:10  desktop.snapShot.persistCapture     Success
11:14:19  desktop.snapShot.applySettings      Success
11:14:19  desktop.snapShot.configure          Success
11:32:48  desktop.snapShot.applySettings      Success
11:32:48  desktop.snapShot.configure          Success
11:52:44  desktop.snapShot.applySettings      Success
11:55:26  desktop.snapShot.applySettings      Success

Notes on the trace:

  • Both logged captures were initiated by desktop.snapShot.shortcutActivated, i.e. the keyboard shortcut, not a UI action.
  • The applySettings / configure spans carry no attributes, so the trace doesn't show whether enabled was true or false at each point. Logging the applied enabled value there would make this much easier to diagnose.
  • The triggers I still see after the last settings change (11:32) do not show up as shortcutActivated / capture spans, so the flash/sound/animation path seems to fire without going through (or being recorded by) the capture pipeline.
  • The renderer keeps polling desktop:list-pending-snap-shots continuously while the feature is off (150+ spans in ~30 minutes).

Workaround

None found. Turning the feature off does not stop it.

Activity

  1. gabbywelson commented on Sep 20, 2026

    @gabbywelson
    Author

    Screenshots of the huge stack of Snapshot notifications. This keeps happening even when the app is in the background with zero interaction

    Image Image
  2. juliusmarminge commented on Sep 20, 2026

    @juliusmarminge
    Member

    Triage

    Confirmed against current main. This is a real desktop SnapShot bug, still present, and not a “settings failed to save” issue.

    client-settings.json with snapShotEnabled: false is doing what it should. The remaining flood is leftover pending captures plus a renderer coordinator that never looks at that flag.

    What the traces and screenshots show

    The two captures in today’s desktop trace (10:27:21, 11:14:09) are real shortcut captures (desktop.snapShot.shortcutActivated → capture → persistCapture). The second one sits next to checkShortcut, so it happened while Settings was still checking/recording the both-Shift pair, i.e. while the feature was still on.

    After the last applySettings / configure at 11:32:48 there are no further shortcutActivated / capture spans. That matches applySettings: when snapShotEnabled flips off it calls releaseShortcut() (kills the macOS osascript both-Shift poller) and capture() fails closed.

    The symptoms that continue after that — sound, motion, and the toast stack, including with the app in the background — are a second path:

    SnapShotCoordinator is always mounted in __root.tsx. It is not gated on snapShotEnabled. On mount, focus, visibility, "ready", and any effect-dep change (thread/draft store updates count, even in the background) it calls listPendingSnapShots(). That is the 150+ desktop:list-pending-snap-shots polls with the feature off.

    For each pending file it:

    1. Plays the capture sound (playCaptureSound) before it knows whether delivery can succeed.
    2. If there is no attach target, toasts Snapshot taken, but no project is available / Add a project, then capture the window again.
    3. Does not acknowledge the file, and removes the id from the “already sounded” set.

    So the same leftover ~/.t3/userdata/snap-shots/*.json is retried forever. Each retry is another whoosh + another toast. The screenshots on this issue are exactly that toast, on Settings → SnapShots with the toggle off.

    On the Settings route there is no thread/draft, so resolveExistingSnapShotTarget often misses, and if defaultProjectRef is empty the coordinator takes the “no project” branch every time.

    Docs say turning capture off releases the shortcut. The main process does that. The renderer does not stop draining, sounding, or toasting.

    Not a duplicate

    No open issue or PR covers “disabled SnapShots still toast/sound from leftover pendings.” DesktopSnapShot.ts / SnapShotCoordinator.tsx are unchanged in the relevant paths since v0.0.42.

    Suggested fix

    1. Gate SnapShotCoordinator drain / sound / toast on snapShotEnabled. When the flag is off, do not listPending on every chat-state effect, and do not play capture feedback.
    2. On disable (or on the “no project” / hard-fail path), either acknowledge/discard the pending files or back off. Do not continue after toasting and then immediately allow the same id to sound again.
    3. Add a macOS regression: configure({ snapShotEnabled: false }) must kill() the osascript both-Shift poller. Today we only assert teardown for Niri / Hyprland / portal.
    4. Optional: put enabled on desktop.snapShot.applySettings / configure spans, as the report asked. Would have made this trace one read.

    Workaround

    Fully quit T3 Code, then delete leftover captures under ~/.t3/userdata/snap-shots/ (*.json / *.png). Turning the toggle off is not enough while those files remain.

    Accepting as a desktop SnapShot bug.

  3. added
    bugSomething is broken or behaving incorrectly.
    acceptedfeature request accepted
    via-triageFiled through npx t3 triage
    on Sep 20, 2026
  4. cestercian commented on Sep 21, 2026

    @cestercian
    Contributor

    I'd like to take this — focused fix so the SnapShots shortcut listener is torn down when the feature is off.

  5. cestercian commented on Sep 21, 2026

    @cestercian
    Contributor

    stepping back — #12775 already covers this

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