exlab_wizard.tray.notifications#

OS notifications via plyer with 5-second coalescing. Backend Spec §15.7.3.

Two notification triggers (Backend §15.7.3 / Frontend §3.4.5):

  • PluginInputRequired escalation when the window is not in the foreground.

  • NAS-sync failure with no auto-retry budget left.

Coalescing rule: a burst of N triggers within the same 5-second window collapses to one notification with a count (“ExLab-Wizard: N plugins need input”). Notifications are suppressed entirely when window_foregrounded is True; the operator is already looking at the UI in that case.

This module is the long-lived process’s OS-notification surface. ui/notifications.py is a separate module covering NiceGUI in-window notifications – distinct concern, distinct file.

Functions

notify(*, title, message[, notifier])

Fire a plyer notification (or an injected stub).

Classes

NotificationBus(*[, notifier, ...])

Coalescing layer over notify().

class exlab_wizard.tray.notifications.NotificationBus(*, notifier=None, is_window_foregrounded=None, coalescing_window=5.0)[source]#

Bases: object

Coalescing layer over notify().

The launcher constructs one bus and threads it through to the components that emit notification-eligible events (plugin host, NAS-sync). Components call emit(); the bus handles coalescing, foreground suppression, and the actual plyer call.

Parameters:
cancel_all()[source]#

Cancel every active timer without firing the notifications.

Return type:

None

emit(*, kind, title, message)[source]#

Submit a notification trigger.

If the window is foregrounded the call is dropped silently. Otherwise the trigger is added to its coalescing bucket; the first trigger in a window arms a timer that fires the actual notification at window end.

Parameters:
Return type:

None

flush_pending()[source]#

Drain every active bucket synchronously. Returns the bucket count.

Used by tests and by the quit coordinator to make sure no in-flight coalesce-buckets are dropped on shutdown.

Return type:

int

exlab_wizard.tray.notifications.TriggerKind#

alias of str

exlab_wizard.tray.notifications.notify(*, title, message, notifier=None)[source]#

Fire a plyer notification (or an injected stub).

notifier defaults to plyer.notification.notify which the plyer wheel auto-resolves to the platform-appropriate backend (UNUserNotificationCenter / ToastNotificationManager / libnotify). Tests pass a recording callable.

Parameters:
Return type:

None