Skip to content

把 Pickroom 规范剩下的几条落到 TheGit:NavigationSplitView、windowResizability、backgroundExtensionEffect、主窗口侧栏选中态 #35

Description

@zjywill

承接 #34。那个 issue 只解决了 Settings 侧栏的选中态(已换成系统 List(selection:),d42322f)。#34 评论里那份 Pickroom 规范还剩四条没落地,各自的风险和收益差得很远,所以拆到这里逐条评估——不是一个"照着清单改完"的任务,每条都要先判断在本仓库成不成立。

前提回顾:#34 里已复验过,macOS 26.5.2 上 List 的 reentrant-layout 崩溃不再复现(1500 次内联 zoom 翻转 + 选中切换 + resize,零 assert)。但那是四行静态内容的结论,不能直接外推到主窗口侧栏(见第 3 条)。


1. .windowResizability(.contentMinSize)(主窗口)

规范说:不要只写 .frame(minWidth:) 却让 NSWindow 继续缩得更小。

本仓库现状是知道这件事的,但用 AppKit 解决的:TheGitApp.swiftWindowFloor:512 起)是一个 NSViewRepresentable,专门把 window.contentMinSize 手动设上去。它的注释记录了原因——在 .windowStyle(.hiddenTitleBar).frame(minWidth:minHeight:) 没有变成窗口最小尺寸,窗口能拖得更小,内容居中后两侧同时被切掉。

要做的:验证 .windowResizability(.contentMinSize).hiddenTitleBar + macOS 26 下是否真的生效。如果生效WindowFloorcontentMinSize 那部分可以删掉——但注意它同时还负责 setFrameAutosaveName(窗口位置恢复)和"从过小的已保存 frame 恢复时纠正一次",这两件事 windowResizability 管不了,不能整个删。

收益:删掉一段 AppKit hack。风险低,可独立完成。

2. Settings 窗口 chrome → NavigationSplitView

规范第 5 节那份"不要采用"清单,SettingsRootView.swift 目前踩了三条:

  • SettingsWindowChrome:170 起)手动设 titlebarAppearsTransparent / titleVisibility / fullSizeContentView,并塞一个空的 unified NSToolbar 纯粹为了拿它的几何(把 traffic lights 挪到胶囊上);
  • 根视图 .ignoresSafeArea(.container, edges: .top) 把内容推到标题栏下;
  • 浮层胶囊的位置是写死的常数手算的:titleBarHeight = 52capsuleInset = 8capsuleRadius = 18,玻璃是自建的 SidebarMaterialNSVisualEffectView)+ clipShape + stroke

换成标准 NavigationSplitView 后这些理论上全部由系统负责。但这是本 issue 里最大的一块,动手前要想清楚:

  • 这套 chrome 现在是工作的,视觉上已经是 macOS 26 的浮层胶囊。换掉是把"手搓但正确"换成"系统画且正确",收益是维护性,不是修 bug。
  • SettingsWindowChrome 的注释记录了一个真实的坑:SwiftUI 的 Settings scene 在 app 失活/重新激活时会重设窗口属性,所以那些设置是挂在 key/occlusion 通知上反复施加的,不是设一次。换成 NavigationSplitView 后必须重测第一次 ⌘-tab 切出去再回来。
  • 侧栏宽度现在是 168 * zoom(跟 UI zoom 走)。NavigationSplitView 下要用 navigationSplitViewColumnWidth,且要确认它接受随 zoom 变化的值而不会打架。
  • 验收必须按规范第 6 节:open -n 全新启动看,而不是 resize 之后"看起来正常"。

3. 主窗口侧栏的自绘选中态(风险最高,建议单独排期)

SidebarView.swift:1285fill:选中 = Color.accentColor.opacity(0.15),hover = Color.primary.opacity(0.06),press 加深。就是规范第 3、5 节点名反对的模式,和 #34 修掉的是同一个反模式。

但这里正是 List 全局禁令当初写的那个视图,不能拿 #34 的复验结论直接换:

  • 几千行(大仓库的分支/标签/stash),LazyVStack + pinnedViews: [.sectionHeaders] + 可折叠分组 + 树形行 + 每行自带高度;
  • 一次 zoom 变更要把这些全部重新布局——SidebarView.swift:34 的注释说这里当初是 AppKit 布局异常的唯一来源。

要做的话,得先针对这个规模和结构重做一次压力复验(几千行 + 折叠展开 + zoom 翻转 + 过滤),而不是复用 #34 的探针结果。复验不过就维持现状,只把选中色调整得更贴近系统材质。

4. backgroundExtensionEffect()

规范里这条是给照片画布用的:把图片镜像模糊延展到浮动 sidebar 后面。

TheGit 没有照片画布。先判断本仓库有没有真实适用的地方(commit graph 背景?detail 面板?),没有就明确记下"不适用"并关掉这一条,不要为了对齐清单而加。真要用,因为 Package.swift 最低是 macOS 14,必须包 #available(macOS 26.0, *) 的 guard。


建议顺序

1 →(4 的判断,很快)→ 2 → 3。第 1 条独立且低风险;第 3 条最好等前面都稳定了再单独开分支做,而且随时可以判定"复验不过,维持现状"。

通用验收

  • open -n dist/TheGit.app 全新启动检查,不接受"resize 之后看起来正常";
  • 五档 UI zoom(85/95/100/115/130)都要过,这是本仓库比 Pickroom 多出来的一维;
  • 窗口拖到最小尺寸不裁切;
  • swift test 全绿(当前 359 个)。

注:#34 评论里的文件路径(PickroomApp.swift / SidebarView.swift / PhotoCanvas.swift)是 Pickroom 那边的,本仓库对应 TheGitApp.swift / SettingsRootView.swift / UI/SidebarView.swift

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions