Skip to content

fix(client): 面板锚点按最近包含块换算(修复皮肤下偏到屏幕右侧) - #14

Merged
Max-Samson merged 9 commits into
Max-Samson:mainfrom
rezon-aki:pr/panel-containing-block
Sep 23, 2026
Merged

Max-Samson merged 9 commits into
Max-Samson:mainfrom
rezon-aki:pr/panel-containing-block

Conversation

@rezon-aki

Copy link
Copy Markdown
Contributor

这个改动带来什么

  • 换成了兼容性更好的面板算法:面板位置不再建立在「没有祖先改变定位基准」这个假设上。无论主题/皮肤给输入框容器加了模糊(backdrop-filter)、变换(transform)还是容器查询,面板都会稳定贴在「用量」按钮上方。
  • 没有这类皮肤时落点与现在完全一致(逐值等价),不引入任何视觉变化。

现象

装了会给输入框所在 dock 的祖先加 backdrop-filter(或其它「创建包含块」属性)的皮肤时 —— 例如 maid-atelier 给 [data-slot='conversation.composer.dock'] > * 加了 backdrop-filter: blur(2px) —— 用量面板会跑到「用量」按钮右侧很远处,而不是贴在按钮上方。

根因

position: fixed 的定位基准是最近的包含块,不是视口。transform、translate/rotate/scale、perspective、filter、backdrop-filter、contain、container-type 以及匹配的 will-change 都会让该祖先成为包含块。锚点是用视口坐标算的,直接写进 left/bottom:存在这样的祖先时,视口坐标被相对它又应用了一次(落点约等于 按钮 left + 视口 left)。

修法

  • 定位前先找最近的包含块,把视口坐标换算到它的坐标系(left - base.left、base.bottom - rect.top + 8)。
  • 没有任何祖先创建包含块时计算不变:base 为 undefined,偏移取 0 与 window.innerHeight,与原来的视口算法完全一致。
  • 祖先探测把「属性不存在」一律当作「不创建包含块」,因此没有 backdropFilter / containerType / translate 的旧浏览器保持现有行为。
  • 窄窗口夹取补了一个下界:innerWidth - width - 8 小于 8 时 left 仍保持在屏幕内。

1 个文件,+25/−2,无新增依赖。

验证

  • npm run typecheck:0 错误。
  • npm test:41/41 通过(node 22,dsh 0.1.5-rc.2)。
  • 本机实测(dsh 0.1.5-rc.2):祖先带 backdrop-filter 时面板在按钮上方展开;不带时落点与改动前一致。

Max-Samson and others added 9 commits September 8, 2026 10:03
fix(host): use session.snapshotEvents() for dsh-session >= 0.1.2-rc.1
…session >= 0.1.2-rc.1)

- fix(host): adapt /usage route to use session.snapshotEvents() for dsh-session >= 0.1.2-rc.1 with fallback to legacy session.events (Max-Samson#7)
- test: add coverage for snapshotEvents() preference and fallback under /usage
- docs: update README and CHANGELOG to 1.1.4
- chore: bump version to 1.1.4 in package.json and package-lock.json
adj: add 4.1 flash and price change 0910
…ly time

ctx.effect(() => fileSource.dispose(), ...) calls dispose while the fiber is
being built and registers undefined as the disposer: the file source is dead
before its first read, so pricing.json is never applied and the change watcher
never fires. Return a disposer instead.

Test mocks now follow cordis semantics (run setup, keep the returned disposer,
release it in after()) and a /pricing route regression test covers the override
path - it fails against the old form.
A position:fixed box is laid out against its containing block, not the viewport:
any ancestor with transform / filter / backdrop-filter / contain / container-type
takes that role. The maid-atelier skin blurs the dock children
([data-slot='conversation.composer.dock'] > *, backdrop-filter: blur(2px)), so
the popover was offset by the indicator row's own origin and flew off to the
right of the screen.

Look up the nearest containing block and convert the viewport anchor into its
coordinate space; also guard the clamp range on narrow windows.
@rezon-aki
rezon-aki force-pushed the pr/panel-containing-block branch from ed11bd5 to 3851fad Compare September 20, 2026 00:40
@Max-Samson
Max-Samson self-requested a review September 23, 2026 15:19
@Max-Samson
Max-Samson merged commit 103e4b4 into Max-Samson:main Sep 23, 2026
2 checks passed
@Max-Samson

Copy link
Copy Markdown
Owner

非常感谢这个极其细致且专业的修复!

在支持现代 CSS 特效(如 backdrop-filter、transform、contain)的第三方皮肤/主题下,position: fixed 创建新包含块导致视口坐标二次偏移是一个非常隐蔽且棘手的定位问题。

containingBlock() 的祖先检测以及针对包含块坐标系的平滑换算逻辑清晰严谨,且在无特殊祖先时保持逐值等价,兼顾了兼容性与稳定性。非常感谢你的支持与贡献!

rezon-aki added a commit to rezon-aki/dsh-usage-chart that referenced this pull request Sep 23, 2026
- 上游 v1.1.7 已收录本 fork 早先提的 4 项修复(PR Max-Samson#10/Max-Samson#12/Max-Samson#14/Max-Samson#15)与合并事故修复
  (9753856),fork 不再重复维护它们;README / FORK_NOTES 改为「已并入上游」的口径。
- fork 独有改动只剩「面板可拖动」:panel-position.ts(持久化 + 包含块夹取)+
  UsageIndicator 把手/双击复位 + i18n/styles + tests/panel-position.test.mjs,
  直接取自上游 v1.1.7 基线上的实现(与本地 live 仓库同一份代码)。
- CHANGELOG 中英新增 [1.1.7-dsh.1] 段。
@rezon-aki
rezon-aki deleted the pr/panel-containing-block branch September 23, 2026 17:17
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