Skip to content

fix(desktop): repair stale composingRef to resolve Enter key issue on Windows - #64372

Open
iborazzi wants to merge 1 commit into
NousResearch:mainfrom
iborazzi:fix/windows-enter-composing-guard-v2
Open

fix(desktop): repair stale composingRef to resolve Enter key issue on Windows#64372
iborazzi wants to merge 1 commit into
NousResearch:mainfrom
iborazzi:fix/windows-enter-composing-guard-v2

Conversation

@iborazzi

Copy link
Copy Markdown
Contributor

Problem:
On Windows, the Electron/Chromium IME handling fires compositionstart for standard keyboard input. This leaves composingRef.current stuck at true, causing the handleEditorKeyDown guard to silently drop the Enter key event.

Solution:
Instead of merely bypassing the guard, this PR repairs the stale composingRef state:

Clears composingRef when isComposing is false before the IME guard.

Explicitly clears the ref on blur for the form-submit path.

Ensures that genuine IME composition remains guarded while standard input is no longer blocked.

Testing:

Verified on Windows 10: Enter key now triggers immediate message submission.

Verified that genuine IME composition still blocks premature submission.

…on Windows

Rebase the NousResearch#39649 fix onto current main and address sweeper review on
NousResearch#39660:

- Enter no longer submitting was only one symptom of a stuck
  composingRef (Chromium/Electron on Windows can fire compositionstart
  for plain, non-IME input and never a matching compositionend). The
  original PR only special-cased the keydown guard, leaving
  handleEditorInput and the Send-button form submit still reading the
  same stale ref.
- handleEditorKeyDown and handleEditorInput now resync composingRef
  from that event's own native isComposing before deciding whether to
  block, so a stale true can't outlive whatever (possibly fake)
  composition set it, while a genuine IME composition is unaffected
  since isComposing is actually true for its duration.
- The Send-button path has no composition event to resync from, so
  composingRef is cleared synchronously on blur instead — losing focus
  means composition, real or falsely stuck, is over either way.
- Added windows-stale-composing-guard.test.tsx: false compositionstart
  with no compositionend still lets Enter and the Send button submit,
  and a genuine IME composition still blocks Enter until
  compositionend.

Fixes NousResearch#39649
@alt-glitch alt-glitch added type/bug Something isn't working comp/desktop Electron desktop app (apps/desktop/*) platform/windows Native Windows-specific behavior or breakage sweeper:risk-platform-windows Sweeper risk: may break or behave differently on native Windows P3 Low — cosmetic, nice to have labels Jul 14, 2026
@teknium1

Copy link
Copy Markdown
Contributor

Thanks for the focused regression fix. The premise remains present on current main: apps/desktop/src/app/chat/composer/index.tsx:389 returns on a stale composingRef.current even when the key event is no longer composing, and the form-submit guard repeats that stale-ref block at apps/desktop/src/app/chat/composer/index.tsx:847-854. Current onBlur at apps/desktop/src/app/chat/composer/index.tsx:746 does not clear the ref.

The PR reconciles the ref before the input/keydown guards, preserves the genuine-IME isComposing guard, and clears the ref on blur for the Send-button path. The added regression cases cover the stale false-composition case, genuine composition, and blur-to-Send behavior; the apps/desktop Typecheck & Test check passed.

Automated hermes-sweeper review.

@teknium1 teknium1 added sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades sweeper:blast-moderate Sweeper blast radius: moderate — a subsystem or single platform labels Jul 16, 2026
@GottZ

GottZ commented Aug 3, 2026

Copy link
Copy Markdown

This was generated by AI during triage.

Summary

43 candidate PRs span gateway restart safety, Desktop IME composition, stale composer state, inline editing, busy-turn steering, configurable Enter behavior, and first-message submission. For the Windows Enter/Send failure targeted here, #64372 directly repairs a stale composingRef; #39660, #44149, and #45999 implement substantially the same recovery class, while the remaining PRs address separate causes or already-landed behavior.

Related pull requests

Duplicates

#39660, #44149, #45999, and #64372 substantially overlap on stale composingRef self-healing; #37487/#37757/#37996/#38001/#38135/#38338/#38785/#38791/#38794/#40015/#41026/#43405 overlap on IME Enter guards; #39650/#39680/#39918/#40148 duplicate the composition-end synchronization represented by #40210; #53660 duplicates #53668; #37550 is the source salvaged by #54090.

