From 75a161410f961f5058d6b3299582b97e2c1e807f Mon Sep 17 00:00:00 2001 From: gentpan Date: Wed, 16 Sep 2026 21:17:31 +0500 Subject: [PATCH] =?UTF-8?q?=E4=B8=BB=E7=AA=97=E5=8F=A3=E9=A1=B6=E6=A0=8F?= =?UTF-8?q?=E6=94=B9=E4=B8=BA=E6=A0=87=E5=87=86=E9=AB=98=E5=BA=A6=2052pt?= =?UTF-8?q?=EF=BC=9A=E5=8F=B3=E4=B8=8A=E8=A7=92=E6=8C=89=E9=92=AE=E7=BB=9F?= =?UTF-8?q?=E4=B8=80=2032pt=E3=80=81=E4=B8=8A=E4=B8=8B=E7=95=99=E7=99=BD?= =?UTF-8?q?=E4=B8=80=E8=87=B4=EF=BC=8C=E7=BA=A2=E7=BB=BF=E7=81=AF=E7=95=99?= =?UTF-8?q?=E5=9C=A8=E4=BE=A7=E8=BE=B9=E6=A0=8F=E9=9D=A2=E6=9D=BF=E4=B9=8B?= =?UTF-8?q?=E5=A4=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 3 ++- .../AppKit/MainWindowController.swift | 4 +-- .../OpenStatsUI/Design/Components.swift | 1 - .../Sources/OpenStatsUI/Design/Tokens.swift | 4 +-- .../OpenStatsUI/Panel/MainWindowView.swift | 26 ++++++++++++++++--- .../OpenStatsUI/Panel/ProcessesPage.swift | 3 ++- 6 files changed, 30 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 19ca48b..6f77779 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,10 +18,11 @@ #### 样式 -- 主窗口在 macOS 26 上改用液态玻璃:侧边栏是一块浮在窗口里的玻璃面板,红绿灯按钮落在面板里,选中项垫一块淡蓝色圆角底并随切换滑动;顶栏右侧“在菜单栏显示”一组收进玻璃胶囊。主按钮是蓝色玻璃胶囊、次要按钮与图标按钮是透明玻璃,风扇模式等快捷切换是玻璃胶囊,开关换成系统开关(拖动时滑块变成玻璃)。设置分组与数据卡片保持实色,与系统设置一致。macOS 14、15 上保持原来的样式。 +- 主窗口在 macOS 26 上改用液态玻璃:侧边栏是一块浮在窗口里的玻璃面板,选中项垫一块淡蓝色圆角底并随切换滑动;顶栏右侧“在菜单栏显示”一组收进玻璃胶囊。主按钮是蓝色玻璃胶囊、次要按钮与图标按钮是透明玻璃,风扇模式等快捷切换是玻璃胶囊,开关换成系统开关(拖动时滑块变成玻璃)。设置分组与数据卡片保持实色,与系统设置一致。macOS 14、15 上保持原来的样式。 - 菜单栏弹窗改为紧凑排版,参照 Stats:区块不再是灰底卡片,改成一条细分隔线隔开,行距收紧,顶栏按钮缩小;网络弹窗的 IP 纯净度与 DNS 默认收起成一行(纯净度显示分数与等级,DNS 显示正在使用的地址),点一下展开、标题栏右侧的箭头收起,状态会记住;流量图变矮,连接探测改为两行细格。网络弹窗从约 1520pt 降到约 950pt,其他弹窗矮了一到两成。主窗口的详情页保持原样,照常完整显示。 - IP 纯净度的标题行重新排版:置信度不再是带框的绿色徽章,改成标题旁一行浅灰小字,百分比按高低着色;“查看完整报告”文字链接换成外链图标,与刷新、收起并成一组按钮,macOS 26 上合成一颗玻璃胶囊。分数右侧的 cleanip.io 字标照旧可以打开完整报告。 - 连接探测只用来看网络通不通:格子通了是绿色、不通是红色(不再用橙色表示延迟偏高),固定 60 格,弹窗排成 3 行、主窗口排成 2 行;去掉格子下面的延迟、抖动、丢包三项,标题右侧也不再写探测地址与频率。打开网络详情时固定每秒探测一次,「设置 · 网络」里的“探测间隔”选项随之去掉,后台低频探测仍是每 10 秒。 +- 主窗口顶栏改为标准高度(52pt,原来 40pt):右上角的按钮、“在菜单栏显示”开关组与“防休眠已开启”标记统一为 32pt 高,上下各留 10pt,各页高度一致,不再偏上。macOS 26 上红绿灯按钮留在侧边栏玻璃面板之外,面板从顶栏下方开始、与右侧内容卡片顶边对齐,顶栏那一条可以按住拖动窗口。 - 分段切换改为苹果标准样式:灰色圆角底槽,各段等宽铺满,选中的一段是实心蓝色、白字,切换时蓝块滑过去;网络详情的 IPv4 / IPv6 切换同样是灰底蓝选中。 #### 新增 diff --git a/Packages/OpenStatsKit/Sources/OpenStatsUI/AppKit/MainWindowController.swift b/Packages/OpenStatsKit/Sources/OpenStatsUI/AppKit/MainWindowController.swift index f572060..b408f42 100644 --- a/Packages/OpenStatsKit/Sources/OpenStatsUI/AppKit/MainWindowController.swift +++ b/Packages/OpenStatsKit/Sources/OpenStatsUI/AppKit/MainWindowController.swift @@ -90,11 +90,11 @@ enum WindowChrome { window.titlebarAppearsTransparent = true window.titlebarSeparatorStyle = .none window.backgroundColor = .dsBackground - // 空的紧凑工具栏让标题栏与顶栏同高(40pt),红绿灯按钮与页面标题对齐 + // 空的标准工具栏让标题栏与顶栏同高(52pt),红绿灯按钮与页面标题、右上角按钮对齐 let toolbar = NSToolbar(identifier: "OpenStats.\(window.title)") toolbar.showsBaselineSeparator = false window.toolbar = toolbar - window.toolbarStyle = .unifiedCompact + window.toolbarStyle = .unified } } diff --git a/Packages/OpenStatsKit/Sources/OpenStatsUI/Design/Components.swift b/Packages/OpenStatsKit/Sources/OpenStatsUI/Design/Components.swift index 631cf66..b83cb9f 100644 --- a/Packages/OpenStatsKit/Sources/OpenStatsUI/Design/Components.swift +++ b/Packages/OpenStatsKit/Sources/OpenStatsUI/Design/Components.swift @@ -862,7 +862,6 @@ struct PageScroll: View { // 弹窗里区块之间靠分隔线隔开,不再额外留间距 let stack = VStack(alignment: .leading, spacing: isPopover ? 0 : DS.Space.s3) { content } .padding(.horizontal, DS.Space.s3) - .padding(.top, isPopover ? 0 : DS.Space.s3) .padding(.bottom, isPopover ? DS.Space.s1 : DS.Space.s3) if isSnapshot { stack diff --git a/Packages/OpenStatsKit/Sources/OpenStatsUI/Design/Tokens.swift b/Packages/OpenStatsKit/Sources/OpenStatsUI/Design/Tokens.swift index e046eb4..80ae627 100644 --- a/Packages/OpenStatsKit/Sources/OpenStatsUI/Design/Tokens.swift +++ b/Packages/OpenStatsKit/Sources/OpenStatsUI/Design/Tokens.swift @@ -166,8 +166,8 @@ extension DS { static let popoverWidth: CGFloat = 320 static let panelMinHeight: CGFloat = 320 static let panelGap: CGFloat = 4 - /// 窗口顶栏高度,与紧凑工具栏的标题栏同高,红绿灯按钮与页面标题在同一水平线上 - static let windowHeader: CGFloat = 40 + /// 窗口顶栏高度:标准工具栏的标题栏(52pt),红绿灯、页面标题与右上角 32pt 的按钮在同一条水平线上,按钮上下各留 10pt + static let windowHeader: CGFloat = DS.Space.s12 + DS.Space.s1 /// 主窗口首次打开的最小高度(屏幕放得下时) static let windowDefaultHeight: CGFloat = 720 /// 主窗口默认内容区宽度(侧边栏另计) diff --git a/Packages/OpenStatsKit/Sources/OpenStatsUI/Panel/MainWindowView.swift b/Packages/OpenStatsKit/Sources/OpenStatsUI/Panel/MainWindowView.swift index 505a546..644b3e4 100644 --- a/Packages/OpenStatsKit/Sources/OpenStatsUI/Panel/MainWindowView.swift +++ b/Packages/OpenStatsKit/Sources/OpenStatsUI/Panel/MainWindowView.swift @@ -99,10 +99,14 @@ private struct SidebarPanel: ViewModifier { func body(content: Content) -> some View { if DS.Glass.isAvailable, !isSnapshot { + // 红绿灯在面板外:面板从标题栏下方开始,标题栏那一条是窗口底色,按住可以拖动窗口 content .environment(\.isInsideGlass, true) .dsGlass(in: RoundedRectangle(cornerRadius: DS.Radius.xl, style: .continuous)) - .padding(DS.Space.s2) + .padding(.horizontal, DS.Space.s2) + .padding(.bottom, DS.Space.s2) + .padding(.top, DS.Size.windowHeader) + .background(alignment: .top) { WindowDragArea().frame(height: DS.Size.windowHeader) } } else { content } @@ -143,13 +147,17 @@ private struct MainSidebar: View { } .padding(.leading, DS.Space.s1) .padding(.trailing, DS.Space.s3) - // 顶部留出窗口红绿灯按钮的位置;玻璃面板本身离窗口顶边已有一圈边距 - .padding(.top, DS.Size.windowHeader + (usesGlassPanel ? 0 : DS.Space.s2)) + .padding(.top, sidebarTopPadding) .padding(.bottom, DS.Space.s3) } private var usesGlassPanel: Bool { DS.Glass.isAvailable && !isSnapshot } + /// 侧边栏内容离自身顶边的距离:玻璃面板在标题栏下方,只留一点边距;没有面板时给红绿灯留出标题栏的高度 + private var sidebarTopPadding: CGFloat { + usesGlassPanel ? DS.Space.s3 : DS.Size.windowHeader + DS.Space.s2 + } + private var navigation: some View { VStack(alignment: .leading, spacing: DS.Space.s1) { group(tr("监控"), PanelTab.monitors) @@ -206,7 +214,16 @@ private struct PageHeader: View { .background(WindowDragArea()) if model.keepAwake.isActive { - Chip(text: tr("防休眠已开启"), icon: "cup.and.saucer.fill", tone: .primary) + // 与右边的按钮同高,顶栏里的控件高度一致 + HStack(spacing: DS.Space.s1) { + Image(systemName: "cup.and.saucer.fill") + Text(tr("防休眠已开启")).lineLimit(1).fixedSize() + } + .dsFont(.xs, weight: .medium) + .foregroundStyle(DS.Palette.primary) + .padding(.horizontal, DS.Space.s3) + .frame(height: DS.Size.controlHeight) + .dsGlass(in: Capsule(), fallback: DS.Palette.primary.opacity(0.12)) } if tab == .memory { PurgeMemoryButton() } // 每个监控页都能在这里开关自己的菜单栏项目;温度与风扇页有两项,各带一个小标签 @@ -228,6 +245,7 @@ private struct PageHeader: View { } } .padding(.horizontal, DS.Space.s3 + DS.Space.s1) + // 52pt 高的顶栏里,32pt 的按钮与开关组上下各留 10pt .frame(height: DS.Size.windowHeader) } } diff --git a/Packages/OpenStatsKit/Sources/OpenStatsUI/Panel/ProcessesPage.swift b/Packages/OpenStatsKit/Sources/OpenStatsUI/Panel/ProcessesPage.swift index dfb2370..dfc6c12 100644 --- a/Packages/OpenStatsKit/Sources/OpenStatsUI/Panel/ProcessesPage.swift +++ b/Packages/OpenStatsKit/Sources/OpenStatsUI/Panel/ProcessesPage.swift @@ -88,7 +88,8 @@ struct ProcessesPage: View { } summary(count: rows.count) } - .padding(DS.Space.s3) + // 顶部不留边距:主窗口顶栏已经在按钮上下留了对称的空 + .padding([.horizontal, .bottom], DS.Space.s3) .frame(maxHeight: isSnapshot ? nil : .infinity, alignment: .top) .confirmationDialog(pendingQuit.map { tr("结束“\($0.title)”?") } ?? "", isPresented: Binding(get: { pendingQuit != nil }, set: { if !$0 { pendingQuit = nil } }), titleVisibility: .visible, presenting: pendingQuit) { row in