Skip to content

Commit 3780022

Browse files
committed
DesktopNotifierBackend: Drop notification param from handle_*() methods
We don't need the `Notification` instance in the platform-dependant code, thus drop it. We don't filter notifications on DesktopNotifier-level callbacks. Different notifications servers (and versions) signal differently: Some send any signal of any notification to anyone listening, some send signals of all notifications with the same `app_name`, some just the notifications this particular instance dispatched (and here some filter by PID, some by fd). We don't try to be smarter than the notifications server, simply pass everything through. It's up to the user to filter events as needed - or to use the `Notification` instance callbacks instead.
1 parent cfaded6 commit 3780022

File tree

5 files changed

+47
-66
lines changed

5 files changed

+47
-66
lines changed

src/desktop_notifier/backends/base.py

Lines changed: 21 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ async def send(self, notification: Notification) -> None:
6969
logger.debug("Notification sent: %s", notification)
7070
self._notification_cache[notification.identifier] = notification
7171

72-
self.handle_dispatched(notification.identifier, notification)
72+
self.handle_dispatched(notification.identifier)
7373

7474
def _clear_notification_from_cache(self, identifier: str) -> Notification | None:
7575
"""
@@ -146,54 +146,43 @@ async def get_capabilities(self) -> frozenset[Capability]:
146146
"""
147147
...
148148

149-
def handle_dispatched(
150-
self, identifier: str, notification: Notification | None = None
151-
) -> None:
149+
def handle_dispatched(self, identifier: str) -> None:
150+
notification = self._clear_notification_from_cache(identifier)
152151
if notification and notification.on_dispatched:
153152
notification.on_dispatched()
154153
elif self.on_dispatched:
155154
self.on_dispatched(identifier)
156155

157-
def handle_clicked(
158-
self, identifier: str, notification: Notification | None = None
159-
) -> None:
156+
def handle_clicked(self, identifier: str) -> None:
157+
notification = self._clear_notification_from_cache(identifier)
160158
if notification and notification.on_clicked:
161159
notification.on_clicked()
162160
elif self.on_clicked:
163161
self.on_clicked(identifier)
164162

165-
def handle_dismissed(
166-
self, identifier: str, notification: Notification | None = None
167-
) -> None:
163+
def handle_dismissed(self, identifier: str) -> None:
164+
notification = self._clear_notification_from_cache(identifier)
168165
if notification and notification.on_dismissed:
169166
notification.on_dismissed()
170167
elif self.on_dismissed:
171168
self.on_dismissed(identifier)
172169

173-
def handle_replied(
174-
self, identifier: str, reply_text: str, notification: Notification | None = None
175-
) -> None:
176-
if (
177-
notification
178-
and notification.reply_field
179-
and notification.reply_field.on_replied
180-
):
181-
notification.reply_field.on_replied(reply_text)
182-
elif self.on_replied:
170+
def handle_replied(self, identifier: str, reply_text: str) -> None:
171+
notification = self._clear_notification_from_cache(identifier)
172+
if notification:
173+
reply_field = notification.reply_field
174+
if reply_field and reply_field.on_replied:
175+
reply_field.on_replied(reply_text)
176+
return
177+
if self.on_replied:
183178
self.on_replied(identifier, reply_text)
184179

185-
def handle_button(
186-
self,
187-
identifier: str,
188-
button_identifier: str,
189-
notification: Notification | None = None,
190-
) -> None:
180+
def handle_button(self, identifier: str, button_identifier: str) -> None:
181+
notification = self._clear_notification_from_cache(identifier)
191182
if notification and button_identifier in notification._buttons_dict:
192183
button = notification._buttons_dict[button_identifier]
193-
else:
194-
button = None
195-
196-
if button and button.on_pressed:
197-
button.on_pressed()
198-
elif self.on_button_pressed:
184+
if button and button.on_pressed:
185+
button.on_pressed()
186+
return
187+
if self.on_button_pressed:
199188
self.on_button_pressed(identifier, button_identifier)

