Repository navigation
Releases: btsd321/dsh-oh-my-terminal
Releases · btsd321/dsh-oh-my-terminal
Release list
v0.4.7:修复 Ctrl+Shift+V 粘贴两次 / Fix Ctrl+Shift+V pasting text twice
中文
修复
- 🔴 Ctrl+Shift+V 粘贴两次(本地直连 SSH 场景):v0.4.7 初版的标志方案有根本性时序缺陷——
readText()是异步的,但原生 paste 事件在 keydown 后同步触发,标志永远来不及在原生 paste 之前设置,导致本地直连 SSH 场景仍然双发。改用原生 paste 优先方案(反转去重方向):不再用异步readText结果去压制同步的原生 paste,而是用同步的原生 paste 决定之后要不要做readText。v分支不调preventDefault、不同步调readText——让原生 paste 优先(Chromium Win/Linux 在 keydown 默认处理中同步派发 paste,由 xtermhandlePasteEvent单发,无需剪贴板权限)keydown时清零nativePasteObserved,setTimeout(0)延迟到宏任务检查:原生 paste 已发生 → 跳过readText(单发);未发生(macOS 不映射该组合键)→readText兜底onNativePaste从拦截者变为纯观察者,不再调preventDefault/stopImmediatePropagation- Electron webview(
readText被权限拒绝)→ 原生 paste 单发,不再触发权限 reject
- 🟢 同时修复 Electron webview 下 Ctrl+Shift+V 完全无法粘贴:v0.4.6 的
preventDefault()方案在readText失败时无法撤销阻断,导致 webview 下彻底无法粘贴。原生 paste 优先方案不调preventDefault,webview 下原生 paste 正常触发单发。
验证
- 类型检查(
pnpm run typecheck)与构建(pnpm run build)均通过。 - 在本地 Chrome 直连 DSH + SSH 到 BJ-SF-Robot 场景下按 Ctrl+Shift+V 确认只粘贴一次。
- 在 dsh-remote-explorer 经 webview 远程 WSL 场景下按 Ctrl+Shift+V 确认能粘贴(原生 paste 兜底)。
- 无配置项、API 或协议变更,升级后刷新页面即生效。
English
Fixes
- 🔴 Ctrl+Shift+V pasted text twice (local direct SSH): The initial v0.4.7 flag-based approach had a fundamental timing flaw —
readText()is async, but the native paste event fires synchronously after keydown, so the flag could never be set before the native paste arrived, causing double-paste in local direct SSH scenarios. Switched to a native-paste-first approach (reversing the dedup direction): instead of using the asyncreadTextresult to suppress the synchronous native paste, use the synchronous native paste to decide whether to callreadTextat all.- The
vbranch no longer callspreventDefaultor invokesreadTextsynchronously — native paste takes priority (Chromium on Win/Linux synchronously dispatches paste during keydown default handling, handled by xtermhandlePasteEventas a single paste, no clipboard permission needed) - On
keydown,nativePasteObservedis cleared;setTimeout(0)defers to a macrotask to check: if native paste occurred → skipreadText(single paste); if not (macOS does not map this combo) →readTextfallback onNativePastechanges from interceptor to pure observer — no longer callspreventDefault/stopImmediatePropagation- Electron webview (
readTextrejected by permission) → native paste fires as single, no permission reject
- The
- 🟢 Also fixes Ctrl+Shift+V failing entirely in Electron webview: The v0.4.6
preventDefault()approach could not be undone whenreadTextfailed, causing webview to have no paste at all. The native-paste-first approach does not callpreventDefault, so webview native paste fires normally as a single paste.
Verification
- Type checking (
pnpm run typecheck) and build (pnpm run build) both pass. - Tested Ctrl+Shift+V in local Chrome direct DSH + SSH to BJ-SF-Robot — pastes exactly once.
- Tested Ctrl+Shift+V in dsh-remote-explorer via webview remote WSL — paste works (native paste fallback).
- No configuration, API, or protocol changes — a page refresh applies the update.
Full Changelog: v0.4.6...v0.4.7
v0.4.6:修复 Ctrl+Shift+V 粘贴两次 / Fix Ctrl+Shift+V pasting text twice
中文
修复
- 🟢 Ctrl+Shift+V 粘贴文本两次:xterm.js 的
_keyDown在customKeyHandler返回false时直接return false,不调用ev.preventDefault()。Chromium 在 xterm 隐藏 textarea 上把Ctrl+Shift+V当作「粘贴为纯文本」,触发原生paste事件,被 xterm 内部的handlePasteEvent再发一次,与我们的term.paste()双发导致文本粘贴两次。SSH 到远程主机时更明显——远程 shell(bash/zsh)开启 bracketed paste mode,两次粘贴产生两段\x1b[200~...\x1b[201~序列。现在onCustomKey在readText可用时调用ev.preventDefault()阻断浏览器原生 paste 事件;不安全上下文(远程 http 无navigator.clipboard)不阻断,交给原生 paste 单发兜底。 - 🟢 Ctrl+Shift+C 不安全上下文也能复制:原代码在无
navigator.clipboard.writeText时不复制;现改为writeClipboard()(内含legacyCopy/execCommand回落),并加preventDefault()阻断 Chrome 的 DevTools 审查元素快捷键。keydown 属用户手势,execCommand在不安全上下文下可用。
验证
- 类型检查(
pnpm run typecheck)与构建(pnpm run build)均通过。 - 在本地 Chrome、DSH 桌面端、远程 http 三种场景各按一次 Ctrl+Shift+V 确认只粘贴一次。
- 无配置项、API 或协议变更,升级后刷新页面即生效。
English
Fixes
- 🟢 Ctrl+Shift+V pasted text twice: xterm.js
_keyDownreturnsfalsedirectly whencustomKeyHandlerreturnsfalse, without callingev.preventDefault(). Chromium treatsCtrl+Shift+Vas "paste as plain text" on the xterm hidden textarea, firing a nativepasteevent that xterm internalhandlePasteEventhandles — sending the text a second time alongside ourterm.paste(). This was more noticeable over SSH, where remote shells (bash/zsh) enable bracketed paste mode, producing two\x1b[200~...\x1b[201~sequences.onCustomKeynow callsev.preventDefault()whenreadTextis available to suppress the native paste event; in insecure contexts (remote http withoutnavigator.clipboard) it does not block, letting the native paste fire once as a fallback. - 🟢 Ctrl+Shift+C works in insecure contexts: Previously no copy happened without
navigator.clipboard.writeText; now useswriteClipboard()(which falls back tolegacyCopy/execCommand), and callspreventDefault()to block Chrome DevTools inspect-element shortcut.keydownis a user gesture, soexecCommandworks in insecure contexts.
Verification
- Type checking (
pnpm run typecheck) and build (pnpm run build) both pass. - Tested Ctrl+Shift+V in local Chrome, DSH desktop, and remote http — each pastes exactly once.
- No configuration, API, or protocol changes — a page refresh applies the update.
Full Changelog: v0.4.5...v0.4.6
v0.4.5:终端面板与下拉菜单主题令牌成对配对,修复第三方皮肤下白底白字 / Theme-token pairing for the panel & dropdown, fixing white-on-white under third-party skins
中文
修复
- 🟢 统一表面/文字令牌配对,修复下拉菜单与面板「白底白字」:此前面板与浮层底色取
--dsw-specific-tip(宿主设计平台的 tip 档、且当前宿主已无任何消费方的孤儿令牌,浅色主题下为近白#F5F6F7),条目文字取--dsw-alias-label-secondary。第三方皮肤可以经宿主公开的theme.overrideTokens()把该角色令牌整体改写并内联到body(例如 dsh-plugin-wallpaper-engine 的字体集把「次要文字」设为#FAFAFA),两枚令牌来源不同、失去成对关系,于是出现白底白字,只有鼠标悬停(文字切换为 primary)才可见。现在面板/栏/头部/侧栏/右侧列表改用宿主面板语义令牌,下拉菜单/右键菜单/输入框改用宿主浮层语义令牌;文字一律由--dsw-alias-label-primary派生(Text / TextDim / TextMuted 三档),边框与 hover 面同样收口。内部令牌声明在:root,body并带宿主令牌回退,浅色/深色、有无皮肤、独立模式与 DSH-better-sidebar 兼容模式表现一致。 - 🟢 弱化文字同源收口:状态文字、图标、占位符与 focus 描边不再直接使用
--dsw-alias-label-tertiary(同样会被皮肤整体改写),改由主文字色派生的--dshTermTextMuted提供,避免浅色面板上对比度过低。
维护
- 构建产物
lib/在主工作区重新构建,修正经 git worktree 构建时带入的相对路径前缀(不影响运行行为)。 - 无配置项、API 或协议变更,升级后刷新页面即生效。
English
Fixes
- 🟢 Pair surface and text theme tokens — fixes white-on-white in the dropdown and panel: The panel/menu background used
--dsw-specific-tip(atip-tier token with no consumer left in the host, near-white#F5F6F7in the light theme) while item text used--dsw-alias-label-secondary. Third-party skins can rewrite that role token wholesale through the host's publictheme.overrideTokens()and have it inlined onbody(for example, a dsh-plugin-wallpaper-engine font set setting "secondary text" to#FAFAFA). The two tokens then come from unrelated sources and lose their pairing, producing white on white that only became visible on hover (when the text switches to primary). Panels/bars/header/side list now use the host's panel-surface semantic token, and the dropdown/context menu/inputs use the host's overlay-surface token; all text is derived from--dsw-alias-label-primary(Text / TextDim / TextMuted tiers), with borders and hover surfaces unified as well. The internal tokens are declared on:root,bodywith host-token fallbacks, so light/dark, with or without skins, and both standalone and DSH-better-sidebar compatibility modes behave the same. - 🟢 Derive muted text from the same source: state text, icons, placeholders and focus outlines no longer use
--dsw-alias-label-tertiarydirectly (also rewritten wholesale by skins); they use--dshTermTextMuted, derived from the primary text color, avoiding low contrast on light panels.
Maintenance
- Rebuilt the
lib/artifacts in the main workspace, correcting the relative path prefixes introduced by building inside a git worktree (no runtime impact). - No configuration, API or protocol changes — a page refresh applies the update.
Full Changelog: v0.4.4...v0.4.5