Skip to content

fix(tui-v3): detect Shift+Enter on Windows via GetAsyncKeyState#519

Closed
jlu005807 wants to merge 1 commit into
lsdefine:mainfrom
jlu005807:fix/win-shift-enter-newline
Closed

fix(tui-v3): detect Shift+Enter on Windows via GetAsyncKeyState#519
jlu005807 wants to merge 1 commit into
lsdefine:mainfrom
jlu005807:fix/win-shift-enter-newline

Conversation

@jlu005807
Copy link
Copy Markdown
Contributor

@jlu005807 jlu005807 commented May 28, 2026

Windows 终端下,Prompt Toolkit 无法区分 Shift+Enter 和 Enter(两者均发送 \r),导致 Shift+Enter
无法换行,直接提交消息。

修改内容

在 frontends/tui_v3.py 的 Enter 处理逻辑中增加 Windows 专用检测:

1 导入 ctypes 模块(仅在 Windows 时)
2 使用 GetAsyncKeyState(0x10) 实时读取 Shift 键物理状态
3 按下 Shift 时返回 \n(换行),否则返回 \r(提交)

   if has('controlm', 'c-m') or key_s in ('\r', '\n'):
  +    if _IS_WINDOWS:
  +        import ctypes
  +        if ctypes.windll.user32.GetAsyncKeyState(0x10) & 0x8000:
  +            return b'\n'
       return b'\r'

影响范围

• 仅 tui_v3.py 一个文件,+5 行
• 仅 Windows 平台生效,Linux/macOS 不受影响
• 无新增依赖(ctypes 为 Python 内置)

测试步骤

1 在 Windows 终端运行 TUI V3
2 按 Enter → 提交消息 ✅
3 按 Shift+Enter → 换行 ✅

Windows terminals don't send unique escape sequences for Shift+Enter
(both Enter and Shift+Enter arrive as \r), so prompt_toolkit can't
distinguish them from the key name alone.

Detect the physical Shift key via Win32 GetAsyncKeyState(0x10) —
hardware-level, no terminal dependency.
@shenhao-stu
Copy link
Copy Markdown
Contributor

ctrl+enter

@jlu005807
Copy link
Copy Markdown
Contributor Author

原来是ctrl+enter吗,我以为一般都是shift+enter😁

@shenhao-stu
Copy link
Copy Markdown
Contributor

我们会参考你的意见,v2+v3都额外绑定shit+enter

@jlu005807
Copy link
Copy Markdown
Contributor Author

好的,收到了

nianyucatfish added a commit to nianyucatfish/GenericAgent that referenced this pull request May 28, 2026
- /export clip 现在通过 _copy_to_clipboard 直接写系统剪贴板:
  Win32 ctypes(CF_UNICODETEXT,避开控制台 codepage)/ macOS pbcopy /
  Wayland wl-copy / X11 xclip 或 xsel,失败再退回手动复制。
- InputArea 在 Windows 上对 Enter 事件用 GetAsyncKeyState(VK_SHIFT) 兜底,
  终端把 Shift+Enter 报成普通 Enter 时也能正确插入换行而非提交。
- watch_theme 漏清 _seg_render_cache 导致主题切换后 Markdown 的
  h1/列表 bullet/code 块/link 等仍是上一主题的色 —— 缓存 key 不含
  theme,且 ANSI 颜色被烤进了 _MdRender。补上 clear()。

Refs:
- Shift+Enter 物理检测思路 from upstream PR lsdefine#519 by @jlu005807
  lsdefine#519
- Markdown 渲染路径上下文 from upstream PR lsdefine#512 by @MuziIsabel
  lsdefine#512
nianyucatfish added a commit to nianyucatfish/GenericAgent that referenced this pull request May 28, 2026
- _ptk_keypress_to_bytes 在 Windows 上对 Enter 收到 \r 时用
  GetAsyncKeyState(VK_SHIFT) 物理检测 Shift,按下时返回 \n 以触发换行
  (PTK 在某些 Windows 终端区分不出 Shift+Enter 与裸 Enter)。
- 新增 _line_region / _logical_visual_range 辅助函数,↑/↓ 按键:
  不在该逻辑行的视觉首/末行 → 视觉滚行;在视觉首行且光标在行首 →
  历史导航,否则先跳逻辑行首/尾,下次按键再跨行/进历史。多行粘贴
  内部导航更符合直觉。

Refs:
- Shift+Enter 物理检测 from upstream PR lsdefine#519 by @jlu005807
  lsdefine#519
nianyucatfish added a commit to nianyucatfish/GenericAgent that referenced this pull request May 28, 2026
- /export clip 现在通过 _copy_to_clipboard 直接写系统剪贴板:
  Win32 ctypes(CF_UNICODETEXT,避开控制台 codepage)/ macOS pbcopy /
  Wayland wl-copy / X11 xclip 或 xsel,失败再退回手动复制。
- InputArea 在 Windows 上对 Enter 事件用 GetAsyncKeyState(VK_SHIFT) 兜底,
  终端把 Shift+Enter 报成普通 Enter 时也能正确插入换行而非提交。
- watch_theme 漏清 _seg_render_cache 导致主题切换后 Markdown 的
  h1/列表 bullet/code 块/link 等仍是上一主题的色 —— 缓存 key 不含
  theme,且 ANSI 颜色被烤进了 _MdRender。补上 clear()。

Refs:
- Shift+Enter 物理检测思路 from upstream PR lsdefine#519 by @jlu005807
  lsdefine#519
nianyucatfish added a commit to nianyucatfish/GenericAgent that referenced this pull request May 28, 2026
- _ptk_keypress_to_bytes 在 Windows 上对 Enter 收到 \r 时用
  GetAsyncKeyState(VK_SHIFT) 物理检测 Shift,按下时返回 \n 以触发换行
  (PTK 在某些 Windows 终端区分不出 Shift+Enter 与裸 Enter)。
- 新增 _line_region / _logical_visual_range 辅助函数,↑/↓ 按键:
  不在该逻辑行的视觉首/末行 → 视觉滚行;在视觉首行且光标在行首 →
  历史导航,否则先跳逻辑行首/尾,下次按键再跨行/进历史。多行粘贴
  内部导航更符合直觉。

Refs:
- Shift+Enter 物理检测 from upstream PR lsdefine#519 by @jlu005807
  lsdefine#519
- 多行输入逻辑行边界导航思路 from upstream PR lsdefine#520 by @jlu005807
  lsdefine#520
@lsdefine lsdefine closed this May 28, 2026
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.

3 participants