Repository navigation
Two defects the portal fix introduced, and a way out when the header is gone.
Fixed
- The image preview was drawn under the panel, stayed open after its attachment was
removed, and cost the panel its input after a single character. Three symptoms, one
cause — and all of them a side effect of the previous release. To keep the mask's blur
from being cut short by an ancestor's containment, the layer portals itself tobody
— and that move lifted itsz-index: 2147483000out of the slot's stacking context and
into the root one, where it competed with the host's own overlays for the first time.
The host's lightbox portals tobodytoo, at a lower level, so it lost.- While a preview is open the layer steps below the lightbox; the lightbox is what
the user is looking at, and the mask only has to cover the page. It steps down only
during a preview. - Removing an attachment closes its preview. The host lightbox listens for keys in
the capture phase and pulls focus back to its own close button whenever its effect
re-runs — and itsonCloseis a fresh function on every render of this panel. So an
orphaned lightbox did not merely linger: typing one character into the panel made it
re-render, stole focus, and the panel stopped accepting input. That is what "one
character and then nothing" was.
- While a preview is open the layer steps below the lightbox; the lightbox is what
- The host's confirmation and approval dialogs were buried under the panel. The other
face of the same portal: once the layer escapes tobody, itsz-indexjoins the root
context, and at2147483000every host modal sat underneath it. On a real machine this
read as "the agent is waiting for your confirmation and all you can see is the panel" —
and under theaskpolicy those confirmations are frequent, each one costing a step of
closing or dragging the panel aside first.- The layer is
999now, whether or not it escaped. That number is measured, not
chosen: the host modal stack sits at 1000 and the page furniture tops out at
996, so the layer has to be above the latter (or the mask stops covering the
sidebar — the first symptom ever reported) and below the former. The usable band is
996–999.
- The layer is
- "Remember panel size" off plus "remember panel position" on could push the panel out of
the viewport, with no way to drag it back. The two switches are independent, so a stored
position could belong to a size that will never be used again — and the clamp was applied
against the stored size while the panel was drawn at the default one. Judging a
small panel's offset and then drawing a large one puttopbelow zero.- The clamp now uses the size the panel will actually be drawn at, and the top edge
keeps aMIN_TOP_INSETof 32px to clear the desktop shell's invisible window drag
strip at the top of the viewport — grabbing the header there moves the whole window
instead of the panel.
- The clamp now uses the size the panel will actually be drawn at, and the top edge
- Switching back to frosted glass left the panel looking solid. Turning the solid pane
on pushed the shared opacity to 100 (deliberately — the default 25% does not read as
solid), and switching back left that 100 in place: the frosted pane inherited it and
looked solid, with the value the user had chosen for frosted glass silently gone.- The two backgrounds now keep their own opacity (
solidOpacitydefault 100,
glassOpacitydefault 25); the slider edits whichever pane is on, and each returns to
its own value when you switch back. The solid switch no longer rewrites the other
pane's setting.
- The two backgrounds now keep their own opacity (
Added
Ctrl+0restores the panel to its default position and size, the same as
double-clicking the header. The reason is not convenience but rescue: the header is
the only control that can drag the panel back, so once it is off the viewport — or under
the desktop shell's invisible window drag strip — the mouse has no way left. It
deliberately does not require focus to be inside the panel, because that is exactly
the case where the panel cannot be clicked. It is the second key the panel claims, after
Esc, and only while the panel is open.
Compatibility
The bundle patch and the dsh manifest are untouched, so existing profiles keep working and a
disable row written against row id fullscreen-input still applies. Settings stored by
earlier versions read back unchanged — a stored glassOpacity keeps its value and
solidOpacity starts at 100, which is what the old behaviour produced anyway.
npm shasum (SHA1) 40e2b69537aa063d42f6792c228354c9b92f5adc
install dsh plugin --profile web add dsh-fullscreen-input
portal 修复带来的两个缺陷,以及一条「标题栏不见了」时的出路。
修复
- 打开图片预览后,预览图被压在面板下面;关掉附件后预览仍在,而且面板只打得进一个字符就失焦。 三个现象、一个根因,都是上一次修复的副作用。为了让遮罩雾化不被祖先的 containment 截断,层会 portal 到
body—— 而这一搬动把它的z-index: 2147483000从「槽位 stacking context 内部」提升到了根 context。它这才第一次真正跟宿主的模态比大小,而宿主的灯箱(ImageLightbox)自己也 portal 到body,层级比它低,于是被盖住。- 预览打开时,层降到灯箱之下:灯箱才是用户正在看的东西,遮罩只需要压住页面。只在预览期间降级,其余时间不变。
- 移除附件时连同预览一起关闭。 宿主灯箱在捕获阶段监听键盘,并在 effect 重跑时把焦点拉回自己的关闭按钮——而它的
onClose在本面板每次渲染时都是新函数。所以一个失去所属附件的灯箱不只是"留在那里":在面板里敲下一个字符就会让它重渲染、抢走焦点,面板随即失去输入能力。这正是「输入任意一个字符就失焦」的成因。
- 宿主的确认框与审批弹窗被面板整块压住。 这是同一个 portal 的另一面:层一旦逃逸到
body,它的z-index就进入根 context 参与比较,而它的值是2147483000—— 宿主所有模态都被埋在下面。真机上的表现是「agent 在等你确认,你只看到面板」,而ask策略下这类确认很频繁,每次都得多一步「先关掉或拖开面板」。- 层改用
999,无论是否逃逸。这个值不是拍的,是在真机上量出来的区间:宿主模态栈是 1000,而页面家具最高到 996,层必须同时高于后者(否则遮罩盖不住侧边栏——那正是最早报过的那个现象)与低于前者,可用区间只有 996–999。
- 层改用
- 关掉「记住面板大小」+ 打开「记住面板位置」,会把面板顶出屏幕并且拖不回来。 两个开关是独立的,于是存下来的位置可能属于一个再也不会用到的尺寸——而夹紧用的正是存储的尺寸,渲染用的却是默认尺寸。等于拿小面板判断偏移合法、再画出一个大面板,
top因此可以是负的。- 夹紧改用面板实际将要渲染的尺寸;顶边不再允许贴到
0,保留MIN_TOP_INSET = 32以避开桌面壳在视口顶部那条不可见的窗口拖动条——在那里抓住 header 拖动会拖动整个窗口,而不是面板。
- 夹紧改用面板实际将要渲染的尺寸;顶边不再允许贴到
- 切回毛玻璃之后,面板看起来仍然是纯色的。 「纯色面板」开启时会把共用的那份不透明度推到 100(这是刻意的:底色默认只有 25%,不推满就不像纯色),但切回毛玻璃时那份 100 还留着——毛玻璃继承了它,于是看起来和纯色一样,而用户先前为毛玻璃调好的浓度已经悄悄丢了。
- 现在两种底色各记一份(
solidOpacity默认 100、glassOpacity默认 25),滑块编辑的是当前这一种的那一份,来回切换时两边各自回到自己调过的值。开关也不再改写另一种模式的数值。
- 现在两种底色各记一份(
新增
Ctrl+0把面板恢复到默认位置与默认大小,与双击标题栏等价。加它的理由不是方便,而是自救:header 是唯一能用鼠标把面板拖回来的控件,一旦它跑到视口之外、或者恰好落在桌面壳那条不可见的窗口拖动条下面,鼠标就没有任何办法了。为此它不要求焦点在面板内 —— 只要面板开着就生效,这正是"点不到面板"时唯一还能用的路径。它是面板继Esc之后抢占的第二个键,且只在面板打开期间监听。
兼容性
组合包补丁与 dsh manifest 均未改动,所以现有 profile 照常工作,针对 row id fullscreen-input 写的禁用行仍然有效。更早版本存下的设置读回来行为不变:glassOpacity 保持原值,solidOpacity 从 100 开始——那本来就是旧行为会得到的值。