Einstellungen: die Reiter schalten wieder, und die Leiste passt ins Fenster
Zwei Folgen der eigenen Reiterleiste, beide meine Schuld. Der Reiter oben sprang um, der Inhalt blieb stehen: der gewählte Reiter liegt im Fenster-Controller — er muss dort liegen, damit ein erneutes Öffnen ihn setzen kann, etwa auf „Berechtigungen", wenn eine fehlt. Der Controller war aber nicht beobachtbar. `TabView` fiel das nie auf, weil es seinen Zustand selbst führte und die Bindung nur benachrichtigte. Ein `switch` im Rumpf braucht dagegen eine Änderungsmeldung, und die kam nie. Jetzt ist der Controller `@Observable`, und beide Richtungen funktionieren. Zu breit war sie wegen `fixedSize`: sieben deutsche Beschriftungen brauchen rund 880 Punkte, und die nahm sich die Leiste auch dann, wenn das Fenster 780 breit war — sie ragte links und rechts über die Kante hinaus, der erste und der letzte Reiter waren nicht mehr erreichbar. Ohne feste Breite bleibt sie im Fenster, und das Fenster ist jetzt 920 breit statt 780, mit 900 als Mindestmaß. Darunter würde gestaucht. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -22,6 +22,8 @@ struct SettingsView: View {
|
|||||||
let fanControl: FanControl
|
let fanControl: FanControl
|
||||||
let launchAtLogin: LaunchAtLogin
|
let launchAtLogin: LaunchAtLogin
|
||||||
let showOnboarding: () -> Void
|
let showOnboarding: () -> Void
|
||||||
|
/// Der gewählte Reiter liegt im Fenster-Controller, damit ein erneutes
|
||||||
|
/// Öffnen ihn setzen kann — etwa auf „Berechtigungen", wenn eine fehlt.
|
||||||
@Binding var selectedTab: SettingsTab
|
@Binding var selectedTab: SettingsTab
|
||||||
|
|
||||||
/// Die Reiter in der Reihenfolge, in der sie oben stehen.
|
/// Die Reiter in der Reihenfolge, in der sie oben stehen.
|
||||||
@@ -50,9 +52,13 @@ struct SettingsView: View {
|
|||||||
}
|
}
|
||||||
.pickerStyle(.segmented)
|
.pickerStyle(.segmented)
|
||||||
.labelsHidden()
|
.labelsHidden()
|
||||||
// Nur so breit wie nötig und mittig: über die volle Fensterbreite
|
// Ohne feste Breite: sieben deutsche Beschriftungen brauchen rund
|
||||||
// gezogen sähen sieben Reiter aus wie eine Werkzeugleiste.
|
// 880 Punkte, und mit `fixedSize` nahm sich die Leiste die auch
|
||||||
.fixedSize()
|
// dann, wenn das Fenster schmaler war — sie ragte dann links und
|
||||||
|
// rechts über die Kante hinaus. Das Mindestmaß des Fensters sorgt
|
||||||
|
// dafür, dass hier trotzdem nichts gestaucht wird.
|
||||||
|
.frame(maxWidth: 1000)
|
||||||
|
.padding(.horizontal, 20)
|
||||||
.padding(.top, 10)
|
.padding(.top, 10)
|
||||||
.padding(.bottom, 14)
|
.padding(.bottom, 14)
|
||||||
|
|
||||||
|
|||||||
@@ -16,10 +16,17 @@ import ShelfProvider
|
|||||||
///
|
///
|
||||||
/// Ein eigenes `NSWindow` hat diese Abhängigkeit nicht. Es kostet ein paar
|
/// Ein eigenes `NSWindow` hat diese Abhängigkeit nicht. Es kostet ein paar
|
||||||
/// Zeilen mehr und funktioniert dafür.
|
/// Zeilen mehr und funktioniert dafür.
|
||||||
|
///
|
||||||
|
/// `@Observable`, und das ist keine Kür: der gewählte Reiter liegt hier, weil
|
||||||
|
/// ein erneutes Öffnen ihn setzen können muss. Ohne Beobachtung bemerkt die
|
||||||
|
/// View die Änderung nicht — weder die von außen noch die eigene. Genau daran
|
||||||
|
/// hing das Fenster, in dem der Reiter oben umsprang und der Inhalt stehen
|
||||||
|
/// blieb.
|
||||||
@MainActor
|
@MainActor
|
||||||
|
@Observable
|
||||||
final class SettingsWindowController: NSObject, NSWindowDelegate {
|
final class SettingsWindowController: NSObject, NSWindowDelegate {
|
||||||
|
|
||||||
private var window: NSWindow?
|
@ObservationIgnored private var window: NSWindow?
|
||||||
/// Muss außerhalb der View liegen, damit ein erneutes Öffnen den Reiter setzen kann.
|
/// Muss außerhalb der View liegen, damit ein erneutes Öffnen den Reiter setzen kann.
|
||||||
private var selectedTab: SettingsTab = .widgets
|
private var selectedTab: SettingsTab = .widgets
|
||||||
|
|
||||||
@@ -76,15 +83,16 @@ final class SettingsWindowController: NSObject, NSWindowDelegate {
|
|||||||
// mehr, und ein Fenster, in dem man scrollen muss, obwohl der
|
// mehr, und ein Fenster, in dem man scrollen muss, obwohl der
|
||||||
// Bildschirm frei ist, ist eine Zumutung.
|
// Bildschirm frei ist, ist eine Zumutung.
|
||||||
window.styleMask = [.titled, .closable, .miniaturizable, .resizable]
|
window.styleMask = [.titled, .closable, .miniaturizable, .resizable]
|
||||||
window.setContentSize(NSSize(width: 780, height: 660))
|
window.setContentSize(NSSize(width: 920, height: 680))
|
||||||
// Breit genug für die Reiterleiste.
|
// Breit genug für die Reiterleiste.
|
||||||
//
|
//
|
||||||
// Sechs Reiter mit deutschen Beschriftungen brauchen mehr, als man
|
// Sieben Reiter mit deutschen Beschriftungen brauchen rund 880
|
||||||
// beim Nachrechnen der reinen Textbreiten herausbekommt: macOS legt
|
// Punkte — mehr, als man beim Nachrechnen der reinen Textbreiten
|
||||||
// je Reiter Innenabstand und Trenner dazu. Ist das Fenster zu
|
// herausbekommt: macOS legt je Reiter Innenabstand und Trenner
|
||||||
// schmal, schneidet es die Leiste rechts einfach ab — der letzte
|
// dazu. Ist das Fenster schmaler, ragt die Leiste über beide
|
||||||
// Reiter ist dann nicht mehr erreichbar.
|
// Kanten hinaus, und der erste wie der letzte Reiter sind nicht
|
||||||
window.contentMinSize = NSSize(width: 740, height: 460)
|
// mehr erreichbar.
|
||||||
|
window.contentMinSize = NSSize(width: 900, height: 460)
|
||||||
window.isReleasedWhenClosed = false
|
window.isReleasedWhenClosed = false
|
||||||
window.delegate = self
|
window.delegate = self
|
||||||
Self.place(window)
|
Self.place(window)
|
||||||
|
|||||||
Reference in New Issue
Block a user