Skip to content

maurges/wzmach

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

55 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Wzmach

Wzmach is a gesture engine for Linux, compatible with both Wayland and X11. It allows you to map keyboard actions to different touchpad figures, such as multi-finger swipes, pinches and shears.

Pronounciation: [vzmax]

Installation

If you don't have a rust toolchain, you can grab a statically-linked binary release in the releases page. You can put that file anywhere in your PATH, for example into ~/.local/bin.

Important: for wzmach to work you need to give it permission to observe and emit input events. Do it with these commands:

cd ~/.local/bin # or the other place where you put the file
sudo chown "$USER:input" wzmach
sudo chmod g+s wzmach
# warning: cp does not preserve permissions, so don't copy it after the modifications

After that you can verify that the permissions are granted by using stat:

stat wzmach
# should produce a line like:
# Access: (2754/-rwxr-sr--)  Uid: ( 1000/    USERNAME)   Gid: (  322/   input)

And verify that your system respects these permissions by running:

RUST_LOG=debug wzmach debug-events
# try to perform multi-finger gestures and see a lot of output. If the output is empty, something is broken!

Installation with cargo

Same as the above, but you can grab the source code and build it with

cargo build --release

This requires the following libraries to be present as development versions:

libdbus libinput libudev
# On opensuse they are called:
dbus-1-devel libinput-devel libudev1

You can then install with cargo install and grant the permissions by hand, or use

make install-local

which executes the above commands for you.

If you instead want a multi-user install, you can run

sudo make install

Installation with nix

Help wanted. I just found out you can't do setgid for nix derivations, but there exist the so-called security wrappers.

Other than that, you can build this package with nix-build

Autostart

If you want wzmach to start with your desktop session, just put the file wzmach.desktop to ~/.config/autostart/. Or if you're already installing with make, you can run

make autostart

Caution: if you're using, KDE it may restore wzmach with the rest of your session by itself, so upon restarts you may end up with two and then more instances of wzmach running. You can fix that by removing wzmach from session restoring in System Settings -> Startup and Shutdown -> Desktop Session -> Don't restore these applications

Uninstallation

If you did installation by hand, you can simply remove all the files you copied:

rm ~/.local/bin/wzmach ~/.config/wzmach/config.ron

If you did a multi-user install via Makefile, you can remove it with make as well:

sudo make uninstall

This will not remove the configs the users created for themselves.

Configuration

Wzmach reads configuration from $XDG_CONFIG_HOME/wzmach/config.ron, which on your system is probably at ~/.config/wzmach/config.ron. You can put the default config there, which provides tab and desktop movement in the style of the old libinput-gestures.

You can then edit that config file to add or replace your gestures. After editing this file you need to restart wzmach.

The default config provides description of top-level fields. Below I describe the available gestures and actions.

UinputAction

Send keyboard events when a gesture is executed. First, it presses all the modifier keys in the order they appear. Then, it clicks (presses and depresses) all the sequence keys one after another. After that, all modifier keys get depressed in the reverse order.

// Example: start omni-completion in vim
UinputAction (

    // These keys are pressed for all the duration of the action
    modifiers: ["RightControl"],

    // There keys are pressed one at a time
    sequence: ["X", "O"],

)

ShellCommandAction

Run a command in the sh shell. All wildcards and special symbols get interpreted like the shell always does.

// Example: toggle a scroll lock LED (works in X11 only)
CommandAction (
    command: r#"
        on=$(xset -q | grep 'Scroll Lock:' | cut -d ":" -f 7)
        echo $on
        if [ $on == "off" ]; then
           xset led named "Scroll Lock"
        else
           xset -led named "Scroll Lock"
        fi
    "#,
),

The example above features a raw string literal. It's delimited by r###" and "### with any number of # symbols, and any symbol can appear inside this string. You can use raw string literals anywhere a string is expected in config, but it's most useful with this and the next action.

CommandAction

Like ShellCommandAction, but skip the shell and invoke the command literally. The difference between this and that is like a difference between system and execv.

// Example: unclutter desktop in KDE
CommandAction (
    // Path can be absolute (/usr/bin/qdbus-qt5) or just a command name. In
    // the second case it's looked up in $PATH
    path: "qdbus-qt5",
    args: [
        "org.kde.KWin",
        "/KWin",
        "unclutterDesktop",
    ],
    // Actually this example doesn't work because of
    // https://bugs.freedesktop.org/show_bug.cgi?id=52202
),

Note that you can use this instead of the previous action. In fact, this is what you should do if you want your command to run in bash or zsh instead of sh.

CommandAction (
    path: "/usr/bin/env",
    args: [
        "bash",
        "-c",
        r##" your command goes here "##,
    ],
),

