{"id":20050105,"url":"https://github.com/jersou/mouse-actions","last_synced_at":"2025-04-04T20:08:18.040Z","repository":{"id":74655545,"uuid":"495002721","full_name":"jersou/mouse-actions","owner":"jersou","description":"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.","archived":false,"fork":false,"pushed_at":"2025-01-24T22:53:44.000Z","size":2130,"stargazers_count":202,"open_issues_count":33,"forks_count":9,"subscribers_count":8,"default_branch":"main","last_synced_at":"2025-03-28T19:07:40.853Z","etag":null,"topics":["binding","corner","easystroke","evdev","gesture","mouse","rdev","rust","tauri"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jersou.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-05-22T08:33:22.000Z","updated_at":"2025-03-27T03:47:20.000Z","dependencies_parsed_at":"2024-05-02T11:05:29.479Z","dependency_job_id":"5218b8c3-2cd6-4e7c-a621-2ad9318723f3","html_url":"https://github.com/jersou/mouse-actions","commit_stats":null,"previous_names":[],"tags_count":10,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jersou%2Fmouse-actions","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jersou%2Fmouse-actions/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jersou%2Fmouse-actions/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jersou%2Fmouse-actions/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jersou","download_url":"https://codeload.github.com/jersou/mouse-actions/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247242678,"owners_count":20907134,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["binding","corner","easystroke","evdev","gesture","mouse","rdev","rust","tauri"],"created_at":"2024-11-13T11:54:09.071Z","updated_at":"2025-04-04T20:08:18.016Z","avatar_url":"https://github.com/jersou.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Mouse actions\n\n![mouse_actions_logo.svg](mouse_actions_logo.svg)\n[![Build](https://github.com/jersou/mouse-actions/actions/workflows/rust.yml/badge.svg)](https://github.com/jersou/mouse-actions/actions)\n\nmouse_actions allows to execute some commands from mouse events such as:\n\n* clicks / wheel on the side / corners of the screen,\n* or drawing shapes.\n\nIt's a mix between [Easystroke](https://github.com/thjaeger/easystroke)\nand [Compiz edge\ncommands](http://wiki.compiz.org/CCSM#Mouse_Buttons).\n\nFor instance, you can configure:\n\n* a click in the top left corner of the screen to go to the first desktop,\n* a middle click on the top side of the screen to play/pause the media,\n* scroll from the left side to increase/decrease the brightness of the\n  screen,\n* scroll from the top-left corner to increase/decrease the volume,\n* draw a `T` with the mouse right button pressed to open a terminal,\n* draw a `G` with the mouse right button pressed to open a text editor (gedit),\n\n![mouse_actions_logo.gif](mouse_actions_logo.gif)\n\nThe GUI to configure the application :\n\n![Mouse Action Configuration Editor](config-editor/mace.png)\n\n## Features\n\nBind command execution with mouse button/wheel events (this conditions bellow\nare optional):\n\n* Shape drawing with the mouse (like Easystroke)\n* Press/release only or click (don't propagate the press \u0026 release event)\n* With some modifiers : shift/Ctrl/Alt...\n* With screen edge : Top/Left...\n* Auto reload config on changes\n* Very low resource usage\n    * Fast shape recognition : ~200µs (0.0002 sec) for a config with 30 shapes\n    * Fast event without shape processing : ~30µs (0.00003 sec)\n    * CPU : ~7 sec CPU usage per hour (~0.2%)\n    * RAM : 5.6 Mo (GUI less version)\n* Works under Wayland but with limitations, see the \"Platform compatibility\"\n  section below.\n\n## Project status\n\n**⚠️ Alpha version ⚠️**\n\nMy feedback on Linux/X11 : after 10 month of daily use (since 15/05/2022) and\n300'000 triggers, it's works well and X11 has not crashed (Unlike Easystroke\nwhich made X11 crash every day before on my laptop).\nWith my usage, mouse_actions triggers commands about once/twice per minute, and\nhalf of which by shape bindings.\n\n## Known bugs\n\n* when a device (like mouse or bluetooth earphone) is added, the mouse/keyboard\n  modifier are locked : if Ctrl is pressed during this plug, Ctrl keep pressed.\n  A workaround for me is to switch : Ctrl+Alt+F1 \u0026 Ctrl+Alt+F7.\n* when a device (like mouse or bluetooth earphone ) is added, the cursor freeze\n  while 2 seconds or the mouse_actions program may crash.\n\n**→ a fix (2023-07-07) disable the detection of new devices from rdev → no\ncrash but new devices may not be usable with MA without restarting it**\n\n* On PC suspend, the mouse_actions program may crash\n* On wayland, the gesture button event is not propagated if there are no\n  detected gesture #8.\n* Under Linux with Nvidia gpu, the GUI window is blank #38, [it's an open bug\n  of Tauri](https://github.com/tauri-apps/tauri/issues/9304) but there is a\n  workaround : set the env var `WEBKIT_DISABLE_DMABUF_RENDERER=1`\n\n## Install / run\n\n[Download the release](https://github.com/jersou/mouse-actions/releases), the 2\nrelease binaries `mouse-actions` and `mouse-actions-gui` are standalone (but use\nthe same configuration), the avantage of using GUI less version is the RAM\nusage : 5.6 Mo vs 34 Mo.\n\nThe gui unbundled standalone binary need this packages :\n\n* Debian/Ubuntu : libwebkit2gtk-4.0-37, libgtk-3-0\n* Arch : webkit2gtk, gtk3\n* Fedora : webkit2gtk3, gtk3\n\nThe AppImage and deb releases includes these dependencies.\n\n### Release types\n\n* mouse-actions-gui-vX.X.X.tar.gz (2 MB) : GUI version standalone binary\n* mouse-actions-gui_X.X.X_amd64.AppImage (69 MB) : GUI version AppImage,\n  includes webkit2gtk \u0026 gtk3\n* mouse-actions-gui_X.X.X_amd64.deb (2.5 MB) : GUI deb package, includes\n  webkit2gtk \u0026 gtk3 ref\n* mouse-actions-vX.X.X.tar.gz (1 MB) : GUI less version standalone binary\n\n### Build\n\n* GUI less version : `cargo build --release`\n* GUI version : `cd config-editor \u0026\u0026 npm i \u0026\u0026 npm run tauri-build`\n\n### Requirement :\n\nTo use the main feature \"grab event\", you need to have the read\u0026write permission\non `/dev/input/event*`. Check the group of `/dev/input/event*` files :\n\n```bash\nls -al /dev/input/event*\n# \u003e crw-rw---- 1 root input /dev/input/event5\n#                     ^^^^^\n```\n\nYou need to add the current user to this group, usually `input` or `plugdev` :\n\n```bash\nsudo usermod -a -G plugdev $USER\n# or\nsudo usermod -a -G input $USER\n```\n\nFurthermore, you must have the read\u0026write permission on `/dev/uinput`, you can\ncheck with:\n\n```bash\ngetfacl /dev/uinput\n# ...\n# user:\u003cthe current user\u003e:rw-\n# ...\n```\n\nIf this permission is not available on the user, to add it\ntemporary : `sudo setfacl -m u:$USER:rw /dev/uinput` or persistent :\n\n```bash\nsudo tee /etc/udev/rules.d/80-mouse-actions.rules \u003c\u003c\u003c'KERNEL==\"uinput\", SUBSYSTEM==\"misc\", TAG+=\"uaccess\", OPTIONS+=\"static_node=uinput\"'\n```\n\nYou need to restart your desktop session to apply these changes.\n\nTo check the user groups and the ACL after the session restart or the reboot:\n\n```bash\n$ groups\n... input ...\n$ getfacl /dev/uinput\n# ...\n# user:\u003cthe current user\u003e:rw-\n# ...\n```\n\n**⚠️ The changes introduced by this chapter may cause security problems:\nan application launched with your user can listen to your input events ⚠️**\n\n### Platform compatibility\n\nI only tested it on Linux + X11 and Linux + Wayland, but it should work on Mac,\nWindows.\n\nThe `grab` feature from rdev give an inaccurate mouse position, so Mouse_actions\nused the `listen` feature from rdev. This function not works on Wayland and the\nlisten feature is used to detect edge of screen click, so this edge actions\ndoesn't works on Wayland (no absolute mouse position).\n\n#### Wayland\n\nNotes:\n\n* Edge screen event doesn't work with Wayland.\n* but the mouse shape actions works !\n* #8 `Gesture button is 'stolen' on Wayland`, this bug should be fixed in the\n  future\n* xdotool doesn't work on Wayland, use ydotool or other alternatives to simulate\n  keyboard event.\n\n## Configuration\n\n### config editor\n\nRun `mouse-actions-gui` to edit the configuration.\n\n### Configuration file format\n\nThe config file default path is `~/.config/mouse-actions.json`\n\n#### Structure\n\n* `shape_button`: the mouse button to use to draw shapes :\n  `Left` | `Right` | `Middle` | `Side` | `Extra` | `Forward` | `Back`\n  | `Task` | `Trigger` | `Thumb` | `Thumb2` | `WheelUp` | `WheelDown`\n  | `Unknown` | `None`\n\n* `bindings` : array of binding :\n    * `cmd_str` : command line to exec\n    * `event`: object :\n        * `button`: `Left` | `Right` | `Middle` | `Side` | `Extra` | `Forward`\n          | `Back`\n          | `Task` | `Trigger` | `Thumb` | `Thumb2` | `WheelUp` | `WheelDown`\n          | `Unknown` | `None`\n        * `edges`: array of : `Top`,`Right`,`Bottom`,`Left`,\n        * `event_type`: `Press` | `Release`| `Click`\n        * `modifiers`: array of :  `ShiftLeft`, `ShiftRight`, `ControlLeft`,\n          `ControlRight`, `MetaLeft`, `Alt`, `AltGr`\n        * `shapes_xy`: the shapes, array of arrays of coordinates. The best\n          shape match will be used.\n\n## CLI usage\n\n```\nUsage: mouse_actions [OPTIONS] [COMMAND]\n\nCommands:\n  show-gui        Default command with mouse-actions-gui, show Mouse Actions Config Editor\n  start           Default command with mouse-actions, Start mouse_actions bindings\n  trace           Trace events\n  record          Start record mode to add some mouse bindings\n  list-bindings   List the current config bindings\n  grab-one-event  Grab one event, print it and exit\n  stop            Stop mouse action\n  status          Get mouse action status : exit 0 if running\n  show-config     print the json config\n  set-config      set the json config from stdin\n  help            Print this message or the help of the given subcommand(s)\n\nOptions:\n  -n, --no-listen                  don't run the listen thread (for Wayland), the edge bindings might not work\n  -c, --config-path \u003cCONFIG_PATH\u003e  config path, default : ~/.config/mouse-actions.json\n  -v, --version                    print version\n  -l, --log-level \u003cLOG_LEVEL\u003e      log level : error, warn, info, debug, trace. [default=info]\n  -h, --help                       Print help\n```\n\n### LOG : RUST_LOG env var \u0026 --log-level option\n\nThe project use [env_logger](https://github.com/rust-cli/env_logger/) to\nlog. The log levels : error, warn, info, debug, trace.\n\n`RUST_LOG=debug ./mouse_actions` or `./mouse_actions --log-level debug` output:\n\n```\n[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\"] }\n[DEBUG] Process event duration : 39.74µs\n[INFO ]      → cmd [\"xdotool\", \"key\", \"49\"]\n[DEBUG] ----------------------------------------\n[DEBUG] angles: 3.14, 3.14, -3.07, -3.07, -3.04, -3.04, -2.96, ...\n[DEBUG] find_candidates_with_shape_with_offset duration : 81.714µs\n[DEBUG] shape candidates=\n[DEBUG]    75.29 %    0.50 : Draw G shape with the right button → launch gedit (text editor)                        [\"gedit\"]\n[DEBUG]    56.13 %    0.66 : Draw S shape with the right button → Ctrl+S key (save)                                 [\"xdotool\", \"key\", \"ctrl+s\"]\n[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\"]\n[DEBUG]    11.70 %    0.94 : Draw H shape with the right button → Ctrl+H key (toggle hide)                          [\"xdotool\", \"key\", \"ctrl+h\"]\n[DEBUG] Process event duration : 145.143µs\n[INFO ]      → cmd [\"gedit\"]\n[DEBUG] ----------------------------------------\n[DEBUG] angles: 0.00, 0.13, 0.13, 0.20, 0.15, 0.15, 0.23, 0.23, ... \n[DEBUG] find_candidates_with_shape_with_offset duration : 113.35µs\n[DEBUG] shape candidates=\n[DEBUG]    84.78 %    0.39 : Draw T shape with the right button → launch the terminal                                        [\"gnome-terminal\"]\n[DEBUG]    49.18 %    0.71 : Draw Z shape with the right button → Ctrl+Z key (undo)                                          [\"xdotool\", \"key\", \"ctrl+z\"]\n[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\"]\n[DEBUG]    13.46 %    0.93 : Draw n shape with the right button → launch nemo (file explorer)                                [\"nemo\"]\n[DEBUG] Process event duration : 194.956µs\n[INFO ]      → cmd [\"gnome-terminal\"]\n```\n\n→ 3 events :\n\n* `Middle click in the top left corner`\n* `Draw G shape with the right button`\n* `Draw T shape with the right button`\n\n## Exemple : big config\n\n* mouse button bindings:\n    * Super+Left click → screenshot script\n    * Side click → script: Alt + Left mouse down\n    * Extra click → script: Alt + Tab\n\n* edges and corners bindings:\n    * Middle click in the top left corner → script: key ² → open Tilda\n    * Middle click in the top right corner → script: lock the screen\n    * Middle click in the top edge → script: play/pause\n    * Right click in the top left corner → script: go to the top left desktop\n    * Right click in the top right corner → script: go to the top right desktop\n    * Right click in the bottom left corner → script: go to the bottom left\n      desktop\n    * Right click in the bottom right corner → script: go to the bottom right\n      desktop\n    * Wheel up in the top left corner → script: increase volume\n    * Wheel up in the top right corner → script: increase volume\n    * Wheel up in the bottom left corner → script: increase volume\n    * Wheel up in the bottom right corner → script: increase volume\n    * Wheel down in the top left corner → script: decrease volume\n    * Wheel down in the top right corner → script: decrease volume\n    * Wheel down in the bottom left corner → script: decrease volume\n    * Wheel down in the bottom right corner → script: decrease volume\n    * Ctrl + Wheel up in the top edge → script: audio next\n    * Ctrl + Wheel up in the top edge → script: audio previous\n    * Wheel up in the left edge → script: increase brightness 1%\n    * Ctrl + Wheel up in the top edge → script: increase brightness 10%\n    * Wheel down in the left edge → script: decrease brightness 1%\n    * Ctrl + Wheel down in the left edge → script: decrease brightness 10%\n    * Right click in the left edge → script: go to desktop on the left\n    * Right click in the top edge → script: go to desktop on the top\n    * Right click in the right edge → script: go to desktop on the right\n    * Right click in the bottom edge → script: go to desktop on the bottom\n\n* Shape biding with the right button :\n    * Draw G shape → launch gedit (text editor)\n    * Draw T shape → launch the terminal\n    * Draw C shape → key Ctrl+C (Copy)\n    * Draw V shape → key Ctrl+V (Paste)\n    * Draw ↑ (vertical line to the top) shape → go to the desktop on the top\n    * Draw ↓ (vertical line to the bottom) shape → go to the desktop on the top\n    * Draw → (horizontal line to the right) shape → go to the desktop on the\n      right\n    * Draw ← (horizontal line to the left) shape → go to the desktop on the left\n    * Draw N shape → open the Note tool\n    * Draw ↗ (line to the top right) shape → F2 key (rename)\n    * Draw ↖ (line to the top left) shape → F2 key (rename)\n    * Draw ↙ (line to the left bottom) shape → Alt+Tab key\n    * Draw n shape → launch nemo (file explorer)\n    * Draw m shape → launch nautilus (file explorer)\n    * Draw ↘ (line to the bottom right) shape → Alt+F8 key (resize the window)\n    * Draw S shape → Ctrl+S key (save)\n    * Draw ∝ (alpha) shape → Ctrl+X key (cut)\n    * Draw ɣ (gamma) shape → Ctrl+X key (cut)\n    * Draw ↵ (bottom then left) shape → Ctrl+X key (cut)\n    * Draw ↶ (reverse n) shape → show/hide hamster time tracker\n    * Draw Z shape → Ctrl+Z key (undo)\n    * Draw F shape → Ctrl+F key (search)\n    * Draw H shape → Ctrl+H key (toggle hide)\n    * Draw D shape → Ctrl+Alt+D key (show the window on all desktops)\n    * Draw B shape → script to remove the window decoration\n    * Draw 2 shape → Shift+F9 key clear draw on screen (Gromit-MPX)\n    * Draw 𝛥 shape (↗↘←) → F9 key toggle draw on screen (Gromit-MPX)\n\n## Development\n\nThis project use [rdev crate](https://crates.io/crates/rdev) that\nuse [Evdev](https://en.wikipedia.org/wiki/Evdev) to grab mouse Event.\n\n### Motivations\n\n* I used [Easystroke](https://github.com/thjaeger/easystroke) a lot but its\n  development stopped in 2014, and it causes my system to crash regularly.\n* Besides, I was also using a lot Compiz screen corner command bindings, and I\n  wanted to have these bindings without necessarily using compiz.\n\nThe goal of this project is then to have these 2 features without having\nOS crash (X11 crash).\n\nCCSM screenshot (Compiz Config Setting Manager) :\n![ccsm.png](ccsm.png)\n\nEasystoke screenshot :\n![easystroke.png](easystroke.png)\n\n### Dev notes :\n\n#### Shape recognition\n\nShape recognition : compare angles, get the average of the angles differences :\n\n![shape-recognition.svg](shape-recognition.svg)\n\nThe calculated difference is approximately the area between the 2 curves of\nangles (mod 2𝜋) visible on the right of the above image.\n\nGet the minimum difference by shifting a curve horizontally: try removing the\nbeginning or the end, by +/- 10 % max offset (max 20 try).\n\n#### upgrade\n\n```bash\ncargo update\ncargo audit\ncargo test\ncargo build --release\n\ncd config-editor\nnpm install @tauri-apps/cli@latest @tauri-apps/api@latest\n\ncd src-tauri\ncargo update\ncargo audit\n```\n\n## TODO\n\n### High\n\n* #8 Gesture button is 'stolen' on Wayland\n* config file for /dev/input/event* in /etc/udev/rules.d/? instead of the\n  usermod if possible, script to create this file, add to the deb package, ...\n\n### Medium\n\n* CI: build the releases https://github.com/tauri-apps/tauri-action\n* change config : if shape → (no need button in binding) or (rm shape_btn :\n  several button for shape event is then possible)\n* cancel shape if no move after few ms (400 ms ?)\n* fix `TODO` and `FIXME`\n* fix rdev\n    * reset the modifiers/button state at root loop restart\n    * fix rdev devices delete/update: the FIXME \"inotify CREATE but not DELETE\n      in grab::inotify_devices()\" in rdev/src/linux/grab.rs:493\n    * pull request/contribute/modify rdev without fork it in this repo (\n      mouse btn add \u0026 fix devices setup/Delete notify)\n* add ARM64 target #6\n\n### Low\n\n* re-enable the new device detection, disabled by the v0.4.4\n* support Windows \u0026 macOS\n* fix exec cmd not found\n  error\n  `Err(Os { code: 2, kind: NotFound, message: \"No such file or directory\" })`\n* create ~/.config if it doesn't exist\n* use https://github.com/hoodie/notify-rust\n* a better Readme\n* improve shape recognition\n* refactor\n    * don't use arrayvec ?\n    * reduce clone() usages\n    * handle errors correctly : remove panic, reduce unwrap\n    * refactor Arc/Mutex usages\n    * refactor/change the pressState usage\n    * dev doc, tests\n* use rdev send() ? → cmd OR sendKeys in bindings (or autopilot-rs) :  trigger\n  keyboard event as action (avoid xdotool usage in\n  cmd) : https://github.com/Narsil/rdev#sending-some-events\n\n### Maybe\n\n* use https://crates.io/crates/deno_task_shell to execute commands ?\n* release a debug version and a gui-less version ?\n* options\n    * dry-run option\n    * min diff shape config option\n    * min score shape config option\n* find a better project name and icon\n* notif/sound/cursor change on action trigger success/failure (\n  configurable) ? https://crates.io/crates/rodio\n* mouse move edge event ?\n* hide/freeze cursor while shape drawing ?\n* Ctrl alias for ControlLeft \u0026 ControlRight, Shift for ShiftLeft \u0026 ShiftRight,\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjersou%2Fmouse-actions","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjersou%2Fmouse-actions","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjersou%2Fmouse-actions/lists"}