Lightweight notification application for Wayland systems.
Currently bell is not packaged in any distribution.
To install it, you must compile it from source, and install it with cargo's commands:
cargo build [--release]
[sudo] cargo install After that, you should have a bell binary installed in your system.
Running it with no arguments will start the application, which will run forever until receiving SIGINT (Ctrl+C).
This application makes use of a TOML file for configuration. This file in searched in the following standard locations, in this order:
$XDG_CONFIG_HOME/bell/config.toml- XDG user configuration$HOME/.config/bell/config.toml- Linux-general user configuration/usr/local/share/bell/config.toml- Global configuration
The following is a sample configuration file detailing some configuration options available.
# Global options are specified without a group.
# They apply to all outputs unless they are overriden.
#
# All options valid for a single output are also valid for the global configuration.
#
# Colors are always specified in 0xAARRGGBB format.
# Size in pixels of the notification surface
width = 300
height = 120
# Layout of the notification message.
#
# All text can be customized by the <(option)=(value) ...> syntax.
# Available options currently are:
# font_size: Font size in pixels
# line_height: Force a specific line height, in pixels.
# color: Text foreground color in 0xAARRGGBB format
#
# Besides that, the following texts are substituted by the notification parameter:
# app_name: Name of the application that triggered the notification (if set).
# summary: Short text describing the notification.
# body: Full text body of the notification.
#
# In addition, basic markup is available on the layout and on the notification
# data itself, like <b>...</b> for bold text.
#
# The available markup is documented by the notification spec (besides hyperlinks
# and images, which are not yet supported):
# https://specifications.freedesktop.org/notification/latest/markup.html
message_layout = """
<b><font_size=18.0 summary></b>
from <i><app_name></i>
<font_size=12.0 body>
"""
# Icon theme to use when trying to render icons.
icon_theme = "Adwaita"
# Default sound to use with the 'play-sound' event. This is a global configuration, and cannot be changed between outputs.
default_sound = "/usr/share/sounds/freedesktop/stereo/message.oga"
# The following idle options are global configurations.
# Persist notifications (don't expire by timeout).
# This only applies to notifications that do not explicitly set a timeout, and don't have the 'transient' hint.
persist-when-idle = true
# Time (in ms) idling on any seat before considering the user as idle.
idle-time = 30000
# Special section for describing actions to perform upon interacting with the notification.
#
# The available triggers are:
# left-click, right-click, middle-click, on-notification-received, on-notification-closed
#
# The available actions are:
# nothing: Do nothing. The default when no action is configured for a trigger.
# close-notification: Close all surfaces of the current notification.
# exec: Execute a custom command. The syntax for that is:
# trigger = { exec = "<command with arguments>" }
# play-sound: Play a sound, either specified in the notification or configured with the 'default_sound' option.
# This is different from 'exec' in that it respects the 'suppress-sound', 'sound-file' and 'sound-name' hints in notification that have them.
# The argument to it is the command-line utility to play the sound. It must support a file path being passed as a positional argument.
# invoke-action: Invoke the default or first action when the notification has them.
# This is a WIP feature, so there's currently no option to select which action to invoke.
[events]
left-click = "invoke-action"
right-click = "close-notification"
on-notification-received = { play-sound = "mpv" }
# Specify per-input options.
[outputs."eDP-1"]
# Enable notifications to show up in this output. Options are:
# true (or "enabled"): Always show notifications on this output.
# false (or "disabled"): Never show notifications on this output.
# "when-active": Only show notifications on this output if it is active
# (depending on the compositor, this could either mean focused or most recently interacted with).
#
# A common approach is to set this option globally (for all outputs, or outside of an output grouping)
# to "when-active", so that a notification will only show on the currently active output.
enabled = true
# Default font family to use.
# Will fallback to the default system font if it could not be found
#
# Can be one of:
# Sans, SansSerif, Cursive, Fantasy, Monospace
# ... or a custom font family name, like below:
font_family = "Liberation"
# Default font size in pixels (height of each glyph).
font_size = 12.0
text_color = 0xFF000000
background_color = 0xFF80A0A0
border_color = 0xFF000000
border_size = 2
# Radius in pixels with which to round the border edges.
border_radius = 0
# Where to anchor the notification on the output.
#
# Available options are:
# Top, Bottom, Left, Right
#
# A combination of them (using '|') specifies an output corner.
anchor = "Right | Bottom"
# Direction on which notifications will stack if there's multiple of them.
# (e.g. 'Up' means that new notifications will push the old ones to above them).
#
# Available options are:
# Up, Down, Left, Right
direction = "Up"
# Layer on which to display the notification surfaces.
#
# Available options are:
# Background, Bottom, Top, Overlay
#
# For more information, see
# https://wayland.app/protocols/wlr-layer-shell-unstable-v1#zwlr_layer_shell_v1:enum:layer
layer = "Overlay"
# Margins from one notification to another and from the output borders.
#
# For instance, the following margins specify that notifications will have a
# spacing of 2 pixels from all borders of the screen, and between notifications,
# 4 pixels are expected (2 from each one's margins).
[outputs."eDP-1".margins]
top = 0
right = 2
bottom = 4
left = 4
# You can also specify different configurations for particular urgency levels.
# There are three documented urgency levels: 'Low', 'Normal' and 'Critical'.
[outputs."eDP-1".urgency.Critical]
background_color = 0xFFA08080
border_color = 0xFFCC4040This project relies on the wlr-layer-shell-unstable-v1 protocol extension in order to create the notification surfaces.
A list of compositors supporting this protocol can be found here.
Furthermore, the following protocols are also used when available in order to provide additional functionality:
wp_cursor_shape_manager_v1- Cursor format manipulation when hovering notifications.ext_idle_notifier_v1- Idle status monitoring for notification persistence.
This project was heavily inspired by mako, an amazing notification daemon for Wayland systems. In fact, I've only started working on this project because I wanted to specify per-output options, and it seemed like a good motivator for learning Rust!
The application is intended to be compatible with the latest Desktop Notification Specification (currently version 1.3), as specified by FreeDesktop.
The reference documentation can be found here.
While striving to be as independent and self-sufficient as possible, this project does make use of some third-party crates for some of the implemented functionality:
- dbus / dbus-crossroads: DBus integration for interacting with the notification system.
- wayland-client and protocol friends: Wayland integration.
- serde / toml: Deserialization of the configuration file.
- libc: Low-level interface to some required facilities (like
epollorshm_open). - cosmic-text: Text rendering facilities.
- png: Decoding of PNG icons.
This project also contains a crate for testing a server's implementation of the FreeDesktop notification specification. It is located in the crates subfolder.
It is a command-line utility for communicating with a server through DBus, testing different notification parameters, automatically whenever possible, or with user interaction when necessary.
