Replies: 1 comment
补充观察
Additional observations
|
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
中文
摘要
在 Safari(任何 WebKit 浏览器)中,若干客户端插件把
onBlur里relatedTarget === null误判为“焦点离开组件”,于是在mousedown与mouseup之间就卸载了浮层,选项的click永远不触发。用户看到的是:菜单/面板有内容、可以点,但点了没有任何效果,也不报错。Chromium 系(Chrome/Edge)不受影响。环境
@deepseek-ai/dsh0.1.6-alpha.2(npm 全局安装),macOS + Safaripackages/client/ui-model-selection(@deepseek-ai/dsh-client-ui-model-selection)——模型菜单点选无效(影响最大)packages/client/ui-directory-picker-browse——编辑路径时点击卡片内任意不可聚焦元素会取消编辑packages/client/ui-workflow-run——运行/阶段 disclosure 的 pending 收起被误触发,面板在指针下收起packages/client/ui-sidebar-documentpreview——经检查已安全,无需改动(见文末)实测环境(报告者机器)
@deepseek-ai/dsh0.1.6-alpha.2(npm 全局安装)复现步骤(模型菜单,稳定复现)
dsh web页面;session/selectModel请求。期望结果
选中该模型,触发标签更新,并发出
session/selectModel。根因
WebKit 点击
<button>不会给它焦点。当mousedown落在选项上时,此前被代码.focus()聚焦的菜单项触发focusout,且 WebKit 给出的event.relatedTarget是null。组件的onBlur只判断“新焦点是否仍在组件内”,null被判成“焦点已离开”,于是立刻close(),把 portal 菜单在mousedown与mouseup之间卸载,选项上的click永远不会触发。Chromium 会在点击时聚焦按钮,
relatedTarget指向菜单内部元素,onBlur提前 return,因此 Chrome/Edge 正常。这也解释了为什么“刷新页面 / 重启浏览器 / 重启 dsh / 换工作区”都无效:它不是页面状态问题,而是客户端代码问题。
证据(Playwright 真实 WebKit 引擎复现)
修复前的同一次点击:
菜单消失、标签不变、network 里没有
session/selectModel。修复后同一次点击:
正常发出
session/selectModel,标签更新为所选模型。建议修复
把
relatedTarget === null当作“未知”而不是“离开组件”。packages/client/ui-model-selection(ModelSelect 的 onBlur):packages/client/ui-workflow-run(settleRunBlur、settlePhaseBlur两处):packages/client/ui-directory-picker-browse:风格参照:
packages/client/ui-sidebar-documentpreview本来就写成if (event.relatedTarget instanceof Node && …),null instanceof Node === false,天然不受影响——这也是我建议的统一写法。本地验证
session/selectModel、标签更新)。mousedown处理器负责),未引入回归。node --check通过,整页加载 0 console/page 错误。English
Summary
In Safari (any WebKit browser) several client plugins treat
relatedTarget === nullinsideonBluras "focus left the widget". They therefore unmount a portal betweenmousedownandmouseup, so the option'sclicknever fires. The user sees a populated, clickable menu that silently does nothing — with no error. Chromium-based browsers are unaffected.Environment
@deepseek-ai/dsh0.1.6-alpha.2 (global npm install), macOS + Safaripackages/client/ui-model-selection— picking a model does nothing (highest impact)packages/client/ui-directory-picker-browse— clicking any non-focusable content inside the dialog card cancels the in-progress path editpackages/client/ui-workflow-run— the pending closure of a run/phase disclosure fires on such clicks and collapses the panel under the pointerpackages/client/ui-sidebar-documentpreview— verified safe; no change needed (see below)Tested environment (reporter machine)
@deepseek-ai/dsh0.1.6-alpha.2 (global npm install)Steps to reproduce (model menu; deterministic)
dsh webpage in Safari on macOS.session/selectModelrequest is sent.Expected
The picked model is applied, the label updates, and
session/selectModelis sent.Root cause
WebKit does not focus a
<button>on click. Whenmousedownlands on an option, the menu item that was programmatically focused earlier receivesfocusout, and WebKit reportsevent.relatedTarget === null. The handler only asks "is the new focus still inside the widget?", treatsnullas "focus left", and callsclose()immediately — unmounting the portaled menu beforemouseup, so the option'sclicknever happens.Chromium focuses the clicked button, so
relatedTargetpoints inside the menu, the handler returns early, and Chrome/Edge work.This also explains why reloading the page, restarting the browser, restarting dsh, or switching workspaces never helped: it is client code, not page state.
Evidence (reproduced in a real WebKit engine via Playwright)
Before the fix, one click produced:
The menu disappeared, the label stayed, and the network log contained no
session/selectModel.After the fix, the same click produced:
session/selectModelwas sent and the label switched to the picked model.Suggested fix
Treat
relatedTarget === nullas "unknown", not as "focus left the widget".packages/client/ui-model-selection(ModelSelect's onBlur):packages/client/ui-workflow-run(bothsettleRunBlurandsettlePhaseBlur):packages/client/ui-directory-picker-browse:Style reference:
packages/client/ui-sidebar-documentpreviewalready starts its condition withevent.relatedTarget instanceof Node && …; sincenull instanceof Node === false, it can never collapse on this blur. That is also the shape I would suggest standardising on.Local verification
session/selectModelrequest plus the updated label).mousedownlistener) — no regression.node --check, and the page boots with zero console/page errors.All reactions