dsh-desktop-web-refresh
在 DSH Desktop 桌面端窗口标题栏(与「最小化 / 还原 / 关闭」原生窗口按钮同一栏) 的「编辑」菜单右侧,新增一个 「刷新」 按钮:按下即重新加载 DSH Desktop 页面(等价于浏览器的刷新)。Host 进程不受影响,会话仍保留在 Host 侧。
按钮做成 蓝底白字圆角矩形,用多层阴影做 伪 3D 凸起(顶面高光 + 底边厚度 +
短投影;悬停变亮、按下压入)。它的 大小、位置与改动前完全一致(76×28,仍在
「编辑」右侧):文案去掉「网页」二字后宽度不随文字收缩;外阴影向下控制在 5px
以内,再加 :host { overflow: hidden } 兜底,不侵入标题栏下方的工具栏。
运行保护:刷新会把正在运行的对话截断,所以按钮实时盯住 Host 的对话名册——
只要有对话在运行(或还有排队没跑完的工作),按钮就不允许使能(灰化、
cursor: not-allowed),点它只会弹出警告:
⚠ 警告 刷新操作会使当前运行的 n 个对话截断,请等待运行结束或手动中止运行
只有确认**所有对话全静默(不运行)**才执行刷新;连对话状态都查不到时,保守地 同样禁止刷新(宁可少刷不可误刷)。
按钮在哪
┌──────────────────────────────────────────────────────────────────────┐
│ [≡] [应用菜单] [编辑] [ 刷新 ] (标题栏空白处可拖动) ─ □ ✕ │
│ └─ 蓝底白字圆角,伪 3D 突出按钮 ─┘ │
└──────────────────────────────────────────────────────────────────────┘
只在 Windows 桌面端(DSH Desktop)出现 —— Web 浏览器版 GUI 没有这一栏菜单, 本插件在那里什么都不做。
实现方式
那一栏的菜单不是 Web 应用的 React 插槽,而是 Electron preload
(lib/preload-app.cjs 的 installWindowsMenu())挂到 document.body 的
<div data-windows-menu>,内部是一个 open shadow root,[role=menubar]
里依次放着「应用菜单」「编辑」两个按钮,样式由同一 shadow root 的 <style> 统一给出。
所以 client.js 做的是同源 DOM 手术:
- 等
[data-windows-menu]的 menubar 出现(preload 注入时机不定,因此带 节流的 MutationObserver 轮询,出现后立即停止观察); - 把
<button>刷新</button>追加到 menubar 末尾,正好落在「编辑」右侧; 挂载时先按上一版文案「网页刷新」量出既有宽高,再换成「刷新」并把宽高锁死, 所以删字后按钮大小、位置都不变; - 在同一 shadow root 装一份
button[data-dsh-web-refresh]样式:蓝底#2563eb、白字、圆角 8px,多层阴影做伪 3D——inset顶面高光与底面暗部、0 2px 0底边厚度、0 3px 5px -1px短投影;特异性压过 preload 的button/button:hover规则,悬停#3b82f6、按下#1d4ed8压入; - 按下 → 先查一次运行状态(见下):全静默才
window.location.reload(), 有对话在运行或状态未知就弹警告,不刷新。
运行状态从哪来
浏览器半拿不到 Host 的 agent 名册,所以 index.js(Host 半)开一个只读查询:
GET /plugins/dsh-desktop-web-refresh/api/active
→ { ok, known, count, running: [{ id, title }] }
「正在运行」的判据与桌面壳的退出检查一致:对话的 status === 'running',或
inbox 里还排着 nextTurn / nextStep。拿不到名册时如实答 known:false。
按钮每 2 秒轮询一次刷新视觉状态;按下时一定重新查一次作为权威判定(轮询
只管显示,判定永远走最新数据),所以按钮哪怕来不及变亮,也不会误刷新。弹窗是
页面层的 role="alertdialog" 浮层,点「知道了」、点遮罩或按 Esc 关闭。
阴影几何专门做了预算:外阴影向下可见延伸 ≤ 5px(按钮在 40px 标题栏带里垂直
居中,下方本有 6px 空隙),:host { overflow: hidden } 再兜一层底,任何意外
溢出都裁在标题栏带内,不会碰到下方工具栏。
注入是幂等的(data-dsh-web-refresh / data-dsh-web-refresh-style 标记),
插件卸载时会把按钮与样式一并摘掉。
文件
| 文件 | 作用 |
|---|---|
index.js |
Host 半。开 /api/active 报告运行中的对话数(判据同桌面壳退出检查)。 |
client.js |
浏览器半。定位标题栏菜单栏,插入「刷新」按钮(突出样式、尺寸锁定、阴影预算)与运行保护(禁用态 + 警告弹窗)。 |
cordis.patch.yml |
把本包的 dsh.client 行插入 Web roster。 |
package.json |
bundle + client 清单。 |
开发机安装(源码 link)
源码在工作区,桌面 profile 通过 link: 引用(与 dsh-workspace-archive 同款):
// ~/.dsh/profiles/desktop/package.json
"dependencies": {
"dsh-desktop-web-refresh": "link:C:/Users/Ash.Cran/Documents/CodeFiles/VibeCoding/dsh-desktop-web-refresh"
},
"dsh": { "profile": { "bundles": [ ..., "dsh-desktop-web-refresh" ] } }
改完在 ~/.dsh/profiles/desktop 跑一次 pnpm install 建立链接,然后重启
DSH Desktop(bundle 在启动时装载)。
分发到别的机器:一句话安装
本地插件包:dsh-desktop-web-refresh-1.0.0.tgz —— 零第三方依赖,离线可装。
把这个
.tgz拷到目标机器(任意方式:U 盘、网盘、局域网……);在那台机器的 DSH Desktop(Windows 桌面端) 里对 DSH 说一句话:
安装本地插件包:C:\你的路径\dsh-desktop-web-refresh-1.0.0.tgz
如果想要更稳的措辞:
用插件管理器把这个本地插件包装到 desktop profile:C:\你的路径\dsh-desktop-web-refresh-1.0.0.tgz 装完提醒我重启 DSH Desktop
DSH 会调
plugin_manager install_bundle:解压进node_modules、把包里的dsh.bundle.patch登记成组合包行。包没有第三方依赖,整个过程不需要联网。重启 DSH Desktop(bundle 在启动时装载),标题栏「编辑」右侧即出现按钮。
卸载同样一句话:
卸载插件 dsh-desktop-web-refresh
注意
- 按钮挂在 Windows 桌面端的窗口标题栏(与「最小化 / 还原 / 关闭」同栏),因此只在 Windows 的 DSH Desktop 出现;Web 浏览器版与 macOS 桌面端没有这栏菜单,装上后 按钮不显示(插件无其他副作用)。
- 装完没看到按钮:先按一次页面刷新,或重启 DSH Desktop —— bundle 是启动时装载的。
- 若 DSH 问装到哪个 profile,选 desktop(DSH Desktop 用的那个)。
备用安装(DSH 没有插件管理工具时)
有些会话预设不带 plugin_manager 工具。这时对 DSH 说:
把 C:\你的路径\dsh-desktop-web-refresh-1.0.0.tgz 用
pnpm add装进 ~/.dsh/profiles/desktop,再把dsh-desktop-web-refresh追加进该目录 package.json 的dsh.profile.bundles数组末尾,最后提醒我重启 DSH Desktop
等价手工步骤:
- 工作目录切到
~/.dsh/profiles/desktop,执行pnpm add <tgz 绝对路径>; - 编辑该目录的
package.json,在dsh.profile.bundles数组末尾追加"dsh-desktop-web-refresh"; - 重启 DSH Desktop。
只做第 1 步不够:bundle 是靠
dsh.profile.bundles选入的,install_bundle会自动补这一步,手工装时别忘了。
测试(重启后做)
- 启动 DSH Desktop,看标题栏「编辑」右侧是否出现 蓝底白字 的「刷新」按钮;
- 尺寸应与改动前一致(不因少两个字变窄),位置仍在「编辑」右侧、同一行;
- 伪 3D 效果:顶面有高光、底边有厚度与短投影;悬停变亮,按下有压入感;
- 阴影只在标题栏带内,不越过标题栏压到下方工具栏;
- 运行保护:随便发起一个对话让它跑着 —— 按钮应变灰(
cursor: not-allowed、 悬停提示「有 1 个对话正在运行,暂不可刷新」),点它只弹警告 「刷新操作会使当前运行的 1 个对话截断,请等待运行结束或手动中止运行」, 不会刷新; - 等对话跑完(或手动中止),按钮自动恢复蓝色可按,悬停提示变回 「重新加载 DSH Desktop 页面」;
- 此时按下按钮,整个 DSH Desktop 页面应当刷新(当前对话回到加载态后仍能从 会话列表进入,Host 侧会话不丢)。
No comments yet. Be the first to write one.