Files
ux/macos/Classes/WindowPlugin.swift
agra 76621a4132 window: extract XWindow primitive; XNotifications stops carrying focus
The window-focus signal had no business living on the notifications
primitive — it was there because the same NotificationsPlugin happened
to observe NSApplication active/resign for its own reasons. Splitting
it into a sibling XWindow primitive (with its own WindowPlugin on
macOS, ux/window/events) lets future consumers — paused video,
deferred-work scheduling, dock badge counts — read focus state without
pulling in UNUserNotificationCenter.

XNotifications now only exposes notification I/O (show/cancel + tap +
authorization). The 'type:focus' event-channel branch is gone.
2026-05-27 14:42:39 +03:00

69 lines
1.9 KiB
Swift

import AppKit
import FlutterMacOS
/// `ux/window/events`. Reports host-application focus state emits
/// `{type: "focus", focused: Bool}` whenever the active NSApplication
/// flips. Seeded from `NSApp.isActive` when Dart subscribes so the
/// emitter starts in a deterministic value.
public class WindowPlugin: NSObject, NativePlugin, FlutterStreamHandler {
private var eventChannel: FlutterEventChannel?
private var eventSink: FlutterEventSink?
public func register(with registrar: FlutterPluginRegistrar) {
let events = FlutterEventChannel(
name: "ux/window/events",
binaryMessenger: registrar.messenger,
)
events.setStreamHandler(self)
eventChannel = events
observeAppActivation()
}
// MARK: - FlutterStreamHandler
public func onListen(
withArguments arguments: Any?,
eventSink events: @escaping FlutterEventSink
) -> FlutterError? {
eventSink = events
emit(["type": "focus", "focused": NSApp.isActive])
return nil
}
public func onCancel(withArguments arguments: Any?) -> FlutterError? {
eventSink = nil
return nil
}
// MARK: - Observers
private func observeAppActivation() {
let nc = NotificationCenter.default
nc.addObserver(
self,
selector: #selector(onDidBecomeActive),
name: NSApplication.didBecomeActiveNotification,
object: nil,
)
nc.addObserver(
self,
selector: #selector(onDidResignActive),
name: NSApplication.didResignActiveNotification,
object: nil,
)
}
@objc private func onDidBecomeActive() {
emit(["type": "focus", "focused": true])
}
@objc private func onDidResignActive() {
emit(["type": "focus", "focused": false])
}
private func emit(_ event: [String: Any]) {
eventSink?(event)
}
}