SWHKD (Simple Wayland HotKey Daemon)

repository·main·Indexed 21 days ago

https://github.com/waycrate/swhkd

A display protocol-independent hotkey daemon written in Rust, designed as a drop-in replacement for sxhkd. It supports Wayland, Xorg, and TTY using a secure server-client architecture consisting of a privileged daemon (swhkd) and a non-privileged server (swhks). Features include support for custom modes, keybindings with modifiers, and integration with systemd and OpenRC.

Tokens
3.1K
Snippets
14
Records
25
Agent score
74%

What's inside swhkd

  1. Understand SWHKD environment variable handling

    main

    SWHKD emulates the environment variables of your default shell. This is achieved through the swhks (server) binary, which runs in the background and tracks environment variables.

    When a hotkey is triggered, the command is executed via SHELL -c 'command'. This ensures that the environment is sourced from your default shell.

    To use a custom set of environment variables, you should either:

    1. Set/export them in your default shell.
    2. Export them in your current shell instance before running the swhks binary.
  2. How SWHKD security works (Server-Client Model)

    main

    SWHKD implements a security-focused server-client model to separate privileges:

    • The Daemon (swhkd): A privileged process responsible for listening to low-level key events and executing shell commands. To prevent arbitrary code execution, it only runs commands that have been explicitly parsed from the configuration file.
    • The Server (swhks): A non-privileged process responsible for tracking environment variables and passing them to the daemon.

    This separation ensures that even if the environment is manipulated, the daemon only executes the specific commands defined in your swhkdrc.

  3. Autostart swhkd with OpenRC

    main

    To configure OpenRC to automatically start the swhkd daemon, follow these steps:

    1. Ensure the swhkd binary is executable: chmod +x swhkd.
    2. Copy the swhkd init script into /etc/init.d/.
    3. Add the service to the OpenRC runlevel: sudo rc-update add swhkd.
    4. Ensure the swhks client is executed upon user login by adding it to your .xinitrc file or your session setup script.
    chmod +x swhkd
    cp swhkd /etc/init.d/
    sudo rc-update add swhkd
    # Add swhks to your .xinitrc or setup script
  4. Autostart SWHKD

    main

    To ensure swhkd starts automatically when you log in, you can use one of two methods:

    1. Window Manager Config: Add the running commands (swhks & swhkd) directly to your window manager's startup configuration file.
    2. Init System Service: Enable the provided service files for your init system. Currently, support is available for:
      • systemd
      • OpenRC
      • (Runit support is planned)
  5. Autostart swhkd using systemd

    main

    To have systemd automatically manage and start swhkd via a user service, follow these steps:

    1. Prepare your script: Copy hotkeys.sh to a directory of your choice.
    2. Make the script executable: Run chmod +x hotkeys.sh.
    3. Install the service: Copy hotkeys.service into your $XDG_CONFIG_DIRS/systemd/user directory.
    4. Configure the service: Open hotkeys.service in a text editor, locate line 7, uncomment it, and update the path to point to your hotkeys.sh script.
    5. Enable the service: Run systemctl --user enable hotkeys.service in your terminal to ensure it starts on login.
    # 1. Prepare script
    mv hotkeys.sh /path/to/your/dir/
    chmod +x /path/to/your/dir/hotkeys.sh
    
    # 2. Install service
    mv hotkeys.service $XDG_CONFIG_DIRS/systemd/user/
    
    # 3. Enable service
    systemctl --user enable hotkeys.service
  6. Dependencies for swhkd

    main

    Ensure the following dependencies are met before building or running swhkd.

    Runtime Dependencies

    • uinput kernel module
    • evdev kernel module

    Compile-time Dependencies

    • git
    • scdoc (optional: used to generate man-pages if present)
    • make
    • libudev (on Debian, use libudev-dev)
    • rustup
  7. Build and install swhkd from source

    main

    To build swhkd from source, clone the repository, navigate to the swhkd directory, and use make to compile and install.

    Note on Installation Path: By default, swhkd and swhks install to /usr/local/bin/. You can change this by setting the DESTDIR variable during the make install step.

    Note on RFKILL: If the daemon causes issues with wifi due to rfkill, you can disable rfkill support during the build process by setting NO_RFKILL_SW_SUPPORT=1.

    git clone https://github.com/waycrate/swhkd
    cd swhkd
    make setup
    make clean
    make
    sudo make install
    
    # To install to a specific directory:
    sudo make DESTDIR="subdir" install
    
    # To build without rfkill support:
    make NO_RFKILL_SW_SUPPORT=1
  8. Run SWHKD using the server-client model

    main

    SWHKD uses a two-part system: swhks (the non-privileged server) and swhkd (the privileged daemon). To run the daemon with the necessary privileges, you can either use doas or sudo to start both components, or set the swhkd binary as a setuid binary.

    Option 1: Using sudo/doas

    Run the server in the background and the daemon with elevated privileges:

    ./swhks && doas ./swhkd

    To run swhkd without typing sudo every time, set the ownership and setuid bit:

    sudo chown root:root swhkd
    sudo chmod u+s swhkd

    Then start them normally:

    swhks &
    swhkd
  9. Configure SWHKD hotkeys and modes

    main

    SWHKD uses a configuration structure composed of Modes, Hotkeys, and KeyBindings.

    • Modes: A collection of hotkeys and unbinds. The default mode is named "normal". Modes can have specific options like swallow and oneoff.
    • Hotkeys: Maps a KeyBinding to a specific shell command. Hotkeys can also include mode_instructions to change the daemon's state (e.g., switching modes).
    • KeyBindings: Defines the physical input, consisting of a keysym (the key pressed) and a set of modifiers.
    • Unbinds: A list of KeyBindings within a mode that are explicitly disabled.
  10. KeyBinding Attributes: send and on_release

    main

    Keybindings can be modified with specific attributes that change how the key event is handled:

    • send: When enabled, the key event is passed through to the system/application.
    • on_release: When enabled, the associated command or action is triggered when the key is released rather than when it is pressed.
  11. Configure SWHKD

    main

    SWHKD uses a configuration syntax inspired by sxhkd, making it a drop-in replacement for existing sxhkd setups.

    Configuration File Locations:

    1. ~/.config/swhkd/swhkdrc (Default)
    2. /etc/swhkd/swhkdrc (Fallback)

    Syntax & Keys:

    • For supported key and modifier names, refer to man 5 swhkd-keys.
    • For general syntax details, refer to the sxhkd man pages.

    Vim Integration: You can use the swhkd-vim plugin for syntax highlighting. In vim-plug, add:

    Plug 'waycrate/swhkd-vim'