Bezel is a Linux daemon that provides customizable trackpad edge gestures. It intercepts raw trackpad inputs via evdev and dispatches shell commands based on directional swipes or taps along the edges (zones) of your trackpad.
Bezel is Linux-only (Wayland required).
curl -sSfL https://raw.githubusercontent.com/indra55/bezel/main/install.sh | bash(To update to a newer version, simply run this exact same command again. It will safely back up your old binary and seamlessly restart the service.)
cargo install --git https://github.com/indra55/bezelNormally we'd just tell you to yay -S bezel, but the AUR is currently experiencing a massive malware apocalypse. Someone adopted 1,500 orphaned packages and turned them into malware, so Arch had to disable new account registrations. We have our PKGBUILD ready to go, but until they put out the fire, you'll have to use the prebuilt binary or build from source like a normal person. Stay safe out there!
You can try out Bezel using this command:
nix run github:indra55/bezelFor a permanent installation, first add Bezel to your flake inputs:
{
inputs = {
# ... other inputs
bezel = {
url = "github:Indra55/bezel";
inputs.nixpkgs.follows = "nixpkgs";
};
};
# ... rest of your flake
}Also make sure that you have extraSpecialArgs = { inherit inputs; }; in your flake outputs.
Bezel provides a NixOS module. To enable it:
{ inputs, ... }: {
imports = [
inputs.bezel.nixosModules.default
];
}You can now enable the Bezel service. This snippet will:
- install the Bezel package on your system;
- create and enable the Bezel service for all users;
- configure udev rules.
NOTE: you'll still have to add yourself to the
inputanduinputgroups
{ ... }: {
services.bezel.enable = true;
}If you prefer to enable Bezel per-user instead, you can do so using Home Manager.
{ inputs, ... }: {
imports = [
inputs.bezel.homeManagerModules.default
];
services.bezel.enable = true;
}NOTE: If you use the Home Manager module, you'll have to enable uinput separately in your NixOS config, as Home Manager doesn't have access to them:
{ ... }: {
hardware.uinput.enable = true;
}Add yourself to the input group (required on all distros):
sudo usermod -aG input $USER
# reboot your computer after thisNixOS Users: Add "input" and "uinput" to your users.users.<name>.extraGroups instead of using usermod.
If you still get Permission denied (os error 13) after rebooting, you may need custom udev rules for your physical and virtual trackpads. Create /etc/udev/rules.d/99-bezel.rules:
SUBSYSTEM=="input", KERNEL=="event*", ENV{ID_INPUT_TOUCHPAD}=="1", GROUP="input", MODE="0640"
KERNEL=="uinput", MODE="0660", GROUP="input", OPTIONS+="static_node=uinput"
Then reload udev rules with sudo udevadm control --reload-rules && sudo udevadm trigger.
NixOS Users: set either services.bezel.enable = true or hardware.uinput.enable = true
Bezel looks for its configuration at ~/.config/bezel/config.toml.
To define a gesture, specify the zone and direction, and the command to run:
[gestures.top.left]
action = "command"
cmd = "hyprctl dispatch workspace e-1"(See config.toml.example in this repo for a complete template).
To configure OSD labels, add the following:
[osd]
enabled = true
backend = "notify-send" # Valid options: "notify-send", "swayosd", "pipe"
canonical_hints = false # Set to true only if using mako or notify-osdNixOS Users: After importing the Home Manager module you can also customize Bezel using the services.bezel.config option. See config.nix.example for a complete template.
Warning
If you used the NixOS/HM module or install.sh script, Bezel is already running as a systemd service! Do not add these autostart commands, or you will run two instances simultaneously and they will crash.
Start Bezel when your Wayland compositor starts. Void Linux / non-systemd users should use this method instead of a background service. If bezel is not in your system $PATH, use the absolute path ~/.local/bin/bezel (or ~/.cargo/bin/bezel if built with cargo).
For Hyprland (~/.config/hypr/hyprland.conf):
exec-once = ~/.local/bin/bezelFor Sway (~/.config/sway/config):
exec ~/.local/bin/bezelFor Niri (~/.config/niri/config.kdl):
spawn-at-startup "~/.local/bin/bezel"Bezel includes a web-based visualizer that shows a graphical representation of your trackpad and animates when you perform gestures. It's useful for testing, debugging, or recording demos.
To use the visualizer:
- Update your
~/.config/bezel/config.tomlto use thepipeOSD backend:[osd] enabled = true backend = "pipe"
- Restart Bezel (
systemctl --user restart bezel.serviceor restart manually). - Start the visualization server from the root of this repository:
python3 viz/server.py
- Open
http://localhost:8080in your web browser. When you perform gestures, the server will read them from the pipe (/tmp/bezel-osd) and broadcast them to the webpage in real-time.
If OSD notifications (notify-send) fail or don't show up when Bezel is run as a systemd service, your compositor might not be exporting the D-Bus environment properly. You can check the logs to see if notify-send is exiting with an error.
To fix this, add the following to your compositor's startup config to import the session variables:
Hyprland:
exec-once = systemctl --user import-environment WAYLAND_DISPLAY XDG_CURRENT_DESKTOP DBUS_SESSION_BUS_ADDRESSSway:
exec systemctl --user import-environment WAYLAND_DISPLAY SWAYSOCK DBUS_SESSION_BUS_ADDRESS(Niri does this automatically).
To enable more detailed logging, you can set the BEZEL_LOG environment variable. Valid log levels are error, warn, info, debug, and trace. For example:
BEZEL_LOG=debug bezelIf you are running Bezel as a systemd service, you can run systemctl --user edit bezel.service and add the following to the override file:
[Service]
Environment="BEZEL_LOG=debug"Then restart the service.
If your trackpad stops responding, restart the service:
systemctl --user restart bezel.service