mirror of
https://github.com/kovidgoyal/kitty
synced 2026-06-06 01:05:48 +02:00
Allow multiple types per notification
This commit is contained in:
@@ -67,8 +67,11 @@ by means of two keys ``f`` which is the application name and ``t``
|
||||
which is the notification type. These are free form keys, they can contain
|
||||
any values, their purpose is to allow users to easily filter out
|
||||
notifications they do not want. Both keys must have :ref:`base64`
|
||||
encoded UTF-8 text as their values. Terminals can then present UI to users
|
||||
to allow them to filter out notifications from applications they do not want.
|
||||
encoded UTF-8 text as their values. The ``t`` key can be specified multiple
|
||||
times, as notifications can have more than one type. See the `freedesktop.org
|
||||
spec
|
||||
<https://specifications.freedesktop.org/notification-spec/notification-spec-latest.html#categories>`__
|
||||
for examples of notification types.
|
||||
|
||||
.. note::
|
||||
The application name should generally be set to the filename of the
|
||||
@@ -273,7 +276,7 @@ Key Value Default Description
|
||||
``e`` ``0`` or ``1`` ``0`` If set to ``1`` means the payload is :ref:`base64` encoded UTF-8,
|
||||
otherwise it is plain UTF-8 text with no C0 control codes in it
|
||||
|
||||
``f`` :ref:`base64` ``unset`` The name of the application sending the notification. Can be used to filter out notifications.
|
||||
``f`` :ref:`base64` ``unset`` The name of the application sending the notification. Can be used to filter out notifications.
|
||||
encoded UTF-8
|
||||
application name
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ def log_notification(nc: NotificationCommand) -> None:
|
||||
print(f'title: {nc.title}', file=log)
|
||||
print(f'body: {nc.body}', file=log)
|
||||
print(f'app: {nc.application_name}', file=log)
|
||||
print(f'type: {nc.notification_type}', file=log)
|
||||
print(f'types: {nc.notification_types}', file=log)
|
||||
print('\n', file=log)
|
||||
|
||||
|
||||
@@ -48,7 +48,7 @@ def main(nc: NotificationCommand) -> bool:
|
||||
# run a script if this notification is from myapp and has
|
||||
# type foo, passing in the title and body as command line args
|
||||
# to the script.
|
||||
if nc.application_name == 'myapp' and nc.notification_type == 'foo':
|
||||
if nc.application_name == 'myapp' and 'foo' in nc.notification_types:
|
||||
subprocess.Popen(['/path/to/my/script', nc.title, nc.body])
|
||||
|
||||
# do some arbitrary actions when this notification is activated
|
||||
|
||||
@@ -209,7 +209,7 @@ class NotificationCommand:
|
||||
icon_data_key: str = ''
|
||||
icon_names: Tuple[str, ...] = ()
|
||||
application_name: str = ''
|
||||
notification_type: str = ''
|
||||
notification_types: tuple[str, ...] = ()
|
||||
timeout: int = -2
|
||||
|
||||
# event callbacks
|
||||
@@ -297,17 +297,17 @@ class NotificationCommand:
|
||||
self.icon_data_key = sanitize_id(v)
|
||||
elif k == 'n':
|
||||
try:
|
||||
self.icon_names += (base64_decode(v).decode('utf-8', 'replace'),)
|
||||
self.icon_names += (base64_decode(v).decode('utf-8'),)
|
||||
except Exception:
|
||||
self.log('Ignoring invalid icon name in notification: {v!r}')
|
||||
elif k == 'f':
|
||||
try:
|
||||
self.application_name = base64_decode(v).decode('utf-8', 'replace')
|
||||
self.application_name = base64_decode(v).decode('utf-8')
|
||||
except Exception:
|
||||
self.log('Ignoring invalid application_name in notification: {v!r}')
|
||||
elif k == 't':
|
||||
try:
|
||||
self.notification_type = base64_decode(v).decode('utf-8', 'replace')
|
||||
self.notification_types += (base64_decode(v).decode('utf-8'),)
|
||||
except Exception:
|
||||
self.log('Ignoring invalid notification type in notification: {v!r}')
|
||||
elif k == 'w':
|
||||
@@ -332,11 +332,11 @@ class NotificationCommand:
|
||||
if not self.icon_data_key:
|
||||
self.icon_data_key = prev.icon_data_key
|
||||
if prev.icon_names:
|
||||
self.icon_names += prev.icon_names
|
||||
self.icon_names = prev.icon_names + self.icon_names
|
||||
if not self.application_name:
|
||||
self.application_name = prev.application_name
|
||||
if not self.notification_type:
|
||||
self.notification_type = prev.notification_type
|
||||
if prev.notification_types:
|
||||
self.notification_types = prev.notification_types + self.notification_types
|
||||
if self.timeout < -1:
|
||||
self.timeout = prev.timeout
|
||||
self.icon_path = prev.icon_path
|
||||
@@ -402,7 +402,11 @@ class NotificationCommand:
|
||||
def matches_rule_item(self, location:str, query:str) -> bool:
|
||||
import re
|
||||
pat = re.compile(query)
|
||||
val = {'title': self.title, 'body': self.body, 'app': self.application_name, 'type': self.notification_type}[location]
|
||||
if location == 'type':
|
||||
for x in self.notification_types:
|
||||
if pat.search(x) is not None:
|
||||
return True
|
||||
val = {'title': self.title, 'body': self.body, 'app': self.application_name}[location]
|
||||
return pat.search(val) is not None
|
||||
|
||||
def matches_rule(self, rule: str) -> bool:
|
||||
|
||||
@@ -14,11 +14,11 @@ from . import BaseTest
|
||||
|
||||
def n(
|
||||
title='title', body='', urgency=Urgency.Normal, desktop_notification_id=1, icon_names=(), icon_path='',
|
||||
application_name='', notification_type='', timeout=-1,
|
||||
application_name='', notification_types=(), timeout=-1,
|
||||
):
|
||||
return {
|
||||
'title': title, 'body': body, 'urgency': urgency, 'id': desktop_notification_id, 'icon_names': icon_names, 'icon_path': icon_path,
|
||||
'application_name': application_name, 'notification_type': notification_type, 'timeout': timeout
|
||||
'application_name': application_name, 'notification_types': notification_types, 'timeout': timeout
|
||||
}
|
||||
|
||||
|
||||
@@ -53,7 +53,7 @@ class DesktopIntegration(DesktopIntegration):
|
||||
self.counter += 1
|
||||
did = self.counter
|
||||
title, body, urgency = cmd.title, cmd.body, (Urgency.Normal if cmd.urgency is None else cmd.urgency)
|
||||
ans = n(title, body, urgency, did, cmd.icon_names, os.path.basename(cmd.icon_path), cmd.application_name, cmd.notification_type, timeout=cmd.timeout)
|
||||
ans = n(title, body, urgency, did, cmd.icon_names, os.path.basename(cmd.icon_path), cmd.application_name, cmd.notification_types, timeout=cmd.timeout)
|
||||
self.notifications.append(ans)
|
||||
return self.counter
|
||||
|
||||
@@ -264,9 +264,9 @@ def do_test(self: 'TestNotifications', tdir: str) -> None:
|
||||
def e(x):
|
||||
return standard_b64encode(x.encode()).decode()
|
||||
|
||||
h(f'i=t:d=0:f={e("app")};title')
|
||||
h(f'i=t:d=0:f={e("app")}:t={e("1")};title')
|
||||
h(f'i=t:t={e("test")}')
|
||||
self.ae(di.notifications, [n(application_name='app', notification_type='test')])
|
||||
self.ae(di.notifications, [n(application_name='app', notification_types=('1', 'test',))])
|
||||
reset()
|
||||
|
||||
# Test timeout
|
||||
|
||||
Reference in New Issue
Block a user