Swipe

Swipe is moving all of your fingers together in one direction.

Example configuration:

(
    // What triggers the action
    trigger: Swipe (

        // Amount of fingers, from 1 to infinity in theory, and from 3 to
        // 4 or 5 in practice
        fingers: 3,

        // Direction of the swipe: Up, Down, Left or Right
        direction: Up,

        // Can this gesture be repeated multiple times without lifting the
        // fingers? true or false
        repeated: false,

    ),

    // The action to execute upon trigger. Use UinputAction, CommandAction
    // or ShellCommandAction here
    action: UinputAction (
        modifiers: ["RightControl"],
        sequence: ["T"],
    )
),

Shear

Shear is when you rest your digits and move your thumb; or when you move your digits and thumb in different directions. It is very easy to confuse vertical shears and pinches, so you probably don't want to create triggers for both.

Example:

(
    trigger: Shear (

        // Amount of fingers, from 2 to infinity in theory, and from 2 to
        // 4 or 5 in practice. 3 fingers means two digits + 1 thumb
        fingers: 4,

        // Direction of your thumb to move. Up, Down, Left or Right
        direction: Left,

        // Can this gesture be repeated multiple times without lifting the
        // fingers? true or false
        // In practice I run out of thumb before I can trigger it twice.
        repeated: false,

    ),
    action: UinputAction (
        modifiers: ["LeftAlt"],
        sequence: ["Tab"],
    )
),

Pinch

Pinch is when you move your thumb towards your digits, or away from them, as if you want to pinch the surface of your touchpad. You may also know this gesture as "zoom the picture on your phone".

Example:

(
    trigger: Pinch (

        // Amount of fingers, from 2 to infinity in theory, and from 2 to
        // 4 or 5 in practice. 3 fingers means two digits + 1 thumb
        fingers: 2,

        // Direction of the pinch in terms of zooming the picture: In or Out
        direction: In,

        // Can this gesture be repeated multiple times without lifting the
        // fingers? true or false
        repeated: false,

    ),
    action: UinputAction (
        modifiers: ["RightControl"],
        sequence: ["Equal"],
    )
),

Rotate

Rotate is when you rotate your fingers in one direction around a "center of mass" of all your fingers; like rotating a map on your phone. It is extremely easy to confuse shears and rotations, so you probably don't want to create triggers for both.

Example:

(
    trigger: Rotate (

        // Amount of fingers, from 2 to infinity in theory, and from 2 to
        // 4 or 5 in practice. 3 fingers means two digits + 1 thumb
        fingers: 2,

        // Direction of the fingers' rotation: Clockwise or Anticlockwise
        direction: Anticlockwise,

        // Can this gesture be repeated multiple times without lifting the
        // fingers? true or false
        repeated: true,

    ),
    action: UinputAction (
        modifiers: ["RightControl"],
        sequence: ["PageUp"],
    )
)

Hold

Holding several digits on touchpad without movement. In practice it works like shit, both because of libinput weirdness and because a proper implementation is way harder.

Example:

(
    trigger: Hold (

        // Amount of fingers, from 2 to infinity in theory, and from 2 to
        // 4 or 5 in practice.
        fingers: 4,

    ),
    action: UinputAction (
        modifiers: ["RightControl", "RightAlt"],
        sequence: ["Esc"],
    )
),

FAQ

Does wzmach work on wayland?

Yes! The goal of developing wzmach was for me to finally migrate to wayland. This is also the reason I still haven't implemented window-local gestures, as it's untrivial and DE-dependent without x-things.

Does wzmach work on X11?

Yes! Wzmach minimally relies only on libinput and uinput which is indenedent of wayland/X11. So unless you are on a linux version with synaptics and no virtual devices, it will work.

Can I use 2 finger swipes, for example to emulate MacOS's browser gestures?

Not presently, since libinput overrides those with scrolling event. In the future I want to give the ability to interpret scrolling events as gestures.

What are the differences from touchegg?

  1. Wzmach works on wayland
  2. Wzmach has a different trigger mechanism, more similar to that of BetterTouchTool for mac: gestures are executed immediately after the threshold has passed, and you can execute multiple gestures without lifting your fingers
  3. Touchegg has cool animations, and for wzmach they are not even planned
  4. Touchegg has a GUI for configuration, and for wzmach it is only in plans
  5. Touchegg has advanced actions like directly switching your desktop. This relies on X11, and so is not possible for wzmach

What is this configuration language? Did you make it up yourself?

It's called RON and no, although the idea for it lies on the surface.

A line for vim whitespace detection

vim: ts=4 sw=4 sts=4