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.
This commit is contained in:
agra
2026-05-27 14:42:39 +03:00
parent c3e540599a
commit 76621a4132
6 changed files with 127 additions and 48 deletions

View File

@@ -2,10 +2,10 @@ import AppKit
import FlutterMacOS
import UserNotifications
/// `ux/notifications` + `ux/notifications/events`. Generic OS-notification
/// + app-focus surface used by hosts that want native Notification Center
/// entries on macOS. Domain-agnostic the Dart caller decides when to
/// emit and how to format the payload.
/// `ux/notifications` + `ux/notifications/events`. Domain-agnostic native
/// OS-notification surface: show / cancel via the method channel, tap +
/// authorization changes via the event channel. Window-focus state lives
/// in `WindowPlugin` (see `XWindow` on the Dart side).
public class NotificationsPlugin: NSObject, NativePlugin, FlutterStreamHandler,
UNUserNotificationCenterDelegate
{
@@ -31,7 +31,6 @@ public class NotificationsPlugin: NSObject, NativePlugin, FlutterStreamHandler,
eventChannel = events
UNUserNotificationCenter.current().delegate = self
observeAppActivation()
}
// MARK: - FlutterStreamHandler
@@ -41,9 +40,6 @@ public class NotificationsPlugin: NSObject, NativePlugin, FlutterStreamHandler,
eventSink events: @escaping FlutterEventSink
) -> FlutterError? {
eventSink = events
// Seed the initial focus state so Dart-side starts in a deterministic
// value rather than the constructor default.
emit(["type": "focus", "focused": NSApp.isActive])
return nil
}
@@ -171,32 +167,6 @@ public class NotificationsPlugin: NSObject, NativePlugin, FlutterStreamHandler,
}
}
// MARK: - App-activation 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])
}
// MARK: - UNUserNotificationCenterDelegate
public func userNotificationCenter(