💾 Archived View for sylvaindurand.org › update-notifications-with-libnotify › index.gmi captured on 2022-04-29 at 11:22:58. Gemini links have been rewritten to link to archived content

View Raw

More Information

⬅️ Previous capture (2022-04-28)

-=-=-=-=-=-=-

sylvaindurand.org

Update notifications with libnotify

The libnotify library allows you to send desktop notifications to a notification daemon commonly used under Linux. Here we will see how to successfully update notifications already displayed.

With notify-send?

This library offers the `notify-send` command, which displays a notification directly on the desktop:

notify-send "Notification title" "Notification description"

But what if you want to update or delete a notification already displayed? If this command is executed several times, the notifications pile up rather than updating the one that has just been sent.

The manual (`man notify-send`) shows us that the options are rather short and do not allow us to expect much:

-?, --help
-u, --urgency=LEVEL
-t, --expire-time=TIME
-i, --icon=ICON[,ICON...]
-c, --category=TYPE[,TYPE...]
-h, --hint=TYPE:NAME:VALUE

We will therefore have to move away from it and return to the fundamentals.

Using gdbus

`notify-send` simply sends information as defined in the "Desktop Notifications" specification, which we will be able to do ourselves with `gdbus`.

The following function will allow us to obtain the same result as before:

gdbus call \
    --session \
    --dest org.freedesktop.Notifications \
    --object-path /org/freedesktop/Notifications \
    --method org.freedesktop.Notifications.Notify \
    "identifier" \
    "1" \
    "" \
    "Notification title" \
    "Notification description" \
    "[]" \
    "{}" \
    "2000"

The second identifier (here `1`) concerns the id of the notification we wish to replace, we will come back to this shortly. The next identifier allows you to define an icon. `"[]"` allows you to define actions, `"{}"` to define hints, and finally the last argument `2000` presents the time during which the notification must remain visible (in milliseconds).

Once this command is executed, the system returns a response that looks like :

(uint32 13,)

This number, here `13`, is the id of the notification that we will be able to replace.

This means that the following command will not create a new notification, but will replace the one we just created:

gdbus call \
    --session \
    --dest org.freedesktop.Notifications \
    --object-path /org/freedesktop/Notifications \
    --method org.freedesktop.Notifications.Notify \
    "identifier" \
    "13" \
    "" \
    "My updated title" \
    "My updated description" \
    "[]" \
    "{}" \
    "2000"

Getting notification id

All that remains is to automatically retrieve this number, and to reinject it as an argument in our function.

To retrieve it, filter the previous function with :

| sed 's/[^ ]* //; s/,.//'

We could then store the number in a temporary file, for example with `> /tmp/.notif`. However, to avoid using the hard disk or the SSD, let's go directly to the RAM :

> ${XDG_RUNTIME_DIR}/.notif

This number can be initiated at startup with :

echo '1' > ${XDG_RUNTIME_DIR}/.notif

It is then easily retrieved with:

notif=`cat ${XDG_RUNTIME_DIR}/.notif`

Result

The following code, executed several times, will then update the notification :

notif=`cat ${XDG_RUNTIME_DIR}/.notif`
gdbus call \
    --session \
    --dest org.freedesktop.Notifications \
    --object-path /org/freedesktop/Notifications \
    --method org.freedesktop.Notifications.Notify \
    "identifier" \
    "`echo $notif`" \
    "" \
    "My updated title" \
    "My updated description" \
    "[]" \
    "{}" \
    "2000" \
| sed 's/[^ ]* //; s/,.//' > ${XDG_RUNTIME_DIR}/.notif