src/desktop_notifier/backends/dbus.py

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -226,16 +226,11 @@ def _on_action(self, nid: int, action_key: str) -> None:
226226
ourselves when scheduling the notification.
227227
"""
228228
identifier = self._platform_to_interface_notification_identifier.pop(nid, "")
229-
notification = self._clear_notification_from_cache(identifier)
230-
231-
if not notification:
232-
return
233229

234230
if action_key == "default":
235-
self.handle_clicked(identifier, notification)
236-
return
237-
238-
self.handle_button(identifier, action_key, notification)
231+
self.handle_clicked(identifier)
232+
else:
233+
self.handle_button(identifier, action_key)
239234

240235
def _on_closed(self, nid: int, reason: int) -> None:
241236
"""
@@ -246,13 +241,9 @@ def _on_closed(self, nid: int, reason: int) -> None:
246241
:param reason: An integer describing the reason why the notification was closed.
247242
"""
248243
identifier = self._platform_to_interface_notification_identifier.pop(nid, "")
249-
notification = self._clear_notification_from_cache(identifier)
250-
251-
if not notification:
252-
return
253244

254245
if reason == NOTIFICATION_CLOSED_DISMISSED:
255-
self.handle_dismissed(identifier, notification)
246+
self.handle_dismissed(identifier)
256247

257248
async def get_capabilities(self) -> frozenset[Capability]:
258249
if not self.interface:

src/desktop_notifier/backends/macos.py

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -94,21 +94,17 @@ def userNotificationCenter_didReceiveNotificationResponse_withCompletionHandler_
9494
self, center: objc_id, response: objc_id, completion_handler: objc_block
9595
) -> None:
9696
identifier = py_from_ns(response.notification.request.identifier)
97-
notification = self.implementation._clear_notification_from_cache(identifier)
9897

9998
if response.actionIdentifier == UNNotificationDefaultActionIdentifier:
100-
self.implementation.handle_clicked(identifier, notification)
101-
99+
self.implementation.handle_clicked(identifier)
102100
elif response.actionIdentifier == UNNotificationDismissActionIdentifier:
103-
self.implementation.handle_dismissed(identifier, notification)
104-
101+
self.implementation.handle_dismissed(identifier)
105102
elif response.actionIdentifier == ReplyActionIdentifier:
106103
reply_text = py_from_ns(response.userText)
107-
self.implementation.handle_replied(identifier, reply_text, notification)
108-
104+
self.implementation.handle_replied(identifier, reply_text)
109105
else:
110106
action_id = py_from_ns(response.actionIdentifier)
111-
self.implementation.handle_button(identifier, action_id, notification)
107+
self.implementation.handle_button(identifier, action_id)
112108

113109
completion_handler()
114110

src/desktop_notifier/backends/winrt.py

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -233,25 +233,21 @@ def _on_activated(
233233
if not sender:
234234
return
235235

236-
notification = self._clear_notification_from_cache(sender.tag)
237-
238236
if not boxed_activated_args:
239237
return
240238

241239
activated_args = boxed_activated_args.as_(ToastActivatedEventArgs)
242240
action_id = activated_args.arguments
243241

244242
if action_id == DEFAULT_ACTION:
245-
self.handle_clicked(sender.tag, notification)
246-
243+
self.handle_clicked(sender.tag)
247244
elif action_id == REPLY_ACTION and activated_args.user_input:
248245
boxed_reply = activated_args.user_input[REPLY_TEXTBOX_NAME]
249246
reply = unbox_string(boxed_reply)
250-
self.handle_replied(sender.tag, reply, notification)
251-
247+
self.handle_replied(sender.tag, reply)
252248
elif action_id.startswith(BUTTON_ACTION_PREFIX):
253249
button_id = action_id.replace(BUTTON_ACTION_PREFIX, "")
254-
self.handle_button(sender.tag, button_id, notification)
250+
self.handle_button(sender.tag, button_id)
255251

256252
def _on_dismissed(
257253
self,
@@ -261,13 +257,11 @@ def _on_dismissed(
261257
if not sender:
262258
return
263259

264-
notification = self._clear_notification_from_cache(sender.tag)
265-
266260
if (
267261
dismissed_args
268262
and dismissed_args.reason == ToastDismissalReason.USER_CANCELED
269263
):
270-
self.handle_dismissed(sender.tag, notification)
264+
self.handle_dismissed(sender.tag)
271265

272266
def _on_failed(
273267
self, sender: ToastNotification | None, failed_args: ToastFailedEventArgs | None

src/desktop_notifier/main.py

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -299,7 +299,10 @@ def on_clicked(self) -> Callable[[str], Any] | None:
299299
"""
300300
A method to call when a notification is clicked
301301
302-
The method must take the notification identifier as a single argument.
302+
The method must take the notification identifier as a single argument. You must
303+
check whether the given identifier matches any of the notifications you care
304+
about, because the notifications server might signal events of other
305+
applications as well.
303306
304307
If the notification itself already specifies an on_clicked handler, it will be
305308
used instead of the class-level handler.
@@ -315,7 +318,10 @@ def on_dismissed(self) -> Callable[[str], Any] | None:
315318
"""
316319
A method to call when a notification is dismissed
317320
318-
The method must take the notification identifier as a single argument.
321+
The method must take the notification identifier as a single argument. You must
322+
check whether the given identifier matches any of the notifications you care
323+
about, because the notifications server might signal events of other
324+
applications as well.
319325
320326
If the notification itself already specifies an on_dismissed handler, it will be
321327
used instead of the class-level handler.
@@ -332,7 +338,9 @@ def on_button_pressed(self) -> Callable[[str, str], Any] | None:
332338
A method to call when one of the notification's buttons is clicked
333339
334340
The method must take the notification identifier and the button identifier as
335-
arguments.
341+
arguments. You must check whether the given identifier matches any of the
342+
notifications you care about, because the notifications server might signal
343+
events of other applications as well.
336344
337345
If the notification button itself already specifies an on_pressed handler, it
338346
will be used instead of the class-level handler.
@@ -349,6 +357,9 @@ def on_replied(self) -> Callable[[str, str], Any] | None:
349357
A method to call when a user responds through the reply field of a notification
350358
351359
The method must take the notification identifier and input text as arguments.
360+
You must check whether the given identifier matches any of the notifications
361+
you care about, because the notifications server might signal events of other
362+
applications as well.
352363
353364
If the notification's reply field itself already specifies an on_replied
354365
handler, it will be used instead of the class-level handler.

0 commit comments

Comments
 (0)