aboutsummaryrefslogtreecommitdiff
path: root/patches/patch-screen_hotplug-20260810-f6805c9.patch
diff options
context:
space:
mode:
Diffstat (limited to 'patches/patch-screen_hotplug-20260810-f6805c9.patch')
-rw-r--r--patches/patch-screen_hotplug-20260810-f6805c9.patch73
1 files changed, 73 insertions, 0 deletions
diff --git a/patches/patch-screen_hotplug-20260810-f6805c9.patch b/patches/patch-screen_hotplug-20260810-f6805c9.patch
new file mode 100644
index 0000000..1533b15
--- /dev/null
+++ b/patches/patch-screen_hotplug-20260810-f6805c9.patch
@@ -0,0 +1,73 @@
+diff --git a/Sources/bar/Models/AppDelegate.swift b/Sources/bar/Models/AppDelegate.swift
+index cefdfc0..5db4946 100644
+--- a/Sources/bar/Models/AppDelegate.swift
++++ b/Sources/bar/Models/AppDelegate.swift
+@@ -6,15 +6,10 @@ final class AppDelegate: NSObject, NSApplicationDelegate {
+ private var windows: [BarWindow] = []
+ private var blocks: [Block] = Config.blocks.map(\.resolved)
+ private var tokens: [UnsafeMutableRawPointer] = []
++ private var screenObserver: NSObjectProtocol?
+
+ func applicationDidFinishLaunching(_ notification: Notification) {
+- for screen in NSScreen.screens {
+- let frame = Screen.barFrame(screen, position: Config.position, height: Config.height)
+- let window = BarWindow(contentRect: frame)
+- window.contentView = NSHostingView(rootView: BarView(blocks: blocks))
+- window.orderFrontRegardless()
+- windows.append(window)
+- }
++ buildWindows()
+
+ // Register a listener to hide the bar
+ tokens.append(
+@@ -41,11 +36,24 @@ final class AppDelegate: NSObject, NSApplicationDelegate {
+
+ // Start the block's auto refresh
+ for block in blocks { block.start() }
++
++ // Observe screen changes — recreate windows when displays
++ // are added or removed.
++ screenObserver = NotificationCenter.default.addObserver(
++ forName: NSApplication.didChangeScreenParametersNotification,
++ object: nil,
++ queue: .main
++ ) { [weak self] _ in
++ self?.rebuildWindows()
++ }
+ }
+
+ func applicationWillTerminate(_ notification: Notification) {
+ for block in blocks { block.stop() }
+ for token in tokens { Notifier.cancel(token) }
++ if let observer = screenObserver {
++ NotificationCenter.default.removeObserver(observer)
++ }
+ }
+
+ /// Order out all bar windows
+@@ -68,6 +76,25 @@ final class AppDelegate: NSObject, NSApplicationDelegate {
+ }
+ }
+
++ /// Create a bar window for each connected screen.
++ @MainActor private func buildWindows() {
++ for screen in NSScreen.screens {
++ let frame = Screen.barFrame(screen, position: Config.position, height: Config.height)
++ let window = BarWindow(contentRect: frame)
++ window.contentView = NSHostingView(rootView: BarView(blocks: blocks))
++ window.orderFrontRegardless()
++ windows.append(window)
++ }
++ }
++
++ /// Remove all existing windows and create new ones for the current
++ /// set of screens — called when a display is connected or disconnected.
++ @MainActor private func rebuildWindows() {
++ for window in windows { window.orderOut(nil) }
++ windows.removeAll()
++ buildWindows()
++ }
++
+ /// Called from a Darwin notification handler. Marked `nonisolated` because
+ /// libnotify's delivery contract isn't statically visible to Swift, so we
+ /// hop back to the main actor explicitly.