Repository navigation
fix(macos): 恢复隐藏标题栏窗口的原生全屏能力 - #1410
Conversation
989b96c to
a298493
Compare
Lithe Review结论: 未发现需要阻塞合并的问题。 Scope Check
Suggestions
Summary静态检查未发现明确的代码回归。守卫会在窗口挂载时处理 Verification
|
问题:当前 macOS 工具链下,SwiftUI 为 .hiddenTitleBar 窗口默认标记 collectionBehavior.fullScreenNone,绿色交通灯按钮因此退化为普通最大化 (action 被固化为 _setNeedsZoom:),toggleFullScreen(_:) 也被静默拒绝, 主窗口无法进入独立全屏 Space。源码构建版本与 v0.6.3 发布版本均复现。 修复:RootView 挂载 WindowFullScreenCapabilityGuard,通过 NSWindow.didUpdateNotification 持续剥离 SwiftUI 反复重设的 fullScreenNone 并补上 fullScreenPrimary;同时把绿色按钮重接到 zoomButtonClicked(_:)(先剥离再 toggleFullScreen),消除标志位竞争。 欢迎页、项目工作台与独立文件窗口共用 RootView,一并覆盖。 - 新增 WindowFullScreenCapabilityGuardTests 覆盖剥离、按钮重接与 SwiftUI 重设后的再次剥离(同步触发,无轮询) - 更新 window-controls 平台能力矩阵:明确绿色按钮应进入原生全屏 Space - 新增 Agent Note 记录根因、备选方案与验证方式
进入原生全屏后 macOS 会隐藏红绿灯按钮,但顶栏仍按普通窗口预留 WorkbenchTopBarMetrics.leadingInset(83pt),左上角出现一段空白。 新增 WindowFullScreenStateReader:复用 NSWindow.didUpdateNotification 机制把窗口全屏状态同步到 SwiftUI @State(无轮询),顶栏在全屏态将 leading padding 降为 0,退出全屏自动恢复预留,行为对齐 IDEA。 新增 WindowFullScreenStateReaderTests 覆盖进入/退出全屏的状态同步 (同步触发,无实时等待);同步更新 window-controls 能力矩阵验证动作 与全屏 Agent Note。
问题一:欢迎页全屏后打开项目,工作台只显示为居中的 1440×900,四周黑屏。 原因:布局切换的换框 setFrame 落在原生全屏窗口上。现在全屏期间跳过换框 (内容继续填满屏幕),退出全屏时补一次换框落到当前布局的正常尺寸;布局 未变的正常退出保持"恢复进入全屏前尺寸"的行为不变。已实测确认修复。 问题二:全屏相关测试直接写 styleMask 的 .fullScreen 位,AppKit 在真实 全屏过渡之外抛 NSGenericException,CI 的 macOS 测试进程整体崩溃。为 WindowFullScreenStateReader 与 LitheWindowCoordinator 增加可注入的全屏 判定接缝(默认行为不变),测试改用注入桩值驱动状态,不再触碰受保护 标志位。 新增 WindowLayoutFullScreenTransitionTests 覆盖全屏期间换框延迟与未变 布局退出不换框;既有 reader 测试改为注入式驱动。
881a364 to
43f3ac9
Compare
CI 的虚拟显示器只有 1024pt 宽,applyFrame 的屏幕钳制会把 1440pt 的目标宽度缩到 1000pt,导致 layoutTransitionWhileFullScreenDefersFrameSwapUntilExit 断言 window.frame.width == workspaceContentSize.width 失败。改为用 LitheWindowLayout.frame(_:fitting:) 按 applyFrame 相同的规则 计算期望宽度,无可见屏幕时不钳制,保证测试在不同显示尺寸下 结果一致。
xiaoyumuxi
left a comment
There was a problem hiding this comment.
跨 PR 审查(head dca90cd4)
结论:暂不建议合并;最新 head 的 macOS CI 仍为失败。 对应工作流。
读取 Swift tests job 日志后,失败位置在 SearchEverywhereBehaviorTests.swift:844-845 的 providerAndExclusionChangesKeepTheNativeFilterAnchorAlive(scheme:)(dark case,2 个断言),并有 1 个 Swift 测试超过本地时长门限;Run Swift unit tests 失败,macOS CI gate 因此失败。这些失败不在此次全屏 PR 的直接修改范围,暂不能归因于本次改动。 请在当前 head/基线对照复测并明确记录处置,不要因为打包 job 绿色而判定 CI 通过。
源码中全屏能力守卫、绿色按钮 action 重接及全屏退出后的窗口 frame 恢复路径已覆盖主要场景。另建议实机验证主窗口、Welcome 和独立编辑器窗口的进入/退出全屏、窗口按钮焦点与非全屏最大化行为,特别是在切换工作区布局期间进出全屏;同时解决当前 mergeable=false 的目标分支同步问题。
本次未在 macOS 上进行实机窗口操作。
|
跑过了的话记得艾特我,我给你合入一下 |
问题
macOS 主窗口(项目工作台、欢迎页、独立文件窗口)点击绿色交通灯按钮后,不会进入 macOS 标准的独立全屏 Space,而是在当前桌面上直接最大化;再次点击也无法还原到进入前的位置。从源码构建的 debug 版本与 v0.6.3 预编译版本均能复现。
根因
通过进程内探针(应用自动点击绿色按钮并记录窗口状态)定位到三个事实:
collectionBehavior含fullScreenNone(实测原始值0x10200=FullScreenNone | Primary)。全仓库源码历史从未设置过该标志,它来自 SwiftUI 对.windowStyle(.hiddenTitleBar)窗口的默认行为,随构建工具链/SDK 版本变化——这解释了较早版本正常、近期构建异常。_setNeedsZoom:(最大化),而不是全屏窗口应有的toggleFullScreen:;collectionBehavior事后变化不会触发按钮 action 重新求值。fullScreenNone还在,NSWindow.toggleFullScreen(_:)会被静默拒绝。探针前后对比:
.fullScreen{0, 85, 2560, 1330}(铺满可视区域=最大化){0, 0, 2560, 1440}(整屏=原生全屏 Space)修复方案
RootView挂载WindowFullScreenCapabilityGuard(NSViewRepresentable),宿主视图WindowFullScreenCapabilityView做三件事:viewDidMoveToWindow时订阅宿主窗口的NSWindow.didUpdateNotification;fullScreenNone并补上fullScreenPrimary(SwiftUI 会在场景更新中反复重设,一次性归一化实测无效);zoomButtonClicked(_:)——先剥离标志位再调用toggleFullScreen(_:),消除"点击瞬间标志位又被设置"的竞争。由于三类主窗口共用
RootView,欢迎页、项目工作台与独立文件窗口一并覆盖;设置窗口与软件更新窗口不经过RootView,不受影响。改动清单
macos/Sources/Lithe/Views/App/RootView.swift:新增WindowFullScreenCapabilityGuard/WindowFullScreenCapabilityView(+68 行),RootView body 挂载一行。macos/Tests/LitheTests/WindowFullScreenCapabilityGuardTests.swift:新增 3 个确定性测试——安装即剥离、按钮重接校验、SwiftUI 重设后经didUpdateNotification再次剥离(同步触发,无轮询、无实时等待)。shared/platform-feature-matrix/features/window-controls.json:能力描述明确"绿色按钮可进入原生全屏 Space(而非主桌面最大化)",macOS evidence 补充新测试,验证动作补充全屏 Space 检查。.agents/notes/implemented/bug-fix/2026-10-21-macos-hidden-titlebar-native-fullscreen.md:新增 Agent Note,记录根因证据、被否方案(仅 coordinator 归一化 / 不重接按钮 / 放弃 hiddenTitleBar)与验证方式。验证
toggleFullScreen被拒;修复后点击直接进入原生全屏 Space(fullScreen=true、styleMask=49167含.fullScreen、frame 覆盖整屏)。./scripts/verify-agent-notes.sh、./scripts/verify-platform-feature-matrix-change.sh origin/preview HEAD、./scripts/verify-platform-feature-matrix.sh、./.agents/skills/write-stable-tests/scripts/verify-test-stability.sh全部通过。风险评估
didUpdateNotification中的contains(_:)位检查开销可忽略。NSButton.target不会悬垂,option 点击的窗口缩放仍由按钮子类在 mouseDown 中处理。fullScreenNone,守卫的检查自然变为空操作。