Skip to content

base: Add window_ext for overlay/floating window configuration - #2964

Open
panzhifu wants to merge 9 commits into
longbridge:mainfrom
panzhifu:feat/window-ext-overlay-support
Open

base: Add window_ext for overlay/floating window configuration#2964
panzhifu wants to merge 9 commits into
longbridge:mainfrom
panzhifu:feat/window-ext-overlay-support

Conversation

@panzhifu

@panzhifu panzhifu commented Sep 5, 2026

Copy link
Copy Markdown
Contributor

Provides cross-platform APIs to configure OS-level window behavior:

  • Skip taskbar (hide from taskbar/dock/alt-tab)
  • Click-through (mouse events pass through window)
  • Always on top (window stays above other windows)

Supports macOS (NSWindow), Windows (Win32 API), and Linux/X11. Wayland is not supported due to protocol limitations.

Generated with assistance from Claude Code.

Closes #[issue number]

Description

Describe in English for the changes made in this pull request and the problem it solves.
Please keep 1 PR to solve 1 problem, and keep Small improvements should be small modifications to make PR easier to review and to merge.

Screenshot

Before After
[Put Before Screenshot here] [Put After Screenshot here]

Break Changes

Describe any breaking changes introduced by this pull request. If none, remove this section.

  • Change 1
- Old code snippet
+ New code snippet

How to Test

Please describe the tests that you ran to verify your changes. Provide instructions so we can reproduce.

Checklist

  • I have read the CONTRIBUTING document and followed the guidelines.
  • Reviewed the changes in this PR and confirmed AI generated code (If any) is accurate.
  • Passed cargo run for story tests related to the changes.
  • Tested macOS, Windows and Linux platforms performance (if the change is platform-specific)

Provides cross-platform APIs to configure OS-level window behavior:
- Skip taskbar (hide from taskbar/dock/alt-tab)
- Click-through (mouse events pass through window)
- Always on top (window stays above other windows)

Supports macOS (NSWindow), Windows (Win32 API), and Linux/X11.
Wayland is not supported due to protocol limitations.

Generated with assistance from Claude Code.
Fix Windows build errors:
- WINDOW_EX_STYLE is u32, not a struct
- SetWindowLongW/SetWindowPos take specific types
- SWP_* flags are SET_WINDOW_POS_FLAGS type

Generated with assistance from Claude Code.
- Use NSView::window() to get NSWindow from AppKitWindowHandle
- Replace NSUInteger with usize for collection behavior
- Remove unused ClassType import

Generated with assistance from Claude Code.
- Cast ns_view through as_ptr() instead of direct NonNull cast
- Use &*ns_window reference for msg_send! (Retained is not MessageReceiver)

Generated with assistance from Claude Code.
…import

- Use windows_sys (not windows) crate for Windows API
- Remove unused NSWindow import on macOS

Generated with assistance from Claude Code.
- HWND is a type alias, use type annotation instead of construction
- WS_EX_* are u32 constants, not newtypes (no .0 field)

Generated with assistance from Claude Code.
- windows-sys HWND is *mut c_void, use is_null() not is_invalid()
- handle.hwnd is NonZero<isize>, use .get() to extract raw value

Generated with assistance from Claude Code.

@huacnlee huacnlee left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

目前不建议合并,需要先澄清功能意图与架构归属,再处理实现问题。

PR 描述只列出了 skip taskbar、click-through 和 always-on-top 三个开关,没有说明具体应用场景、现有 WindowOptions / WindowKind::{Floating, PopUp} 为什么不能满足需求,以及为什么需要在 gpui-base 增加这组公开 API。描述中仍保留了未填写的模板内容,也没有可复现的功能测试步骤。请先补充这些信息。

此类新增功能必须随代码提交可运行的示例,明确展示实际使用场景;这是本次修改的合并要求,不是可选补充。 请在仓库中提供独立 example 或合适的 Story,说明用户要完成什么任务、为什么需要这些窗口行为,并展示窗口创建、配置调用、开关切换及预期效果。在 PR 中给出启动命令、操作步骤、适用平台和验证结果。仅提交 API 实现、零散文档片段,或笼统勾选“已运行 Story”,不能替代这个示例。示例也应让维护者能够实际复现并评估需求是否应该由本项目承担。

