Skip to content

Indra55/bezel

Repository files navigation

Bezel

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 Demo


Installation

Bezel is Linux-only (Wayland required).

Prebuilt binary

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.)

From source

cargo install --git https://github.com/indra55/bezel

Arch Linux

Normally 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!

NixOS

You can try out Bezel using this command:

nix run github:indra55/bezel

For 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:

  1. install the Bezel package on your system;
  2. create and enable the Bezel service for all users;
  3. configure udev rules. NOTE: you'll still have to add yourself to the input and uinput groups
{ ... }: {
  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;
}

Setup

Add yourself to the input group (required on all distros):

sudo usermod -aG input $USER
# reboot your computer after this

NixOS 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

Configuration

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-osd

NixOS 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.

Autostart

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/bezel

For Sway (~/.config/sway/config):

exec ~/.local/bin/bezel

For Niri (~/.config/niri/config.kdl):

spawn-at-startup "~/.local/bin/bezel"

Web Visualizer (Demo)

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:

  1. Update your ~/.config/bezel/config.toml to use the pipe OSD backend:
    [osd]
    enabled = true
    backend = "pipe"
  2. Restart Bezel (systemctl --user restart bezel.service or restart manually).
  3. Start the visualization server from the root of this repository:
    python3 viz/server.py
  4. Open http://localhost:8080 in 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.

Troubleshooting

OSD Notifications Not Showing

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_ADDRESS

Sway:

exec systemctl --user import-environment WAYLAND_DISPLAY SWAYSOCK DBUS_SESSION_BUS_ADDRESS

(Niri does this automatically).

Debugging Logs

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 bezel

If 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

About

A lightweight Rust daemon for trackpad gestures on Wayland compositor

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors