jersou / mouse-actions

mouse-actions execute some command from mouse events such as clicks/wheel on the side/corners of the screen, or drawing shapes. It's a mix between Easystroke and Compiz edge commands.
MIT License
176 stars 7 forks source link
binding corner easystroke evdev gesture mouse rdev rust tauri

Mouse actions

mouse_actions_logo.svg Build

mouse_actions allows to execute some commands from mouse events such as:

It's a mix between Easystroke and Compiz edge commands.

For instance, you can configure:

mouse_actions_logo.gif

The GUI to configure the application :

Mouse Action Configuration Editor

Features

Bind command execution with mouse button/wheel events (this conditions bellow are optional):

Project status

⚠️ Alpha version ⚠️

My feedback on Linux/X11 : after 10 month of daily use (since 15/05/2022) and 300'000 triggers, it's works well and X11 has not crashed (Unlike Easystroke which made X11 crash every day before on my laptop). With my usage, mouse_actions triggers commands about once/twice per minute, and half of which by shape bindings.

Known bugs

→ a fix (2023-07-07) disable the detection of new devices from rdev → no crash but new devices may not be usable with MA without restarting it

Install / run

Download the release, the 2 release binaries mouse-actions and mouse-actions-gui are standalone (but use the same configuration), the avantage of using GUI less version is the RAM usage : 5.6 Mo vs 34 Mo.

The gui unbundled standalone binary need this packages :

The AppImage and deb releases includes these dependencies.

Release types

Build

Requirement :

To use the main feature "grab event", you need to have the read&write permission on /dev/input/event*. Check the group of /dev/input/event* files :

ls -al /dev/input/event*
# > crw-rw---- 1 root input /dev/input/event5
#                     ^^^^^

You need to add the current user to this group, usually input or plugdev :

sudo usermod -a -G plugdev $USER
# or
sudo usermod -a -G input $USER

Furthermore, you must have the read&write permission on /dev/uinput, you can check with:

getfacl /dev/uinput
# ...
# user:<the current user>:rw-
# ...

If this permission is not available on the user, to add it temporary : sudo setfacl -m u:$USER:rw /dev/uinput or persistent :

sudo tee /etc/udev/rules.d/80-mouse-actions.rules <<<'KERNEL=="uinput", SUBSYSTEM=="misc", TAG+="uaccess", OPTIONS+="static_node=uinput"'

You need to restart your desktop session to apply these changes.

To check the user groups and the ACL after the session restart or the reboot:

$ groups
... input ...
$ getfacl /dev/uinput
# ...
# user:<the current user>:rw-
# ...

⚠️ The changes introduced by this chapter may cause security problems: an application launched with your user can listen to your input events ⚠️

Platform compatibility

I only tested it on Linux + X11 and Linux + Wayland, but it should work on Mac, Windows.

The grab feature from rdev give an inaccurate mouse position, so Mouse_actions used the listen feature from rdev. This function not works on Wayland and the listen feature is used to detect edge of screen click, so this edge actions doesn't works on Wayland (no absolute mouse position).

Wayland

Notes:

Configuration

config editor

Run mouse-actions-gui to edit the configuration.

Configuration file format

The config file default path is ~/.config/mouse-actions.json

Structure

CLI usage

Usage: mouse_actions [OPTIONS] [COMMAND]

Commands:
  show-gui        Default command with mouse-actions-gui, show Mouse Actions Config Editor
  start           Default command with mouse-actions, Start mouse_actions bindings
  trace           Trace events
  record          Start record mode to add some mouse bindings
  list-bindings   List the current config bindings
  grab-one-event  Grab one event, print it and exit
  stop            Stop mouse action
  status          Get mouse action status : exit 0 if running
  show-config     print the json config
  set-config      set the json config from stdin
  help            Print this message or the help of the given subcommand(s)

Options:
  -n, --no-listen                  don't run the listen thread (for Wayland), the edge bindings might not work
  -c, --config-path <CONFIG_PATH>  config path, default : ~/.config/mouse-actions.json
  -v, --version                    print version
  -l, --log-level <LOG_LEVEL>      log level : error, warn, info, debug, trace. [default=info]
  -h, --help                       Print help

LOG : RUST_LOG env var & --log-level option

The project use env_logger to log. The log levels : error, warn, info, debug, trace.

RUST_LOG=debug ./mouse_actions or ./mouse_actions --log-level debug output:

[DEBUG] Binding without shape found : Binding { comment: "Middle click in the top left corner → script: key ² → open Tilda", event: ClickEvent { button: Middle, edges: [Left, Top], event_type: Click}, cmd: ["xdotool", "key", "49"] }
[DEBUG] Process event duration : 39.74µs
[INFO ]      → cmd ["xdotool", "key", "49"]
[DEBUG] ----------------------------------------
[DEBUG] angles: 3.14, 3.14, -3.07, -3.07, -3.04, -3.04, -2.96, ...
[DEBUG] find_candidates_with_shape_with_offset duration : 81.714µs
[DEBUG] shape candidates=
[DEBUG]    75.29 %    0.50 : Draw G shape with the right button → launch gedit (text editor)                        ["gedit"]
[DEBUG]    56.13 %    0.66 : Draw S shape with the right button → Ctrl+S key (save)                                 ["xdotool", "key", "ctrl+s"]
[DEBUG]    25.80 %    0.86 : Draw D shape with the right button → Ctrl+Alt+D key (show the window on all desktops)  ["xdotool", "key", "ctrl+alt+d"]
[DEBUG]    11.70 %    0.94 : Draw H shape with the right button → Ctrl+H key (toggle hide)                          ["xdotool", "key", "ctrl+h"]
[DEBUG] Process event duration : 145.143µs
[INFO ]      → cmd ["gedit"]
[DEBUG] ----------------------------------------
[DEBUG] angles: 0.00, 0.13, 0.13, 0.20, 0.15, 0.15, 0.23, 0.23, ... 
[DEBUG] find_candidates_with_shape_with_offset duration : 113.35µs
[DEBUG] shape candidates=
[DEBUG]    84.78 %    0.39 : Draw T shape with the right button → launch the terminal                                        ["gnome-terminal"]
[DEBUG]    49.18 %    0.71 : Draw Z shape with the right button → Ctrl+Z key (undo)                                          ["xdotool", "key", "ctrl+z"]
[DEBUG]    18.31 %    0.90 : Draw ↘ (line to the bottom right) shape with the right button → Alt+F8 key (resize the window)  ["xdotool", "key", "alt+F8"]
[DEBUG]    13.46 %    0.93 : Draw n shape with the right button → launch nemo (file explorer)                                ["nemo"]
[DEBUG] Process event duration : 194.956µs
[INFO ]      → cmd ["gnome-terminal"]

→ 3 events :

Exemple : big config

Development

This project use rdev crate that use Evdev to grab mouse Event.

Motivations

The goal of this project is then to have these 2 features without having OS crash (X11 crash).

CCSM screenshot (Compiz Config Setting Manager) : ccsm.png

Easystoke screenshot : easystroke.png

Dev notes :

Shape recognition

Shape recognition : compare angles, get the average of the angles differences :

shape-recognition.svg

The calculated difference is approximately the area between the 2 curves of angles (mod 2𝜋) visible on the right of the above image.

Get the minimum difference by shifting a curve horizontally: try removing the beginning or the end, by +/- 10 % max offset (max 20 try).

upgrade

cargo update
cargo audit
cargo test
cargo build --release

cd config-editor
npm install @tauri-apps/cli@latest @tauri-apps/api@latest

cd src-tauri
cargo update
cargo audit

TODO

High

Medium

Low

Maybe