Linux desktop automation shortcuts via mouse/trackball+keyboard chording
xmchord =======
xmchord is a productivity tool for Linux desktops, that binds custom actions to chording* events of mouse buttons and key presses: this way, mouse buttons become additional modifier keys.
*Chording: Chording generally means pushing several keys or buttons simultaneously to achieve a result.
xmchord comes with a comprehensive set of shortcut **actions to automate and speed-up user activities** that are common on the Linux desktop.
Table of contents
* Command:help
* Command: debug
* Command: actions
* Argument: --keyboard
* Command: listDevices
* Command: printPreferences
* Command: reset
* Command: version
* Third party dependencies
* Global actions
+ Application launchers
+ Various global actions
* Application specific actions
* Chrome, Chromium and Firefox Web-Browser
+ Advanced browser action: Toggle URL sub string
* Claws Mail
* Gnome Terminal
+ Terminal command snippets
* Gnome Screenshot
* Mattermost Desktop Client
* Thunderbird
+ Advanced global-actions
* Open generic URL
* Archived/inactive actions
- Build from source
- Code Convention
- Contributing
- Bug Reporting and Feature Requests
- Changelog
- Third Party References
- Author and License
- Addendum I: Linux trackball configuration snippets
- Addendum II: Action shell scripting tricks
What does it do?
xmchord listens for events of mouse buttons pressed together with keyboard keys. When observing a chording event, xmchord generates an identifier code for the given combination (and order) of button/key presses. If there is a shell script file named by the current event code within xmchord's actions directory, it is executed.
Usage and arguments
Usage is: sudo xmchord
To ensure read-access to Linux device events, xmchord must be run with root privileges (e.g. viasudo). Action shell scripts that perform user specific tasks, therefor must take care of running on that user's behalf.
Command: help
Running xmchord help or xmchord h, displays a list and explanation of available commands.
Command: debug
Running xmchord debug or xmchord d, activates tracing of event codes. While in debug mode, action shell script files can be added without having to stop and restart xmchord.
In regular mode, xmchord reduces processing time by indexing which actions are available during startup.
Command: actions
Running xmchord actions or xmchord a, lists all recognized action shell scripts, including their inlined description comments (which must be prefixed with #:).
Argument: --keyboard
xmchord by default installs its keyboard watcher upon the 1st keyboard device found (e.g. on laptops the built-in one). This optional argument allows setting a specific keyboard device to be used. xmchord stores this device preference, so once it is set, xmchord continues using that device when restarted later. Running xmchord -k=/path/to/my/keyboard or xmchord --keyboard=/path/to/my/keyboard selects the device at the given path as the keyboard watcher's target. Tip: xmchord's device detection is looking for a matching substring, therefore the device-identifier can also be given w/o a path, e.g: xmchord -k=Logitech.
Command: listDevices
Running xmchord listDevices or xmchord l lists paths of available devices.
Command: printPreferences
Running xmchord printPreferences or xmchord p outputs xmchord's preferences if given, or a respective info if not.
Command: reset
Running xmchord reset or xmchord r unsets xmchord's keyboard device preference.
Command: version
Running xmchord version or xmchord v, tests whether xmchord is available and displays it's version number.
Included shortcut actions
See files under bin/actions
The included shortcut actions are scripted for use with a Kensington Expert Mouse trackball, tested on Linux Mint Cinnamon, but should be compatible or easily adjustable for other devices and Linux distributions and desktop environments.
Third party dependencies
The following third party dependencies must be installed for all included actions to work:
| Application | Description | |-----------------------------------------------------------------|-----------------------------------------------------------------------------------| | aosd-cat of libaosd | Display TEXT, or standard input, on top of display | | feh | Image viewer aimed mostly at console users to simply display images w/o fancy GUI | | sed | Stream editor for filtering and transforming text | | wmctrl | Command line tool to interact with an EWMH/NetWM compatible X Window Manager | | xdotool | Fake keyboard/mouse input, window management, and more | | xsrel | Manipulate the X selection (Clipboard) | | xclip | Interface to X selections ("the clipboard") from the command line. |
Install dependencies that are not included in Linux Mint distribution by default:
bash
sudo apt install aosd-cat feh xclip xdotool xsel -y</code></pre>
Global actions (not application specific)
Symbols are:
◤ ◥ = Top buttons left / right ◣ ◢ = Bottom buttons left / right
Application launchers
These actions launch applications, or bring re-focus their window, if already running (like the behavior on Mac OS).
| Shortcut | Description | |--------------------------------|---------------------------------------------------------------------| | ◤ + G | Summon default email client (like mail key on keyboard) | | ◤ + M | Bring Mattermost desktop client to front, launch if not yet running | | ◤ + O | Bring Orange-player to front, launch if not yet running | | ◤ + W | Summon default web browser (like browser key on keyboard) | | ◣ + C | Launch or bring Chromium to front | | ◣ + D | Launch or bring DataGrip to front | | ◣ + F | Launch or bring Firefox to front | | ◣ + K | Launch or bring Kitematic to front | | ◣ + M | Launch or bring Claws Mail to front | | ◣ + Y | Bring CherryTree to front, launch if not yet running | | ◣ + Esc | Launch or bring System Monitor to front |
Various global actions
| Shortcut | Description | |--------------------------------|--------------------------------------------------------------------------------| | ◤ + ← | Go to workspace left of current (Hit SUPER+SHIFT+Left) | | ◤ + → | Go to workspace left of current (Hit SUPER+SHIFT+Right) | | ◤ + ◣ | Jump to next workspace | | Right Shift + ◤ + ◣ | Jump to previous workspace | | ◣ + ◢ | Touch bottom-right hot-corner (E.g. expose windows) | | ◣ + I | Display public and private IP and wifi MAC address, copy public IP address | | ◣ + L | Toggle keyboard backlight | | ◣ + R | Toggle active window roll-up state | | ◣ + S | Toggle active window "roll-sideways" state | | ◣ + T | Toggle active window always-on-top state | | ◣ + U | Type current UNIX timestamp | | ◣ + V | Toggle active window always-on-visible-workspace state | | ◣ + W | Hit CTRL+W (close window) | | ◣ + Ä | Type large A-umlaut (helpful e.g. on swiss keyboards) | | ◣ + Ö | Type large O-umlaut (helpful e.g. on swiss keyboards) | | ◣ + Ü | Type large U-umlaut (helpful e.g. on swiss keyboards) | | ◣ + 0 | Move active window to workspace 0 | | ◣ + 1 | Move active window to workspace 1 | | ◣ + 2 | Move active window to workspace 2 | | ◣ + 3 | Move active window to workspace 3 | | ◣ + 4 | Move active window to workspace 4 | | ◣ + 8 | Move caret eight times to the right (helpful e.g. to crop git hashes quickly) | | ◣ + ← | Focus previous tab | | ◣ + → | Focus next tab | | ◣ + ↑ | Scroll to top (same as home key) | | ◣ + ↓ | Scroll to bottom (same as end key) | | ◣ + Numpad "-" | Toggle play/pause audio | | ◣ + Numpad 7 | Tile active window to top-left 50% of screen | | ◣ + Numpad 8 | Tile active window to top 50% of screen | | ◣ + Numpad 9 | Tile active window to top-right 50% of screen | | ◣ + Numpad 6 | Tile active window to right 50% of screen | | ◣ + Numpad 3 | Tile active window to bottom-right 50% of screen | | ◣ + Numpad 2 | Tile active window to bottom 50% of screen | | ◣ + Numpad 1 | Tile active window to bottom-left 50% of screen | | ◣ + Numpad 4 | Tile active window to left 50% of screen | | ◣ + Numpad 5 | Maximize active window | | ◣ + ' | Output name of application of focused window (to terminal) | | ◣ + $ | Convert selected text to all upper/lower case | | ◣ + ENTER | Click left mouse button three times (select line) | | ◢ + A | Select all (same as CTRL+A) | | ◢ + C | Copy (same as CTRL+C) | | ◢ + F | Find (same as CTRL+F) | | ◢ + V | Paste (same as CTRL+V) | | ◢ + X | Cut (same as CTRL+X) | | ◢ + Y | Redo (same as CTRL+Y) | | ◢ + Z | Undo (same as CTRL+Z) | | ◢ + Numpad 4 | Move active window to screen left of current | | ◢ + Numpad 6 | Move active window to screen right of current | | ◢ + Numpad Plus | Zoom in (same as CTRL+Plus) | | ◢ + Numpad Minus | Zoom out (same as CTRL+Minus) | | ◢ + ↑ | Increase audio volume | | ◢ + ↓ | Decrease audio volume |
Application specific actions
For these actions to be triggered, a window of the respective application must be focussed when the shortcut is fired.
Chrome, Chromium and Firefox Web-Browser
| Shortcut | Description | |------------------------------|----------------------------------------------| | ◤ + D | Show downloads | | ◤ + R | Reload | | ◤ + L or ◤ + U | Focus URL field | | ◣ + ← | Focus previous tab (browser and DevTools) | | ◣ + → | Focus next tab (browser and DevTools) | | Right-CTRL + ◣ + ← | Focus previous tab, than reload it | | Right-CTRL + ◣ + → | Focus next tab, than reload it | | ◣ + , | Decrement numeric ending of current URL by 1 | | ◣ + . | Increment numeric ending of current URL by 1 | | ◣ + Backspace | Remove trailing segment from current URL | | ◣ + C | Copy trailing segment of current URL | | ◣ + D | Duplicate active tab | | ◣ + H | Toggle HTML "view-source" of current URL | | ◣ + N | Move active tab to new window | | ◣ + RETURN | Browse for selected text in new tab | | ◢ + ← | Go URL backwards | | ◢ + → | Go URL forward | | ◢ + F4 | Close active tab |
Advanced browser action: Toggle URL sub string
| Shortcut | Description | |--------------------------------|-----------------------------| | ◣ + \[-\] | Toggle URL sub string |
When running this action while the current browser URL contains one of two sub strings, it is been replaced by the other and the browser reloaded.
The following environment variables must be set in your /etc/environment:
sudo nano /etc/environment
sh
PATH="/usr/local/sbin:..."
XMCHORDURLSUBSTR_1='http://localhost' XMCHORDURLSUBSTR_2='https://yoururl.com'</code></pre>
For changes to take effect after editing /etc/environment reload it and restart xmchord.
Claws Mail
| Shortcut | Description | |---------------------|----------------------------------------------------------------| | ◣ + F | Open "Search Folder" popup | | ◣ + H | Toggle "Hide read messages", precondition: "thread view" must be deactivated |
Gnome Terminal
| Shortcut | Description | |--------------|----------------------------------------------------------------| | ◤ | Close active tab | | ◣ + F | Open Find popup | | ◣ + Numpad / | Insert 40 empty lines (helpful to separate sections of output) | | ◣ + ← | Focus previous tab | | ◣ + → | Focus next tab | | ◣ + ↑ | Scroll to top | | ◣ + ↓ | Scroll to bottom |
Terminal command snippets
| Shortcut | Description | |----------------------------|---------------------------------------------------------------------------------------------------------| | ◣ + C | Type and execute command to cd into a favorite local path | | ◣ + D | Type scp command to recursively download remote directory | | ◣ + L | Shortcut to wipe a cache directory: Type and execute command to clean a preferred path by executing rm -rf upon it. | | ◣ + S | Type and execute command to connect to preferred SSH host and cd into preferred path | | ◣ + SPACE | Type yes and hit ENTER | | ◣ + U | Type scp command to recursively upload local directory to remote | | ◣ + X | Type exit and hit ENTER |
For the cd, rm -rf, scp and ssh shortcut snippets, the following environment variables must be set in your /etc/environment:
sudo nano /etc/environment
sh
PATH="/usr/local/sbin:..."
XMCHORDCDFAVORITE=/home/john/Projects/myProject
XMCHORDRMFAVORITE=/home/john/Projects/myProject/var/cache
XMCHORDSCPREMOTE=johndoe@yourhost:/var/www XMCHORDSCPLOCAL=/home/john/yourhostvarwww
XMCHORDSSHREMOTE=johndoe@yourhost XMCHORDSSHREMOTENEEDSCONFIRMATION=1 XMCHORDSSHREMOTEPATHINITIAL=/var/www</code></pre>
For changes to take effect, restart xmchord after editing your /etc/environment.
Gnome Screenshot
These actions automate the steps for transferring screenshots made with Gnome Screenshot into other applications. For them to work, the mouse must be hovering Gnome Screenshot's copy to clipboard button when fired.
| Shortcut | Description | |-------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | ◣ + AltGr | Click and hit [Esc] = Copy to clipboard and close Gnome Screenhot popup at once | | ◣ + G | Click, hit [Esc], focus Gimp (if running) and paste image from clipboard as new image | | ◢ + V | View as "sticky note:" Click, hit [Esc], store clipboard to temporary image file and open image file in feh Image Viewer, Set feh window always-on-top and always-on-visible-workspace. |
Mattermost Desktop Client
| Shortcut | Description | |--------------|--------------------------------| | ◣ + M | Open "direct messages" popup | | ◣ + U | Upload files | | ◣ + W | Type ":wave:" | | ◣ + . | Next unread channel | | ◣ + 1 | Type ":+1:" (= thumbs-up icon) |
Thunderbird
| Shortcut | Description | |--------------|-------------------------------| | ◣ + B | Open address book | | ◣ + F | Open "Search Messages" popup |
Advanced global actions
These actions differ from the basic global actions, in that they require some manual configuration, as described here.
Open generic URL
This action adds text from a currently given text-selection to a preset URL, and loads the resulting URL in the web browser (chromium by default).
| Shortcut | Description | |--------------|----------------------------------------------------------------------| | ◣ + O | Open generic URL in browser. Precondition: a text selection is given |
The following environment variable must be set in your /etc/environment:
sudo nano /etc/environment
sh
PATH="/usr/local/sbin:..."
XMCHORDGENERICURL='https://www.your-domain.com/?id=SELECTED_TEXT'</code></pre>
When running this action, `SELECTED_TEXT will be replaced by your text selection.
For changes to take effect after editing
/etc/environment reload it and restart xmchord.
To use a different browser, edit script:
0220022-24.sh
Archived/inactive actions
Some additional actions that aren't active by default can be found within the
actions/inactive directory.
Build from source
cmake CMakeLists.txt; make
Code Convention
The source code of xmchord follows the Google C++ Style Guide, see: https://google.github.io/styleguide/cppguide.html The source code of action shell script files follows the Google Shell Style Guide, see https://google.github.io/styleguide/shell.xml
Contributing
See CONTRIBUTING.md
Bug Reporting and Feature Requests
If you find a bug or have an enhancement request, please file an issue on the github repository.
Changelog
See CHANGELOG.md
Third Party References
Expert Mouse® Trackball is a registered trademark of Kensington Computer Products Group, a division of ACCO Brands
The example action for window arrangement uses splitDesk.sh, based on the original script by Steve Simpson.
Build tools and Continuous Integration
The following third party tools are used for building xmchord with automatic control over code quality and standards:
| Tool or Service | Description | License | | ----------------------------------------------------- | ------------------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------- | | Clang | A C language family frontend for LLVM | Apache License | | Cmake | Family of tools designed to build, test and package software | New BSD License | | Cppcheck | Static analysis tool for C/C++ code | GNU General Public License version 3 | | cpplint | Static code checker for C++ | BSD-3 Clause | | GCC | GCC, the GNU Compiler Collection | GNU General Public License version 3 | | lgtm automated code review | Code analysis platform for finding zero-days and preventing critical vulnerabilities | lgtm Terms of Service | | ShellCheck | ShellCheck, a static analysis tool for shell scripts | GNU General Public License version 3 | | Tavis CI | Test and Deploy Your Code with Confidence | Travis CI Contact & Legal Inquiries |
Thanks a lot!
Author and License
Written by Kay Stenschke. xmchord is licensed under the New BSD License
> Copyright (c), Kay Stenschke > All rights reserved. > > Redistribution and use in source and binary forms, with or without modification, > are permitted provided that the following conditions are met: > > 1. Redistributions of source code must retain the above copyright notice, this > list of conditions and the following disclaimer. > > 2. Redistributions in binary form must reproduce the above copyright notice, > this list of conditions and the following disclaimer in the documentation > and/or other materials provided with the distribution. > > 3. Neither the name of the copyright holder nor the names of its contributors > may be used to endorse or promote products derived from this software without > specific prior written permission. > > THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND > ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED > WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE > DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR > ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES > (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; > LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON > ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT > (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS > SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Addendum I: Linux trackball configuration snippets
Output list of devices:
xinput --list Output mouse buttons mapping: xinput get-button-map <device-ID> Trace mouse button IDs: xev
Set speed and acceleration, buttons mapping and wheel emulation:
<pre><code class="lang-bash">#!/bin/bash
for id in
xinput --list|grep 'Kensington Expert Wireless TB Mouse'|perl -ne 'while (m/id=(\d+)/g){print "$1\n";}'; do # set speed + accelleration xinput set-ptr-feedback $id 0 34 12
# set top/left button to be middle-click xinput set-button-map $id 3 2 1 4 5 6 7 8 9 10 11 12 # left-handed: bottom-right is left-click
# emulate mouse wheel on bottom/left (right-click) button + move xinput set-prop "pointer:Kensington Expert Wireless TB Mouse" "libinput Scroll Method Enabled" 0, 0, 1 # on Kensington Expert Mouse, buttons are: # 0 = no button needed # 2 = top/left # 8 = top/right # 1 = bottom/left # 8 1 = bottom buttons together # 8 2 = bottom right + top/left together
# set bottom button to fire scroll-mode xinput set-prop "pointer:Kensington Expert Wireless TB Mouse" "libinput Button Scrolling Button" 1 # map bottom-left button held to scroll xinput set-prop $id "Evdev Wheel Emulation Timeout" 300 done</code></pre>
Addendum II: Action shell scripting tricks
1. User-specific actions
Problem: xmchord runs as root, but some actions need to be run for a specific logged-in user.
E.g. Cinnamon's D-Bus methods require being launched by a specific user. The following script switches from root to original user, before triggering the desired method:
<pre><code class="lang-bash">#!/bin/bash me=$SUDO_USER sudo -u $me dbus-send --dest=org.Cinnamon --print-reply /org/Cinnamon org.Cinnamon.switchWorkspaceRight</code></pre>
2. Launching applications and switching windows
Shell scripts can detect whether an application is running already and using e.g. wmctrl, bring a respective window onto the active workspace, or launch the application (similar to the behavior on Mac OS).
<pre><code class="lang-bash">#!/bin/bash if pidof -s evolution > /dev/null; then wmctrl -a Evolution else me=$SUDO_USER sudo -u $me nohup evolution > /dev/null & fi</code></pre>
3. Triggering window actions
Using e.g. wmctrl, shell scripts can switch the active window's roll-up and always-on-top state:
<pre><code class="lang-bash">#!/bin/bash wmctrl -b toggle,shaded -r :ACTIVE:</code></pre>
<pre><code class="lang-bash">#!/bin/bash wmctrl -r :ACTIVE: -b toggle,above</code></pre>
4. Application specific shortcut actions
Using e.g. xdotool, shell scripts can detect the currently focused window's application, and vary the triggered function accordingly. Xdotool also allows to trigger key-combinations for various shortcuts:
<pre><code class="lang-bash">#!/bin/bash focusApplication=\
cat /proc/$(xdotool getwindowpid $(xdotool getwindowfocus))/comm`
if [[ "$focusApplication" =~ "gnome-terminal-" ]]; then xdotool key ControlL+PageUp else xdotool key shift+ctrl+Tab fi