这些能力直接涉及原生窗口层级、输入区域和窗口管理器协议,原则上应由 GPUI 的平台窗口层统一维护。在 gpui-base 直接操作原生句柄,会绕过 GPUI 对窗口状态的管理,并让基础组件层承担另一套平台实现。请优先在 GPUI 层讨论和实现;如果确实需要在这里提供适配,请说明边界、现有 API 的缺口,以及如何与 GPUI 的状态保持一致。

当前代码还存在以下具体问题(基于 f58f9a06cd7ee1183e56bfb6735bbaea414ccd58,行号均指 crates/base/src/window_ext.rs):

  1. X11 分支不会执行(第 111 行):这里只匹配 RawWindowHandle::Xlib,但当前锁定版本 GPUI 的 X11 后端返回 XcbWindowHandle。实际调用会落入 _ => {},三个配置都静默无效。

  2. macOS 常量错误(第 175–183 行)1 << 6 实际是 IgnoresCycle1 << 71 << 8 分别是 FullScreenPrimaryFullScreenAuxiliary,并非注释所述含义;后两个还是不能同时指定的选项。ExcludedFromWindowsMenu 是独立 setter。请使用 AppKit 的类型化常量和方法,避免手写位值。

  3. macOS 无法恢复配置(第 172–203 行):只在选项为 true 时设置系统状态,传入 false 不执行恢复。例如先 set_click_through(window, true) 再传 false,窗口仍不接收鼠标事件。置顶和 collection behavior 也有类似问题。

  4. Windows 覆盖了已有扩展样式(第 230–247 行):从零构造 ex_style,再通过 SetWindowLongW 整体替换,会清掉 GPUI 设置的 WS_EX_NOREDIRECTIONBITMAP、对话框样式等。应保留无关标志,仅修改该功能负责的位。参见 SetWindowLongW 文档

  5. 切换穿透会重置 Windows 浮窗行为(第 142–143 行)set_click_through() 用其余字段均为 false 的完整配置调用 configure()。因此 make_floating() 后调用它,会取消置顶及隐藏任务栏配置,而不是只改变鼠标穿透。

  6. X11 点击穿透没有实现(第 326–333 行):即使修正句柄匹配,设置 _NET_WM_WINDOW_TYPE_SPLASH 也只是改变窗口类型,没有修改输入区域,不能实现鼠标事件穿透。需要实际处理 input shape,并支持恢复。参见 X Shape 协议

  7. X11 状态更新方式不正确且相互覆盖(第 294–323 行):对已映射窗口,应向根窗口发送 _NET_WM_STATE ClientMessage,而不是直接替换属性。当前 PropModeReplace 每次只写一个 atom,写入 ABOVE 还会覆盖之前的 SKIP_TASKBAR 及已有状态。参见 EWMH 规范

  8. 新增文档测试失败(第 12、30、92 行)gpui-base 的 doctest 无法解析未依赖的 gpui_kit;示例还包含不存在的 .skip_taskbar() / .click_through() / .always_on_top() 方法,以及未定义的 windowno_run 仍然需要编译通过。

本地执行 cargo test -p gpui-base --doc --locked --offline,结果为 14 passed、3 failed、7 ignored,失败的三项均来自本次新增模块。平台行为问题依据当前锁定依赖源码和协议核对,未在 macOS / Windows 上运行复现。

请先明确需求与实现层级,再提供各支持平台的可复现验证,至少覆盖开启/关闭、选项组合、保留已有窗口状态,以及不支持平台的明确行为。当前 CI 通过不足以证明这些原生窗口功能正确。

Panels that don't need zoom/close affordances (e.g. a fixed sidebar)
currently have no way to remove the ⋯ button. This adds
DockSkin::ellipsis_menu(true) so callers can hide it. Default is unchanged.

Refs longbridge#2983
- configure() and platform functions now return Result<()> instead of
  silently ignoring failures
- Windows: check SetWindowLongW/SetWindowPos return values, report OS errors
- macOS: document window level constant (5 = above floating)
- Linux: document click-through as partial (XShape not implemented),
  document per-call Display connection
- Add builder roundtrip and default-value tests
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.

2 participants