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.
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.
[ 13:55 Aug 25, 2023 More linux | permalink to this entry | ]