Zenity for Notification Dialogs (Shallow Thoughts)

Akkana's Musings on Open Source Computing and Technology, Science, and Nature.

Fri, 25 Aug 2023

Zenity for Notification Dialogs

When I wrote about Getting Linux System Notifications under Openbox, I ended up tossing out the whole notification system and using zenity to pop up a dialog directly. Specifically, a command like XAUTHORITY=~/.Xauthority DISPLAY=:0 zenity --title "Hello" --info --text="Hello world"

But customizing zenity to make it more attention-getting turned out to be more difficult than expected ... and like many GTK problems. The more I looked into it, the more tempted I was to forget about zenity and just write a 10-line Python-tk script. But in the end, I found settings that worked okay.

First, I wanted a way of popping up different colors of dialog depending on the urgency of the warning, like dunst offers for notification dialogs.

In zenity: forget it. A web search shows lots of people asking, a few people speculating that it might theoretically be possible in GTK2 by specifying an alternate configuration directory and writing a custom theme; but even if you could figure out how to write a custom theme, the alternate-config GTK2 option is no longer offered with GTK3. You could probably fiddle something by changing $HOME, but there's so little guidance on writing GTK themes that in the end I decided it wasn't worth the hassle.

However, making the dialog wider even if the given text is short is easy: use --width and the pixel width you want.

[Zenity screenshot showing colors and line breaks] You can use a larger font or change the text color using inline <span> with CSS, which helps make the dialog more eyecatching:
--text="<span color='blue' font='15'>The Title</span><span color='red' font='14'>The content</span>"
though to add line breaks, you use not <br> tags but \n:
zenity --info --width 400 --text="<span color='blue' font='dejavu bold oblique 16'>Soliloquy</span>\n\n<span color='red' font='dragon wick 15'>To be, or not to be\nThat is the question</span>"

The Wrong Desktop Problem

That's most of what I needed. But there's one problem. When the at job fires, the zenity window pops up ... but it's often on a different desktop, so I don't see it until I happen to switch to the desktop where the zenity window appeared.

Some experimenting revealed that it was popping up on the virtual desktop from which I launched the at command. Weirdly, this was true even if I ran at on Thursday, shut the computer down, and booted it Friday morning; the at job still fired up on my second desktop.

(Aside: a nice feature of at that I discovered accidentally is that if it's noon now and you type at 9:00, it will automatically set up the job for tomorrow at 9am. No need to fiddle with formatting tomorrow's date.)

At stores environment variables from when it was run, which you can inspect via at -c jobid; if you didn't save your at job id, you can get it by running atq. But none of the environment variables listed there looks like it's storing the virtual desktop number.

It turns out I was hitting an obscure feature of zenity, documented in the zenity man page under ENVIRONMENT:

Normally, zenity detects the terminal window from which it was launched and keeps itself above that window. This behavior can be disabled by unsetting the WINDOWID environment variable.

I still wonder how that happens even across reboots. Does the WINDOWID of my first terminal on the second desktop always end up the same from day to day? Answer: no, I just tested that and the WINDOWID changed. So I still don't understand how zenity from an at job run yesterday decides to pop up on the second desktop.

Anyway, unsetting WINDOWID is an easy fix. In other words, tell at to run

XAUTHORITY=~/.Xauthority DISPLAY=:0 WINDOWID= zenity --title "Hello" --info --text="Hello world"

A Shell Wrapper

This worked fine ... but it's a lot to type every time I want a notification. So I wrote a shell wrapper for my .zshrc that builds up the right at+zenity command with colors, sizes and environment variables:

atnotify() {
    attime=$1
    shift
    at $attime <<EOF
XAUTHORITY=~/.Xauthority DISPLAY=:0 WINDOWID= zenity --width 700 \
    --title "at $attime" --info \
    --text="<span color='blue' font='15'>at $attime</span>\n\n<span color='red' font='14'>$*</span>"
EOF
}

Now I just type atnotify 11:55 Meeting starts in five minutes and I don't even need to quote the text. Much simpler.

Tags: , ,
[ 13:55 Aug 25, 2023    More linux | permalink to this entry | ]

Comments via Disqus:

blog comments powered by Disqus