Wezterm GUI Notifications

Wezterm has a utility for raising GUI system notifications, window:toast_notification(), which is a handy way to bring notifications to you that you might otherwise miss if the window is hidden or if a given tab is inactive.

However, on Linux, it's a far from ideal tool, at least under gnome-shell. (I don't know how it does on KDE or other desktop environments.) It raises the notification, but the notification never times out, even if you provide a timeout value (fourth argument to the function). This means that you have to manually dismiss the notification, which can be annoying, particularly if the notifications happen regularly.

So, I worked up my own utility.

notify.send

Since Wezterm uses Lua for configuration, configuration actually also acts as an extension mechanism. The primary wezterm Lua module itself provides a run_child_process function for spawning a system process, which allows me to call on the system notify-send utility.

As such, I wrote up the following Lua module:

### File: notify.lua
local wezterm = require 'wezterm'
local module  = {}

local function has_value (tab, val)
    for index, value in ipairs(tab) do -- luacheck: ignore 213
        if value == val then
            return true
        end
    end

    return false
end

local function notify (subject, msg, urgency)
    local allowed_urgency = { 'low', 'normal', 'critical' }
    urgency = urgency or 'normal'
    if not has_value(allowed_urgency, urgency) then
        urgency = 'normal'
    end

    wezterm.run_child_process {
        'notify-send',
        '-i',
        'org.wezfurlong.wezterm',
        '-a',
        'wezterm',
        '-u',
        urgency,
        subject,
        msg
    }
end

module.send = notify

return module

Within other configuration, when I want to send GUI notifications, I can do the following:

local notify = require './notify'

notify.send('Subject Line', 'This is the full message', 'low')

Some notes on usage:

  • The urgency argument is one of 'low', 'normal', or 'critical', and defaults to 'normal'. These correspond to the same --urgency option of notify-send, with the following behavior:
    • 'low' urgency messages are collected in the notification panel, but not displayed.
    • 'normal' urgency messages display until the system timeout for notifications is met. (For me, that's 3 seconds.) After that, it disappears into the notification panel.
    • 'critical' urgency messages require manual dismissal.
  • The subject argument is used for the notification subject; it's what you see without expanding the notification.
  • The msg argument is the full detail you want in the notification, and is shown when you expand the notification.

notify-send has a variety of other flags which can control things like timeout, whether or not the message is transient (i.e., will never be displayed in the notification panel), application category, etc. I've found for myself that just these three items are sufficient for probably 99% of any uses cases I'll need.