主窗口顶栏改为标准高度 52pt:右上角按钮统一 32pt、上下留白一致,红绿灯留在侧边栏面板之外

This commit is contained in:
gentpan committed 2026-09-16 21:17:31 +05:00
1 parent 5cca1169bd
commit 75a161410f
6 files changed
+30 -11

No files matched your search

@@ -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
}
}
@@ -862,7 +862,6 @@ struct PageScroll<Content: View>: 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
@@ -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
/// 主窗口默认内容区宽度(侧边栏另计)
@@ -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)
}
}
@@ -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