Suggested consolidation

Keep #64372 open with a salvage path: rebase its input/keydown reconciliation, blur reset, and three stale-versus-genuine-IME regressions onto current main, as supported by the high-salvage maintainer-bot review and its recorded best-fix status. Treat #39660, #44149, and #45999 as competing implementations until #64372’s current-main port demonstrably preserves their covered paths; handle the distinct post-composition, inline-edit, steering, preference, gateway, and first-message PRs under their own issue lanes.

Complex graph

flowchart LR
    classDef open fill:#dbeafe,stroke:#1d4ed8,color:#1e3a8a
    classDef merged fill:#dcfce7,stroke:#15803d,color:#14532d
    classDef closed fill:#e5e7eb,stroke:#6b7280,color:#1f2937
    classDef unverified fill:#f3f4f6,stroke:#9ca3af,color:#374151
    classDef best stroke-width:3px,stroke:#b45309
    classDef target stroke-width:3px,stroke:#4338ca
    I39107(["issue #39107 (open)"])
    I39112(["issue #39112 (open)"])
    I39649(["issue #39649 (open)"])
    I40226(["issue #40226 (open)"])
    I44135(["issue #44135 (open)"])
    I71701(["issue #71701 (closed)"])
    subgraph Dup39660 ["PRs duplicating each other"]
        P39660["PR #39660 (open)"]
        P44149["PR #44149 (open)"]
        P45999["PR #45999 (open)"]
        P64372["PR #64372 (open)"]
    end
    P64372 -->|best fix| I39107
    P64372 -->|best fix| I39112
    P64372 -->|best fix| I39649
    P64372 -->|best fix| I40226
    P64372 -->|best fix| I44135
    P64372 -.->|partial| I71701
    class I39107 open
    class I39112 open
    class I39649 open
    class I40226 open
    class I44135 open
    class I71701 closed
    class P39660 open
    class P44149 open
    class P45999 open
    class P64372 open
    class P39660 best
    class P44149 best
    class P44149 best
    class P45999 best
    class P45999 best
    class P45999 best
    class P64372 best
    class P64372 best
    class P64372 best
    class P64372 best
    class P64372 best
    class P64372 target
    click I39107 "https://github.com/NousResearch/hermes-agent/issues/39107"
    click I39112 "https://github.com/NousResearch/hermes-agent/issues/39112"
    click I39649 "https://github.com/NousResearch/hermes-agent/issues/39649"
    click I40226 "https://github.com/NousResearch/hermes-agent/issues/40226"
    click I44135 "https://github.com/NousResearch/hermes-agent/issues/44135"
    click I71701 "https://github.com/NousResearch/hermes-agent/issues/71701"
    click P39660 "https://github.com/NousResearch/hermes-agent/pull/39660"
    click P44149 "https://github.com/NousResearch/hermes-agent/pull/44149"
    click P45999 "https://github.com/NousResearch/hermes-agent/pull/45999"
    click P64372 "https://github.com/NousResearch/hermes-agent/pull/64372"
Loading

Graph: solid arrow = fixes / best fix, dashed arrow = partial or unverified (see edge label); boxed group = PRs duplicating each other; amber border = best fix; indigo border = target; gray node = closed (state tag in the node label).

Cross-PR triage: Reviewed 43 pull requests and 33 issues in this complex. Each diff was read against this issue; Assessment working set: 328 kB of PR diffs, 159 kB of issue/PR text, 63 kB of discussion (113 comments), 189 verify verdicts. verdicts reflect diff content, not PR titles. Part of an automated triage batch.

@iborazzi

iborazzi commented Aug 4, 2026

Copy link
Copy Markdown
Contributor Author

Thanks for the thorough cross-PR triage and best-fix classification!

Rebased and verified against current main. The input/keydown reconciliation, blur reset, and stale-vs-genuine IME regression tests are green and ready for final maintainer review/merge.

@alt-glitch alt-glitch removed the sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades label Aug 4, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/desktop Electron desktop app (apps/desktop/*) P3 Low — cosmetic, nice to have platform/windows Native Windows-specific behavior or breakage sweeper:blast-moderate Sweeper blast radius: moderate — a subsystem or single platform sweeper:risk-platform-windows Sweeper risk: may break or behave differently on native Windows type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants