Add command line tools for configurations
This commit is contained in:
parent
ffe664c7d8
commit
de3f88c83c
213
README.md
213
README.md
@ -3,10 +3,12 @@
|
|||||||
[](https://github.com/Hikari9/comfortable-swipe/releases)
|
[](https://github.com/Hikari9/comfortable-swipe/releases)
|
||||||
[](https://www.gnu.org/licenses/gpl-3.0)
|
[](https://www.gnu.org/licenses/gpl-3.0)
|
||||||
|
|
||||||
> **_New in Version 1.1.0!_** Added mouse gestures, see [#mouse-gestures-experimental](#mouse-gestures-experimental)
|
|
||||||
|
|
||||||
Comfortable, seamless, and fast 3-finger (and 4-finger) touchpad swipe gestures for Ubuntu 14.04 LTS and beyond. May work for other Linux distros that support `libinput`.
|
Comfortable, seamless, and fast 3-finger (and 4-finger) touchpad swipe gestures for Ubuntu 14.04 LTS and beyond. May work for other Linux distros that support `libinput`.
|
||||||
|
|
||||||
|
> **_New in Version 1.1.0_**: Added mouse gestures, see [#mouse-gestures-experimental](#mouse-gestures-experimental)
|
||||||
|
|
||||||
|
> **_New in Version 1.2.0_**: Autostart now switched ON by default
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
1. Install git and g++
|
1. Install git and g++
|
||||||
@ -18,7 +20,7 @@ Comfortable, seamless, and fast 3-finger (and 4-finger) touchpad swipe gestures
|
|||||||
1. Install libinput-tools and C libraries
|
1. Install libinput-tools and C libraries
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
sudo apt install libinput-tools libconfig-dev libxdo-dev
|
sudo apt install libinput-tools libconfuse-dev libxdo-dev
|
||||||
```
|
```
|
||||||
|
|
||||||
2. Clone this repository
|
2. Clone this repository
|
||||||
@ -39,44 +41,93 @@ Comfortable, seamless, and fast 3-finger (and 4-finger) touchpad swipe gestures
|
|||||||
## How to Run
|
## How to Run
|
||||||
|
|
||||||
1. You'll need some group permissions to read touchpad input data. Run
|
1. You'll need some group permissions to read touchpad input data. Run
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
sudo gpasswd -a $USER $(ls -l /dev/input/event* | awk '{print $4}' | head --line=1)
|
sudo gpasswd -a "$USER" "$(ls -l /dev/input/event* | awk '{print $4}' | head --line=1)"
|
||||||
```
|
|
||||||
2. **_Important_**: After inputing your `sudo` password, log out then log back in
|
|
||||||
3. Run
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
1. **_Important_**: After inputing your `sudo` password, log out then log back in
|
||||||
|
|
||||||
|
1. Run
|
||||||
|
|
||||||
|
```bash
|
||||||
comfortable-swipe start
|
comfortable-swipe start
|
||||||
```
|
```
|
||||||
4. _Optional_: Automatically run on startup
|
|
||||||
```
|
1. (Optional) Automatically run on startup
|
||||||
comfortable-swipe autostart
|
|
||||||
```
|
```bash
|
||||||
5. Check the status of your application by running
|
comfortable-swipe autostart on
|
||||||
```
|
|
||||||
comfortable-swipe status
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## Swipe Configurations
|
1. You can check general program status
|
||||||
|
```basha
|
||||||
|
$> comfortable-swipe status
|
||||||
|
|
||||||
Comfortable swipe makes use of keyboard shortcuts for configurations. Edit by running:
|
autostart is ON
|
||||||
|
comfortable-swipe program is RUNNING
|
||||||
|
```
|
||||||
|
|
||||||
```
|
## List of Commands
|
||||||
gedit $(comfortable-swipe config)
|
|
||||||
|
1. Run / stop the program
|
||||||
|
```
|
||||||
|
comfortable-swipe start
|
||||||
|
comfortable-swipe stop
|
||||||
|
comfortable-swipe restart
|
||||||
|
```
|
||||||
|
|
||||||
|
1. Show help / version
|
||||||
|
```
|
||||||
|
comfortable-swipe --help
|
||||||
|
comfortable-swipe --version
|
||||||
|
```
|
||||||
|
|
||||||
|
1. Show path to configuration file
|
||||||
|
|
||||||
|
```bash
|
||||||
|
comfortable-swipe config
|
||||||
|
```
|
||||||
|
|
||||||
|
1. Toggle autostart
|
||||||
|
|
||||||
|
```bash
|
||||||
|
comfortable-swipe autostart [on|off|toggle|status|path]
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
1. (Advanced) Run program buffer
|
||||||
|
|
||||||
|
```bash
|
||||||
|
comfortable-swipe buffer
|
||||||
|
```
|
||||||
|
|
||||||
|
## Configuring Swipe Gestures
|
||||||
|
|
||||||
|
The default configuration file is located at `~/.config/comfortable-swipe.conf`.
|
||||||
|
Comfortable swipe makes use of keyboard shortcuts to perform swipes through `xdotool`.
|
||||||
|
|
||||||
|
An example:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# File: ~/.config/comfortable-swipe.conf
|
||||||
|
|
||||||
|
left3 = ctrl+alt+Right
|
||||||
|
left4 = ctrl+alt+shift+Right
|
||||||
|
right3 = ctrl+alt+Left
|
||||||
|
right4 = ctrl+alt+shift+Left
|
||||||
|
up3 = ctrl+alt+Down
|
||||||
|
up4 = ctrl+alt+shift+Down
|
||||||
|
down3 = ctrl+alt+Up
|
||||||
|
down4 = ctrl+alt+shift+Up
|
||||||
|
threshold = 0.0
|
||||||
```
|
```
|
||||||
|
|
||||||
| Property | Description | Default Value | Default Behavior |
|
Edit configurations by running:
|
||||||
| --------- | :------------------------------------------: | -------------------- | -------------------------------------------------------------------------------------------------------------------------- |
|
|
||||||
| left3 | 3-finger swipe left | ctrl+alt+Right | switch to right workspace |
|
```
|
||||||
| left4 | 4-finger swipe left | ctrl+alt+shift+Right | move window to right workspace |
|
gedit ~/.config/comfortable-swipe.conf
|
||||||
| right3 | 3-finger swipe right | ctrl+alt+Left | switch to left workspace |
|
```
|
||||||
| right4 | 4-finger swipe right | ctrl+alt+shift+Left | move window to left workspace |
|
|
||||||
| up3 | 3-finger swipe up | ctrl+alt+Down | switch to bottom workspace |
|
|
||||||
| up4 | 4-finger swipe up | ctrl+alt+shift+Down | move window to bottom workspace |
|
|
||||||
| down3 | 3-finger swipe down | ctrl+alt+Up | switch to above workspace |
|
|
||||||
| down4 | 4-finger swipe down | ctrl+alt+shift+Up | move window to above workpace |
|
|
||||||
| threshold | mouse pixels to activate swipe | 0.0 | tweak this if you're having troubles with touchpad sensitivity (higher = less sensitive, values can be as large as 1000.0) |
|
|
||||||
| hold3 | holds a mouse button when 3 fingers are down | (none) | See [Mouse Gestures (Experimental)](#mouse-gestures-experimental) |
|
|
||||||
| hold4 | holds a mouse button when 4 fingers are down | (none) | See [Mouse Gestures (Experimental)](#mouse-gestures-experimental) |
|
|
||||||
|
|
||||||
After making changes, make sure to restart the program:
|
After making changes, make sure to restart the program:
|
||||||
|
|
||||||
@ -84,6 +135,28 @@ After making changes, make sure to restart the program:
|
|||||||
comfortable-swipe restart
|
comfortable-swipe restart
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
> **Note**: For v1.1.0 below, the configuration file is located at
|
||||||
|
> `/usr/local/share/comfortable-swipe/comfortable-swipe.conf`
|
||||||
|
|
||||||
|
> **Note**: You can locate your configuration by running `comfortable-swipe config`
|
||||||
|
|
||||||
|
## Configuration Reference
|
||||||
|
|
||||||
|
| Key | Value | Examples |
|
||||||
|
| --------- | :------------------------------------------: | -------------------- |
|
||||||
|
| left3 | 3-finger swipe left | ctrl+alt+Right |
|
||||||
|
| left4 | 4-finger swipe left | ctrl+alt+shift+Right |
|
||||||
|
| right3 | 3-finger swipe right | ctrl+alt+Left |
|
||||||
|
| right4 | 4-finger swipe right | ctrl+alt+shift+Left |
|
||||||
|
| up3 | 3-finger swipe up | ctrl+alt+Down |
|
||||||
|
| up4 | 4-finger swipe up | ctrl+alt+shift+Down |
|
||||||
|
| down3 | 3-finger swipe down | ctrl+alt+Up |
|
||||||
|
| down4 | 4-finger swipe down | ctrl+alt+shift+Up |
|
||||||
|
| threshold | mouse movement pixels that trigger a swipe (can be as large as 1000.0) | 0.0, 240.0, 1000.0 |
|
||||||
|
| mouse3 | holds a mouse button when 3 fingers are down | button1 (see [Mouse Gestures](#mouse-gestures-experimental)) | |
|
||||||
|
| mouse4 | holds a mouse button when 4 fingers are down | button1 (see [Mouse Gestures](#mouse-gestures-experimental) |
|
||||||
|
|
||||||
Taken from `man xdotool`:
|
Taken from `man xdotool`:
|
||||||
|
|
||||||
> Type a given keystroke. Examples being "alt+r", "Control_L+J",
|
> Type a given keystroke. Examples being "alt+r", "Control_L+J",
|
||||||
@ -100,42 +173,52 @@ Taken from `man xdotool`:
|
|||||||
|
|
||||||
Refer to https://www.linux.org/threads/xdotool-keyboard.10528/ for a complete list of keycodes you can use.
|
Refer to https://www.linux.org/threads/xdotool-keyboard.10528/ for a complete list of keycodes you can use.
|
||||||
|
|
||||||
**Keyboard Shortcuts**:
|
## Keyboard shortcuts
|
||||||
|
|
||||||
- Unity: https://cheatography.com/sapemeg/cheat-sheets/ubuntu-unity-16-04/
|
- [Unity Keyboard Shortcuts](https://cheatography.com/sapemeg/cheat-sheets/ubuntu-unity-16-04/)
|
||||||
- GNOME: https://wiki.gnome.org/Design/OS/KeyboardShortcuts
|
- [GNOME Keyboard Shortcuts](https://wiki.gnome.org/Design/OS/KeyboardShortcuts)
|
||||||
- KDE: https://community.linuxmint.com/tutorial/view/47
|
- [KDE Keyboard Shortcuts](https://community.linuxmint.com/tutorial/view/47)
|
||||||
|
|
||||||
## Swipe Gesture Templates
|
> **Note**: You can check which desktop you are using with `echo $DESKTOP_SESSION`.
|
||||||
|
|
||||||
1. Switching workspaces
|
## Example Configurations
|
||||||
|
|
||||||
|
This section includes some example configurations for `~/.config/comfortable-swipe.conf` which you can use for your swipe experience.
|
||||||
|
|
||||||
|
1. Switch workspace (horizontal)
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Unity, KDE
|
|
||||||
left3 = ctrl+alt+Right
|
left3 = ctrl+alt+Right
|
||||||
right3 = ctrl+alt+Left
|
right3 = ctrl+alt+Left
|
||||||
|
```
|
||||||
|
|
||||||
|
1. Switch workspace (vertical)
|
||||||
|
|
||||||
|
```
|
||||||
up3 = ctrl+alt+Down
|
up3 = ctrl+alt+Down
|
||||||
down3 = ctrl+alt+Up
|
down3 = ctrl+alt+Up
|
||||||
```
|
```
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# GNOME
|
|
||||||
up3 = super+PgDown
|
up3 = super+PgDown
|
||||||
down3 = super+PgUp
|
down3 = super+PgUp
|
||||||
```
|
```
|
||||||
|
|
||||||
1. Move window to workspace
|
1. Move window to workspace (horizontal)
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Unity, KDE
|
|
||||||
left4 = ctrl+alt+shift+Right
|
left4 = ctrl+alt+shift+Right
|
||||||
right4 = ctrl+alt+shift+Left
|
right4 = ctrl+alt+shift+Left
|
||||||
|
```
|
||||||
|
|
||||||
|
1. Move window to workspace (vertical)
|
||||||
|
|
||||||
|
```bash
|
||||||
up4 = ctrl+alt+shift+Down
|
up4 = ctrl+alt+shift+Down
|
||||||
down4 = ctrl+alt+shift+Up
|
down4 = ctrl+alt+shift+Up
|
||||||
```
|
```
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# GNOME
|
|
||||||
up4 = super+shift+PgDown
|
up4 = super+shift+PgDown
|
||||||
down4 = super+shift+PgUp
|
down4 = super+shift+PgUp
|
||||||
```
|
```
|
||||||
@ -143,7 +226,6 @@ Refer to https://www.linux.org/threads/xdotool-keyboard.10528/ for a complete li
|
|||||||
1. Move window to other monitor
|
1. Move window to other monitor
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# GNOME
|
|
||||||
left4 = super+shift+Right
|
left4 = super+shift+Right
|
||||||
right4 = super+shift+Left
|
right4 = super+shift+Left
|
||||||
```
|
```
|
||||||
@ -154,20 +236,17 @@ Refer to https://www.linux.org/threads/xdotool-keyboard.10528/ for a complete li
|
|||||||
up3 = super+s
|
up3 = super+s
|
||||||
```
|
```
|
||||||
|
|
||||||
1. Show desktop ([setup manually](https://www.itsupportguides.com/knowledge-base/ubuntu/ubuntu-how-to-make-windows-d-show-desktop/))
|
1. Show desktop
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Ubuntu
|
|
||||||
down3 = ctrl+super+d
|
|
||||||
```
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# GNOME
|
|
||||||
down3 = super+d
|
down3 = super+d
|
||||||
```
|
```
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# KDE
|
down3 = ctrl+super+d
|
||||||
|
```
|
||||||
|
|
||||||
|
```bash
|
||||||
down3 = ctrl+alt+d
|
down3 = ctrl+alt+d
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -199,22 +278,26 @@ Refer to https://www.linux.org/threads/xdotool-keyboard.10528/ for a complete li
|
|||||||
|
|
||||||
## Mouse Gestures (Experimental)
|
## Mouse Gestures (Experimental)
|
||||||
|
|
||||||
|
You can also play around with mouse gestures during swipe.
|
||||||
|
This enables certain mouse behaviour to trigger along with a 3/4-finger swipe.
|
||||||
|
|
||||||
|
Keys:
|
||||||
|
* mouse3 - for 3-finger mouse gestures
|
||||||
|
* mouse4 - for 4-finger mosue gestures
|
||||||
|
* hold3 (deprecated) - old equivalent of mouse3
|
||||||
|
* hold4 (deprecated) - old equivalent of mouse4
|
||||||
|
|
||||||
We have included simple mouse gestures on swipe by setting `hold3` and `hold4`.
|
We have included simple mouse gestures on swipe by setting `hold3` and `hold4`.
|
||||||
|
|
||||||
```bash
|
Possible Values:
|
||||||
Possible Values (hold3, hold4):
|
* button1 - hold left click on finger swipe
|
||||||
|
* button2 - hold middle click on finger swipe
|
||||||
move # just move the mouse cursor (no mousedown)
|
* button3 - hold right click on finger swipe
|
||||||
button1 # hold left click on finger swipe
|
* button4 - wheel up on finger swipe (experimental)
|
||||||
button2 # hold middle click on finger swipe
|
* button5 - wheel down on finger swipe (experimental)
|
||||||
button3 # hold right click on finger swipe
|
* move - just move the mouse cursor with the fingers
|
||||||
button4 # wheel up on finger swipe (experimental)
|
* scroll - 3/4 finger natural scroll (no acceleration, very experimental)
|
||||||
button5 # wheel down on finger swipe (experimental)
|
* scroll_reverse - 3/4 finger reverse scroll (no acceleration, very experimental)
|
||||||
scroll # naive 3/4 finger natural scroll (no acceleration, very experimental)
|
|
||||||
scroll_reverse # naive 3/4 finger reverse scroll (no acceleration, very experimental)
|
|
||||||
```
|
|
||||||
|
|
||||||
Any value not mentioned above disables the mouse-hold.
|
|
||||||
|
|
||||||
Examples:
|
Examples:
|
||||||
|
|
||||||
|
|||||||
@ -28,7 +28,7 @@ Commands:
|
|||||||
restart
|
restart
|
||||||
restarts 3/4-finger gesture service
|
restarts 3/4-finger gesture service
|
||||||
|
|
||||||
autostart [on|off|toggle|status|path]
|
autostart [<on|off|toggle|status|path>]
|
||||||
toggle to automatically run on startup automatically run on startup (toggleable)
|
toggle to automatically run on startup automatically run on startup (toggleable)
|
||||||
|
|
||||||
buffer
|
buffer
|
||||||
@ -37,7 +37,7 @@ Commands:
|
|||||||
help
|
help
|
||||||
shows the help dialog
|
shows the help dialog
|
||||||
|
|
||||||
config
|
config [<get|set|delete|list|keys|path>...]
|
||||||
shows the location of the config file
|
shows the location of the config file
|
||||||
|
|
||||||
debug
|
debug
|
||||||
@ -60,41 +60,20 @@ function start {
|
|||||||
|
|
||||||
# stop running comfortable-swipe commands (except self)
|
# stop running comfortable-swipe commands (except self)
|
||||||
function stop {
|
function stop {
|
||||||
local pids="$(pgrep -f comfortable-swipe | fgrep -v $$)"
|
function stop_name {
|
||||||
local stopped=""
|
pgrep -f "${1:?}" | fgrep -v $$ | xargs kill --
|
||||||
for pid in "$pids"; do
|
}
|
||||||
# stop process tree
|
stop_name "$BASENAME"
|
||||||
if kill -- -$pid 2> /dev/null; then
|
stop_name "$(which comfortable-swipe)"
|
||||||
stopped=" $(echo $pid)"
|
stop_name "$(which comfortable-swipe-buffer)"
|
||||||
fi
|
|
||||||
done
|
|
||||||
if [[ ! -z "$stopped" ]]; then
|
|
||||||
echo "comfortable-swipe stopped"
|
|
||||||
else
|
|
||||||
echo "comfortable-swipe is not running"
|
|
||||||
fi
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
# restart comfortable swipe
|
# restart comfortable swipe
|
||||||
function restart {
|
function restart {
|
||||||
stop > /dev/null 2>&1
|
stop > /dev/null 2>&1
|
||||||
start
|
# restart the server in the background
|
||||||
}
|
nohup "$BASENAME" start 0<&- &>/dev/null &
|
||||||
|
|
||||||
|
|
||||||
# parse input from a buffer
|
|
||||||
# internally calls comfortable-swipe-main.cpp, which is
|
|
||||||
# installed as: comfortable-swipe-buffer
|
|
||||||
function buffer {
|
|
||||||
exec comfortable-swipe-buffer "$@"
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
# get location of configuration file
|
|
||||||
function config {
|
|
||||||
# TODO: invoke subcommands
|
|
||||||
echo "$HOME/.config/comfortable-swipe.conf"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -110,9 +89,204 @@ function debug {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# parse input from a buffer
|
||||||
|
# internally calls comfortable-swipe-main.cpp, which is
|
||||||
|
# installed as: /usr/local/bin/ comfortable-swipe-buffer
|
||||||
|
function buffer {
|
||||||
|
exec comfortable-swipe-buffer "$@"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# get location of configuration file
|
||||||
|
function config {
|
||||||
|
local CONFIG="$HOME/.config/comfortable-swipe.conf"
|
||||||
|
local KEYS="left3|left4|right3|right4|up3|up4|down3|down4|threshold|mouse3|mouse4"
|
||||||
|
local DEPRECATED="hold3|hold4"
|
||||||
|
local USAGE="Usage: $BASENAME config [get|set|delete|list|keys|path]..."
|
||||||
|
# show path to config
|
||||||
|
function path {
|
||||||
|
echo "$CONFIG"
|
||||||
|
}
|
||||||
|
# get all keys from config, without comments
|
||||||
|
# and show only last among duplicates
|
||||||
|
function list {
|
||||||
|
# dispatch subcommands
|
||||||
|
if [[ $# -eq 0 ]]; then
|
||||||
|
# no options; just show path
|
||||||
|
tac "$CONFIG" |\
|
||||||
|
sed -E "s/[#;].*//g" |\
|
||||||
|
egrep '\s+' |\
|
||||||
|
tr -d ' ' |\
|
||||||
|
egrep "^($KEYS|$DEPRECATED)=" |\
|
||||||
|
awk '!a[$1]++' |\
|
||||||
|
tac |\
|
||||||
|
sed 's/=/ = /g'
|
||||||
|
else
|
||||||
|
# filter list to match arguments as pattern
|
||||||
|
local pattern="$1"
|
||||||
|
for arg in "${@:2}"; do
|
||||||
|
pattern="$pattern|$arg"
|
||||||
|
done
|
||||||
|
list | egrep "($pattern)[^=]* ="
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
# get a list of all valid keys, one per line
|
||||||
|
function keys {
|
||||||
|
echo "$KEYS" | sed 's/|/\n/g'
|
||||||
|
}
|
||||||
|
# Get a specific key in the config
|
||||||
|
# Usage: comfortable-swipe config get <key>
|
||||||
|
function get {
|
||||||
|
# helper function to print usage
|
||||||
|
function usage {
|
||||||
|
echo "Usage: $BASENAME config get <KEY>"
|
||||||
|
echo -n "Keys: "
|
||||||
|
echo "$KEYS" | sed 's/|/, /g'
|
||||||
|
}
|
||||||
|
# no next argument: show list
|
||||||
|
if [[ $# -eq 0 ]]; then
|
||||||
|
list
|
||||||
|
exit $?
|
||||||
|
fi
|
||||||
|
local KEY="$1"
|
||||||
|
# check if key is valid
|
||||||
|
if ! [[ "$KEY" =~ ^($KEYS|$DEPRECATED)$ ]]; then
|
||||||
|
echo "'$KEY' is an invalid key" >&2
|
||||||
|
echo >&2
|
||||||
|
usage >&2
|
||||||
|
echo >&2
|
||||||
|
echo "If you want to filter keys, you can instead try:" >&2
|
||||||
|
echo >&2
|
||||||
|
echo " $BASENAME config list $@"
|
||||||
|
echo >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
# get key from config file
|
||||||
|
list | fgrep -m1 "$KEY =" | sed -E "s/^$KEY = //"
|
||||||
|
}
|
||||||
|
# Deletes a key in the config
|
||||||
|
function delete {
|
||||||
|
# helper function to print usage
|
||||||
|
function usage {
|
||||||
|
echo "Usage: $BASENAME config delete [<KEYS>...]"
|
||||||
|
}
|
||||||
|
# no next argument: show help
|
||||||
|
if [[ $# -eq 0 ]]; then
|
||||||
|
echo "Key is required!" >&2
|
||||||
|
# no key; show usage
|
||||||
|
usage >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
local DELETE="$(list "$@")"
|
||||||
|
# check if there is something to delete
|
||||||
|
if [[ -z "$DELETE" ]]; then
|
||||||
|
echo "No config entry to delete" >&2
|
||||||
|
exit 1
|
||||||
|
else
|
||||||
|
echo "Deleted:"
|
||||||
|
echo "$DELETE"
|
||||||
|
local RESULT="$(egrep -v "^\\s*($(echo "$DELETE" | awk '{print $1}' | paste -s -d '|'))\\s*=" "$CONFIG")"
|
||||||
|
echo "$RESULT" > "$CONFIG"
|
||||||
|
# restart comfortable-swipe
|
||||||
|
restart
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
# Set a specific key in the config
|
||||||
|
# Usage: comfortable-swipe config get <key>
|
||||||
|
function set {
|
||||||
|
# helper function to print usage
|
||||||
|
function usage {
|
||||||
|
echo "Usage: $BASENAME config set <KEY> [=] <VALUE>"
|
||||||
|
echo -n "Valid keys: "
|
||||||
|
echo "$KEYS" | sed 's/|/, /g'
|
||||||
|
}
|
||||||
|
# no next argument: show help
|
||||||
|
if [[ $# -eq 0 ]]; then
|
||||||
|
echo "Key is required!" >&2
|
||||||
|
echo >&2
|
||||||
|
# no key; show usage
|
||||||
|
usage >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
# parse key and value option
|
||||||
|
local KEYVALUE="${@:1}"
|
||||||
|
local KEY=
|
||||||
|
local VALUE=
|
||||||
|
case "$KEYVALUE" in
|
||||||
|
*=*)
|
||||||
|
# key has equal sign, we split it
|
||||||
|
KEY="${KEYVALUE%%=*}"
|
||||||
|
VALUE="${KEYVALUE#*=}"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
# default: just get from next arguments combined
|
||||||
|
if [[ $# -eq 1 ]]; then
|
||||||
|
echo "Value is required!" >&2
|
||||||
|
usage >&2
|
||||||
|
echo >&2
|
||||||
|
echo "If you want to set value to blank, explicitly pass a blank string:" >&2
|
||||||
|
echo >&2
|
||||||
|
echo " $BASENAME config set $@ \"\"" >&2
|
||||||
|
echo >&2
|
||||||
|
echo "Or delete explicitly:" >&2
|
||||||
|
echo >&2
|
||||||
|
echo " $BASENAME config delete $1"
|
||||||
|
echo >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
KEY="$1"
|
||||||
|
VALUE="${@:2}"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
# trim leading and trailing spaces from key and value
|
||||||
|
KEY="$(echo "$KEY" | awk '{$1=$1};1')"
|
||||||
|
VALUE="$(echo "$VALUE" | awk '{$1=$1};1')"
|
||||||
|
# check if key is valid
|
||||||
|
if ! [[ "$KEY" =~ ^($KEYS|$DEPRECATED)$ ]]; then
|
||||||
|
echo "'$KEY' is an invalid key" >&2
|
||||||
|
echo >&2
|
||||||
|
usage
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
# if the key is present in the config, perform a replace
|
||||||
|
# replace the last value from the config with the given key
|
||||||
|
if list | grep -P "^\Q$KEY =" > /dev/null 2>&1; then
|
||||||
|
# apply sed to keep our formatting
|
||||||
|
# \\1 - keep any kind of indentation
|
||||||
|
# \\2 - keep any comments after the value (with the whitespace instact)
|
||||||
|
local RESULT="$(tac "$CONFIG" |\
|
||||||
|
sed -E "s/^(\\s*)$KEY\\s*=\\s*(\?!(\\s*[#;]))*(.*)\$/\\1$KEY = $VALUE\\2/1" |\
|
||||||
|
tac)"
|
||||||
|
# make sure we separate piping from outputing
|
||||||
|
echo "$RESULT" > "$CONFIG"
|
||||||
|
else
|
||||||
|
# otherwise, key is not present so we simply append
|
||||||
|
echo "$KEY = $VALUE" >> "$CONFIG"
|
||||||
|
fi
|
||||||
|
# show newly set value
|
||||||
|
echo "$KEY = $(get "$KEY")"
|
||||||
|
restart
|
||||||
|
}
|
||||||
|
# dispatch subcommands
|
||||||
|
if [[ $# -eq 0 ]]; then
|
||||||
|
# no options; just show path
|
||||||
|
path
|
||||||
|
elif declare -f "$1" >/dev/null 2>&1; then
|
||||||
|
# invoke subcommand function, passing arguments through
|
||||||
|
# TODO: unset all nonlocal functions
|
||||||
|
"$@" # same as "$1" "$2" "$3" ... for full argument list
|
||||||
|
else
|
||||||
|
echo "Error: function $1 not recognized" >&2
|
||||||
|
echo "$USAGE" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
# enable or disable autostart
|
# enable or disable autostart
|
||||||
# you can also set manually by running: gnome-session-properties
|
# you can also set manually by running: gnome-session-properties
|
||||||
function autostart {
|
function autostart {
|
||||||
|
# path to autostart files
|
||||||
local AUTOSTART="$HOME/.config/autostart/comfortable-swipe.desktop"
|
local AUTOSTART="$HOME/.config/autostart/comfortable-swipe.desktop"
|
||||||
local ENABLED="X-GNOME-Autostart-enabled"
|
local ENABLED="X-GNOME-Autostart-enabled"
|
||||||
# show autostart file path
|
# show autostart file path
|
||||||
@ -145,15 +319,17 @@ function autostart {
|
|||||||
function toggle {
|
function toggle {
|
||||||
[[ $(status) = ON ]] && off || on
|
[[ $(status) = ON ]] && off || on
|
||||||
}
|
}
|
||||||
|
# dispatch subcommands
|
||||||
if [[ $# -eq 0 ]]; then
|
if [[ $# -eq 0 ]]; then
|
||||||
# default behavior is to toggle
|
# default behavior is to toggle
|
||||||
toggle
|
toggle
|
||||||
elif declare -f "$1" >/dev/null 2>&1; then
|
elif declare -f "$1" >/dev/null 2>&1; then
|
||||||
# invoke subcommand function, passing arguments through
|
# invoke subcommand function, passing arguments through
|
||||||
|
# TODO: unset all nonlocal functions
|
||||||
"$@" # same as "$1" "$2" "$3" ... for full argument list
|
"$@" # same as "$1" "$2" "$3" ... for full argument list
|
||||||
else
|
else
|
||||||
echo "Function $1 not recognized" >&2
|
echo "Function $1 not recognized" >&2
|
||||||
echo "Usage: comfortable-swipe autostart [on|off|toggle|status|path]" >&2
|
echo "Usage: $BASENAME autostart [on|off|toggle|status|path]" >&2
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
@ -162,8 +338,8 @@ function autostart {
|
|||||||
# verbosely show comfortable-swipe status
|
# verbosely show comfortable-swipe status
|
||||||
function status {
|
function status {
|
||||||
# TODO: show configuration status as well
|
# TODO: show configuration status as well
|
||||||
echo "autostart is $(autostart status)"
|
echo "Autostart is $("$BASENAME" autostart status)"
|
||||||
if pgrep -f comfortable-swipe | fgrep -v $$ > /dev/null 2>&1; then
|
if pgrep -f "$BASENAME" | fgrep -v $$ > /dev/null 2>&1; then
|
||||||
echo "comfortable-swipe program is RUNNING"
|
echo "comfortable-swipe program is RUNNING"
|
||||||
else
|
else
|
||||||
echo "comfortable-swipe program is STOPPED"
|
echo "comfortable-swipe program is STOPPED"
|
||||||
@ -193,18 +369,16 @@ case $i in
|
|||||||
esac
|
esac
|
||||||
done
|
done
|
||||||
|
|
||||||
############
|
# dispatch subcommands
|
||||||
# DISPATCH #
|
|
||||||
############
|
|
||||||
|
|
||||||
if [[ $# -eq 0 ]]; then
|
if [[ $# -eq 0 ]]; then
|
||||||
# no options; just show help
|
# no options; just show help
|
||||||
help
|
help
|
||||||
elif declare -f "$1" >/dev/null 2>&1; then
|
elif declare -f "$1" >/dev/null 2>&1; then
|
||||||
# invoke subcommand function, passing arguments through
|
# invoke subcommand function, passing arguments through
|
||||||
|
# TODO: unset all nonlocal functions
|
||||||
"$@" # same as "$1" "$2" "$3" ... for full argument list
|
"$@" # same as "$1" "$2" "$3" ... for full argument list
|
||||||
else
|
else
|
||||||
echo "error: function $1 not recognized" >&2
|
echo "Error: function $1 not recognized" >&2
|
||||||
echo "full usage: comfortable-swipe --help" >&2
|
echo "Usage: $BASENAME [--help|--version] [start|stop|restart|config|autostart|buffer|debug|status] [<args>]" >&2
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
#ifndef __comfortable_swipe_defines__
|
#ifndef __comfortable_swipe_defines__
|
||||||
#define __comfortable_swipe_defines__
|
#define __comfortable_swipe_defines__
|
||||||
/** All global #define statements go here */
|
// all global #define statements go here
|
||||||
/*
|
/*
|
||||||
Comfortable Swipe
|
Comfortable Swipe
|
||||||
by Rico Tiongson
|
by Rico Tiongson
|
||||||
|
|||||||
@ -54,12 +54,20 @@ public:
|
|||||||
virtual void end() override;
|
virtual void end() override;
|
||||||
// override this when keyboard gesture is to be performed
|
// override this when keyboard gesture is to be performed
|
||||||
virtual void do_keyboard_gesture(int mask);
|
virtual void do_keyboard_gesture(int mask);
|
||||||
|
// public accessors
|
||||||
|
virtual int get_previous_gesture() const {
|
||||||
|
return this->previous_gesture;
|
||||||
|
}
|
||||||
|
virtual int get_current_mask() const {
|
||||||
|
return this->current_mask;
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// stores square of threshold so we can compute faster
|
// stores square of threshold so we can compute faster
|
||||||
float threshold_squared;
|
float threshold_squared;
|
||||||
// stores previous gesture so we don't repeat action
|
// stores previous gesture so we don't repeat action
|
||||||
int previous_gesture;
|
int previous_gesture;
|
||||||
|
int current_mask;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// static enums we will use for gesture matching
|
// static enums we will use for gesture matching
|
||||||
@ -104,8 +112,12 @@ decltype(
|
|||||||
*/
|
*/
|
||||||
gesture_swipe_xdokey::gesture_swipe_xdokey(
|
gesture_swipe_xdokey::gesture_swipe_xdokey(
|
||||||
const decltype(gesture_swipe_xdokey::commands) &commands, float threshold)
|
const decltype(gesture_swipe_xdokey::commands) &commands, float threshold)
|
||||||
: gesture_swipe(), commands(commands),
|
: gesture_swipe(),
|
||||||
threshold_squared(threshold * threshold) {}
|
commands(commands),
|
||||||
|
threshold_squared(threshold * threshold),
|
||||||
|
previous_gesture(gesture_swipe_xdokey::FRESH),
|
||||||
|
current_mask(gesture_swipe_xdokey::FRESH)
|
||||||
|
{}
|
||||||
/**
|
/**
|
||||||
* Destructs this keyboard swipe gesture.
|
* Destructs this keyboard swipe gesture.
|
||||||
*/
|
*/
|
||||||
@ -116,8 +128,9 @@ gesture_swipe_xdokey::~gesture_swipe_xdokey() {}
|
|||||||
void gesture_swipe_xdokey::begin() {
|
void gesture_swipe_xdokey::begin() {
|
||||||
// call superclass method
|
// call superclass method
|
||||||
gesture_swipe::begin();
|
gesture_swipe::begin();
|
||||||
// assign previous gesture to FRESH
|
// assign gesture to FRESH
|
||||||
this->previous_gesture = gesture_swipe_xdokey::FRESH;
|
current_mask = FRESH;
|
||||||
|
previous_gesture = FRESH;
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Hook on update of swipe gesture.
|
* Hook on update of swipe gesture.
|
||||||
@ -125,60 +138,59 @@ void gesture_swipe_xdokey::begin() {
|
|||||||
void gesture_swipe_xdokey::update() {
|
void gesture_swipe_xdokey::update() {
|
||||||
// call superclass method
|
// call superclass method
|
||||||
gesture_swipe::update();
|
gesture_swipe::update();
|
||||||
// scale threshold to 1/10 when gesture is not fresh
|
// scale threshold to 1/10 when gesture is fresh
|
||||||
float scale = 1;
|
// acts like our static friction coefficient
|
||||||
if (this->previous_gesture == gesture_swipe_xdokey::FRESH)
|
float scale = get_previous_gesture() == FRESH ? 0.01f : 1.0f;
|
||||||
scale = 0.01f; // square root of 1/10
|
|
||||||
// we are working with floating points which are not exact
|
// we are working with floating points which are not exact
|
||||||
// make sure we compare with a very small value (epsilon)
|
// make sure we compare with a very small value (1e-6f)
|
||||||
static const float EPSILON = 1e-6f;
|
|
||||||
const float distance_squared = this->x * this->x + this->y * this->y;
|
|
||||||
const float beyond_threshold = this->threshold_squared * scale;
|
|
||||||
// if distance goes out of threshold, perform our swipe
|
// if distance goes out of threshold, perform our swipe
|
||||||
if (distance_squared > beyond_threshold + EPSILON) {
|
if (x * x + y * y > threshold_squared * scale + 1e-6f) {
|
||||||
// we parse our mask based on the values obtained from the regex
|
// we parse our mask based on the values obtained from the regex
|
||||||
int mask = 0;
|
int mask = 0;
|
||||||
if (this->fingers == 3)
|
if (fingers == 3)
|
||||||
mask |= gesture_swipe_xdokey::MSK_THREE_FINGERS;
|
mask |= MSK_THREE_FINGERS;
|
||||||
else if (this->fingers == 4)
|
else if (fingers == 4)
|
||||||
mask |= gesture_swipe_xdokey::MSK_FOUR_FINGERS;
|
mask |= MSK_FOUR_FINGERS;
|
||||||
const float absx = x >= 0 ? x : -x;
|
const float absx = x >= 0 ? x : -x;
|
||||||
const float absy = y >= 0 ? y : -y;
|
const float absy = y >= 0 ? y : -y;
|
||||||
if (absx > absy) {
|
if (absx > absy) {
|
||||||
// gesture is horizontal
|
// gesture is horizontal
|
||||||
mask |= gesture_swipe_xdokey::MSK_HORIZONTAL;
|
mask |= MSK_HORIZONTAL;
|
||||||
if (x < 0)
|
if (x < 0)
|
||||||
mask |= gesture_swipe_xdokey::MSK_NEGATIVE;
|
mask |= MSK_NEGATIVE;
|
||||||
else
|
else
|
||||||
mask |= gesture_swipe_xdokey::MSK_POSITIVE;
|
mask |= MSK_POSITIVE;
|
||||||
} else /* std::abs(x) <= std::abs(y) */
|
} else /* std::abs(x) <= std::abs(y) */
|
||||||
{
|
{
|
||||||
// gesture is vertical
|
// gesture is vertical
|
||||||
mask |= gesture_swipe_xdokey::MSK_VERTICAL;
|
mask |= MSK_VERTICAL;
|
||||||
if (y < 0)
|
if (y < 0)
|
||||||
mask |= gesture_swipe_xdokey::MSK_NEGATIVE;
|
mask |= MSK_NEGATIVE;
|
||||||
else
|
else
|
||||||
mask |= gesture_swipe_xdokey::MSK_POSITIVE;
|
mask |= MSK_POSITIVE;
|
||||||
}
|
}
|
||||||
|
// update our mask
|
||||||
|
current_mask = mask;
|
||||||
// send command on fresh OR opposite gesture
|
// send command on fresh OR opposite gesture
|
||||||
if (this->previous_gesture == gesture_swipe_xdokey::FRESH ||
|
if (previous_gesture == FRESH || previous_gesture == (mask ^ MSK_POSITIVE)) {
|
||||||
this->previous_gesture == (mask ^ gesture_swipe_xdokey::MSK_POSITIVE)) {
|
// do keyboard gesture
|
||||||
// finally, perform keyboard gesture
|
do_keyboard_gesture(mask);
|
||||||
this->do_keyboard_gesture(mask);
|
// reset our location variables
|
||||||
|
x = y = 0;
|
||||||
|
previous_gesture = mask;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else { // not in threshold, set mask to fresh
|
||||||
|
current_mask = FRESH;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Perform our maske command to xdo.
|
* Perform our maske command to xdo.
|
||||||
*/
|
*/
|
||||||
void gesture_swipe_xdokey::do_keyboard_gesture(int mask) {
|
void gesture_swipe_xdokey::do_keyboard_gesture(int mask) {
|
||||||
// perform our keyboard command with xdo_send_keysequence
|
// perform our keyboard command with xdo_send_keysequence
|
||||||
xdo_send_keysequence_window(this->xdo, CURRENTWINDOW, commands[mask].data(),
|
xdo_send_keysequence_window(xdo, CURRENTWINDOW, commands[mask].data(), 0);
|
||||||
0);
|
|
||||||
std::cout << "SWIPE " << command_name[mask] << std::endl;
|
std::cout << "SWIPE " << command_name[mask] << std::endl;
|
||||||
// reset our location variables
|
|
||||||
this->x = this->y = 0;
|
|
||||||
this->previous_gesture = mask;
|
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Hook on end of swipe gesture.
|
* Hook on end of swipe gesture.
|
||||||
|
|||||||
@ -67,8 +67,8 @@ public:
|
|||||||
// the button number being clicked
|
// the button number being clicked
|
||||||
int button;
|
int button;
|
||||||
// constructor
|
// constructor
|
||||||
gesture_swipe_xdomouse(const char *hold3, // 3 finger mouse down
|
gesture_swipe_xdomouse(const char *mouse3, // 3 finger mouse gesture
|
||||||
const char *hold4 // 4 finger mouse down
|
const char *mouse4 // 4 finger mouse gesture
|
||||||
);
|
);
|
||||||
// destructor
|
// destructor
|
||||||
virtual ~gesture_swipe_xdomouse();
|
virtual ~gesture_swipe_xdomouse();
|
||||||
@ -77,39 +77,27 @@ public:
|
|||||||
virtual void update() override;
|
virtual void update() override;
|
||||||
virtual void end() override;
|
virtual void end() override;
|
||||||
// provide our own mouse dispatch functions
|
// provide our own mouse dispatch functions
|
||||||
virtual void do_mousedown(const char *);
|
virtual void do_mousedown(int button, int fingers);
|
||||||
virtual void do_mouseup(const char *);
|
virtual void do_mouseup(int button, int fingers);
|
||||||
// utility method to check if mouse is being held
|
|
||||||
virtual bool is_holding() const;
|
|
||||||
// utility method to parse mouse input given config characters
|
// utility method to parse mouse input given config characters
|
||||||
static int parse_mouse_button(const char *);
|
static int parse_mouse_button(const char *);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// command holders
|
// command holders
|
||||||
const char *hold3;
|
const char *mouse3;
|
||||||
const char *hold4;
|
const char *mouse4;
|
||||||
|
|
||||||
private:
|
|
||||||
// flag we can use to check if mouse is down
|
|
||||||
bool flag_is_holding;
|
|
||||||
};
|
};
|
||||||
/**
|
/**
|
||||||
* Constructs a new mouse gesture, given "hold3" and "hold4" configurations.
|
* Constructs a new mouse gesture, given "mouse3" and "mouse4" configurations.
|
||||||
*/
|
*/
|
||||||
gesture_swipe_xdomouse::gesture_swipe_xdomouse(const char *hold3,
|
gesture_swipe_xdomouse::gesture_swipe_xdomouse(const char *mouse3,
|
||||||
const char *hold4)
|
const char *mouse4)
|
||||||
: gesture_swipe(), button(MOUSE_NONE), hold3(hold3), hold4(hold4),
|
: gesture_swipe(), button(MOUSE_NONE), mouse3(mouse3), mouse4(mouse4) {}
|
||||||
flag_is_holding(false) {}
|
|
||||||
/**
|
/**
|
||||||
* Destructs this mouse swipe gesture.
|
* Destructs this mouse swipe gesture.
|
||||||
*/
|
*/
|
||||||
gesture_swipe_xdomouse::~gesture_swipe_xdomouse() {}
|
gesture_swipe_xdomouse::~gesture_swipe_xdomouse() {}
|
||||||
/**
|
|
||||||
* Determines if some mousehold command is being run.
|
|
||||||
*/
|
|
||||||
bool gesture_swipe_xdomouse::is_holding() const {
|
|
||||||
return this->flag_is_holding;
|
|
||||||
}
|
|
||||||
/**
|
/**
|
||||||
* Utility method to parse mouse number from input.
|
* Utility method to parse mouse number from input.
|
||||||
* Returns MOUSE_NONE on failure.
|
* Returns MOUSE_NONE on failure.
|
||||||
@ -132,32 +120,21 @@ int gesture_swipe_xdomouse::parse_mouse_button(const char *input) {
|
|||||||
return MOUSE_NONE;
|
return MOUSE_NONE;
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Perform mousedown command on hold input.
|
* Run mousedown command on a mouse button input.
|
||||||
*/
|
*/
|
||||||
void gesture_swipe_xdomouse::do_mousedown(const char *input) {
|
void gesture_swipe_xdomouse::do_mousedown(int button, int fingers) {
|
||||||
const int button = this->button = this->parse_mouse_button(input);
|
if (MOUSE_LEFT_CLICK <= button && button <= MOUSE_RIGHT_CLICK) {
|
||||||
if (button != MOUSE_NONE) {
|
// send mouse down on associated button
|
||||||
// eg. MOUSE DOWN hold3 mouse1
|
xdo_mouse_down(xdo, CURRENTWINDOW, button);
|
||||||
std::printf("MOUSE DOWN hold%d %s\n", this->fingers, input);
|
|
||||||
if (MOUSE_LEFT_CLICK <= button && button <= MOUSE_RIGHT_CLICK) {
|
|
||||||
// send mouse down on associated button
|
|
||||||
xdo_mouse_down(this->xdo, CURRENTWINDOW, button);
|
|
||||||
}
|
|
||||||
this->flag_is_holding = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Run mouseup command on hold output.
|
* Run mouseup command on a mouse button output.
|
||||||
*/
|
*/
|
||||||
void gesture_swipe_xdomouse::do_mouseup(const char *input) {
|
void gesture_swipe_xdomouse::do_mouseup(int button, int fingers) {
|
||||||
const int button = this->button = this->parse_mouse_button(input);
|
if (MOUSE_LEFT_CLICK <= button && button <= MOUSE_RIGHT_CLICK) {
|
||||||
if (button != MOUSE_NONE) {
|
// send mouse up on associated button
|
||||||
std::printf("MOUSE UP hold%d %s\n", this->fingers, input);
|
xdo_mouse_up(xdo, CURRENTWINDOW, button);
|
||||||
if (MOUSE_LEFT_CLICK <= button && button <= MOUSE_RIGHT_CLICK) {
|
|
||||||
// send mouse up on associated button
|
|
||||||
xdo_mouse_up(this->xdo, CURRENTWINDOW, button);
|
|
||||||
}
|
|
||||||
this->flag_is_holding = false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
@ -166,11 +143,16 @@ void gesture_swipe_xdomouse::do_mouseup(const char *input) {
|
|||||||
void gesture_swipe_xdomouse::begin() {
|
void gesture_swipe_xdomouse::begin() {
|
||||||
// call superclass method
|
// call superclass method
|
||||||
gesture_swipe::begin();
|
gesture_swipe::begin();
|
||||||
// dispatch mouse down event
|
// map fingers to gesture command
|
||||||
if (this->fingers == 3) {
|
auto command = fingers == 3 ? mouse3 : (fingers == 4 ? mouse4 : NULL);
|
||||||
this->do_mousedown(this->hold3);
|
if (command != NULL) {
|
||||||
} else if (this->fingers == 4) {
|
// get button int from the command
|
||||||
this->do_mousedown(this->hold4);
|
button = parse_mouse_button(command);
|
||||||
|
// perform mousedown on the button and print to console
|
||||||
|
if (button != MOUSE_NONE) {
|
||||||
|
do_mousedown(button, fingers);
|
||||||
|
std::printf("MOUSE DOWN mouse%d %s\n", this->fingers, command);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
@ -179,26 +161,25 @@ void gesture_swipe_xdomouse::begin() {
|
|||||||
void gesture_swipe_xdomouse::update() {
|
void gesture_swipe_xdomouse::update() {
|
||||||
// call superclass method
|
// call superclass method
|
||||||
gesture_swipe::update();
|
gesture_swipe::update();
|
||||||
if (this->is_holding()) {
|
if (button != MOUSE_NONE) {
|
||||||
// if MOUSE_MOVE or MOUSE_CLICK*
|
// if MOUSE_MOVE or MOUSE_CLICK*
|
||||||
if (0 <= this->button && this->button <= 3) {
|
if (0 <= button && button <= 3) {
|
||||||
// drag mouse with pointer during update
|
// drag mouse with pointer during update
|
||||||
xdo_move_mouse_relative(this->xdo, this->udx, this->udy);
|
xdo_move_mouse_relative(xdo, udx, udy);
|
||||||
} else if (this->button == MOUSE_SCROLL ||
|
} else if (button == MOUSE_SCROLL ||
|
||||||
this->button == MOUSE_SCROLL_REVERSE) {
|
button == MOUSE_SCROLL_REVERSE) {
|
||||||
// perform naive scroll depending on vertical direction
|
// perform naive scroll depending on vertical direction
|
||||||
int wheel = MOUSE_WHEEL_DOWN;
|
int wheel = MOUSE_WHEEL_DOWN;
|
||||||
if ((this->udy > 0) == (this->button == MOUSE_SCROLL))
|
if ((udy > 0) == (button == MOUSE_SCROLL))
|
||||||
wheel = MOUSE_WHEEL_UP;
|
wheel = MOUSE_WHEEL_UP;
|
||||||
|
|
||||||
// click wheel on update (note: this is not precise)
|
// click wheel on update (note: this is not precise)
|
||||||
xdo_mouse_down(this->xdo, CURRENTWINDOW, wheel);
|
xdo_mouse_down(xdo, CURRENTWINDOW, wheel);
|
||||||
xdo_mouse_up(this->xdo, CURRENTWINDOW, wheel);
|
xdo_mouse_up(xdo, CURRENTWINDOW, wheel);
|
||||||
} else if (this->button == MOUSE_WHEEL_UP ||
|
} else if (button == MOUSE_WHEEL_UP ||
|
||||||
this->button == MOUSE_WHEEL_DOWN) {
|
button == MOUSE_WHEEL_DOWN) {
|
||||||
// click wheel button on 4 or 5
|
// click wheel button on 4 or 5
|
||||||
xdo_mouse_down(this->xdo, CURRENTWINDOW, this->button);
|
xdo_mouse_down(xdo, CURRENTWINDOW, button);
|
||||||
xdo_mouse_up(this->xdo, CURRENTWINDOW, this->button);
|
xdo_mouse_up(xdo, CURRENTWINDOW, button);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -207,13 +188,14 @@ void gesture_swipe_xdomouse::update() {
|
|||||||
*/
|
*/
|
||||||
void gesture_swipe_xdomouse::end() {
|
void gesture_swipe_xdomouse::end() {
|
||||||
// optimization: only perform mouseup when flag is set
|
// optimization: only perform mouseup when flag is set
|
||||||
if (this->is_holding()) {
|
if (button != MOUSE_NONE) {
|
||||||
if (this->fingers == 3) {
|
// map fingers to gesture command
|
||||||
this->do_mouseup(this->hold3);
|
// perform mouseup on the button and print to console
|
||||||
} else if (this->fingers == 4) {
|
do_mouseup(button, fingers);
|
||||||
this->do_mouseup(this->hold4);
|
std::printf("MOUSE UP mouse%d %s\n", fingers, fingers == 3 ? mouse3 : mouse4);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
// reset button
|
||||||
|
button = MOUSE_NONE;
|
||||||
// call superclass method
|
// call superclass method
|
||||||
gesture_swipe::end();
|
gesture_swipe::end();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,7 +3,7 @@
|
|||||||
/**
|
/**
|
||||||
* File: comfortable-swipe-gesture-swipe.cpp
|
* File: comfortable-swipe-gesture-swipe.cpp
|
||||||
*
|
*
|
||||||
* The definition of the class comfortable_swipe::gesture_swipe.
|
* This is the base class of all comfortable swipe gestures.
|
||||||
*
|
*
|
||||||
* The class `comfortable_swipe::gesture_swipe` handles dispatching
|
* The class `comfortable_swipe::gesture_swipe` handles dispatching
|
||||||
* of swipe gestures. The method `gesture_swipe::run(const char*)`
|
* of swipe gestures. The method `gesture_swipe::run(const char*)`
|
||||||
@ -41,13 +41,11 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||||||
#include <iostream> // std::cout, std::endl
|
#include <iostream> // std::cout, std::endl
|
||||||
#include <regex> // std::regex, std::regex_match, std::cmatch
|
#include <regex> // std::regex, std::regex_match, std::cmatch
|
||||||
#include <string> // std::stoi, std::stof
|
#include <string> // std::stoi, std::stof
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#include <xdo.h> // xdo, xdo_new, xdo_free,
|
#include <xdo.h> // xdo, xdo_new, xdo_free,
|
||||||
// xdo_get_mouse_location
|
// xdo_get_mouse_location
|
||||||
// CURRENT_WINDOW
|
// CURRENT_WINDOW
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace comfortable_swipe {
|
namespace comfortable_swipe {
|
||||||
/**
|
/**
|
||||||
* Handles swipe gesture input from libinput debug-events.
|
* Handles swipe gesture input from libinput debug-events.
|
||||||
@ -70,6 +68,10 @@ public:
|
|||||||
virtual void update();
|
virtual void update();
|
||||||
virtual void end();
|
virtual void end();
|
||||||
virtual bool run(const char *);
|
virtual bool run(const char *);
|
||||||
|
// public check if currently swiping
|
||||||
|
virtual bool is_swiping() const {
|
||||||
|
return this->flag_swiping;
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// xdo container
|
// xdo container
|
||||||
|
|||||||
@ -83,20 +83,29 @@ int main() {
|
|||||||
// initialize mouse hold gesture handler
|
// initialize mouse hold gesture handler
|
||||||
// for now, this supports 3-finger and 4-finger hold
|
// for now, this supports 3-finger and 4-finger hold
|
||||||
// Examples:
|
// Examples:
|
||||||
// hold3=move move mouse on 3 fingers
|
// mouse3=move move mouse on 3 fingers
|
||||||
// hold3=button1 hold button 1 on 3 fingers
|
// mouse3=button1 hold button 1 on 3 fingers
|
||||||
// hold4=button3 hold button 3 (right click) on 3 fingers
|
// mouse4=button3 hold button 3 (right click) on 3 fingers
|
||||||
// hold3=ignore <do nothing>
|
// warn user that hold3 is deprecated
|
||||||
gesture_swipe_xdomouse mousehold(config["hold3"].data(),
|
if (config.count("hold3"))
|
||||||
config["hold4"].data());
|
std::cerr << "WARNING: hold3 is deprecated. Use mouse3 instead." << std:: endl;
|
||||||
|
if (config.count("hold4"))
|
||||||
|
std::cerr << "WARNING: hold4 is deprecated. Use mouse4 instead." << std::endl;
|
||||||
|
// get input values
|
||||||
|
string mouse3 = config.count("mouse3") ? config["mouse3"] : config["hold3"];
|
||||||
|
string mouse4 = config.count("mouse4") ? config["mouse4"] : config["hold4"];
|
||||||
|
// create our mouse gesture holder
|
||||||
|
gesture_swipe_xdomouse mousehold(mouse3.data(), mouse4.data());
|
||||||
// start reading lines from input one by one
|
// start reading lines from input one by one
|
||||||
for (string line; getline(cin, line);) {
|
for (string line; getline(cin, line);) {
|
||||||
// prioritize mouse hold gesture first before keyboard gesture
|
// optimization: if no mouse config is set, just run keyboard
|
||||||
mousehold.run(line.data());
|
if (mousehold.is_swiping() && mousehold.button == MOUSE_NONE) {
|
||||||
// if mouse hold fails, try keyboard swipe
|
|
||||||
// attempt to parse keyboard gestures
|
|
||||||
if (!mousehold.is_holding()) {
|
|
||||||
keyswipe.run(line.data());
|
keyswipe.run(line.data());
|
||||||
|
} else if (mousehold.run(line.data())) {
|
||||||
|
// only allow keyswipe gestures on mouse move
|
||||||
|
if (mousehold.button == MOUSE_MOVE) {
|
||||||
|
keyswipe.run(line.data());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
|
|||||||
12
compile
Executable file
12
compile
Executable file
@ -0,0 +1,12 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# usage: ./compile *.cpp
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
DIR="$(dirname $0)"
|
||||||
|
VERSION="$(cat "$DIR/VERSION" | tr -d '[:space:]')"
|
||||||
|
|
||||||
|
CXX='g++'
|
||||||
|
CXX_FLAGS='-std=c++14 -O2 -Wall -lxdo -linih -lxdo -linih'
|
||||||
|
|
||||||
|
g++ "$@" ${CXX_FLAGS} -DCOMFORTABLE_SWIPE_VERSION="\"$VERSION\""
|
||||||
@ -1,9 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
# main compile script
|
|
||||||
# usage: ./compile.sh *.cpp
|
|
||||||
set -e
|
|
||||||
|
|
||||||
DIR="$(dirname $0)"
|
|
||||||
VERSION="$(cat "$DIR/VERSION" | tr -d '[:space:]')"
|
|
||||||
|
|
||||||
g++ "$@" -std=c++14 -O2 -Wall -lxdo -linih -DCOMFORTABLE_SWIPE_VERSION="\"$VERSION\""
|
|
||||||
42
config/comfortable-swipe.conf
Normal file
42
config/comfortable-swipe.conf
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
# Comfortable Swipe
|
||||||
|
#
|
||||||
|
# Feel free to edit this configuration file if you have different
|
||||||
|
# keyboard shortcuts that you would like to use. Comments starting
|
||||||
|
# with a pound (#) or semi-colon (;) are ignored.
|
||||||
|
#
|
||||||
|
# Refer to https://www.linux.org/threads/xdotool-keyboard.10528/ for
|
||||||
|
# a list of keycodes you can use.
|
||||||
|
|
||||||
|
left3 = ctrl+alt+Right
|
||||||
|
left4 = ctrl+alt+shift+Right
|
||||||
|
right3 = ctrl+alt+Left
|
||||||
|
right4 = ctrl+alt+shift+Left
|
||||||
|
up3 = ctrl+alt+Down
|
||||||
|
up4 = ctrl+alt+shift+Down
|
||||||
|
down3 = ctrl+alt+Up
|
||||||
|
down4 = ctrl+alt+shift+Up
|
||||||
|
|
||||||
|
# Tweak threshold depending on the sensitivity of your touchpad.
|
||||||
|
# Make this higher to lessen sensitivity.
|
||||||
|
# (note: values have no limit, can be as large as 1000.0)
|
||||||
|
threshold = 0.0
|
||||||
|
|
||||||
|
# Uncomment below to enable mouse gestures (3 fingers)
|
||||||
|
; mouse3 = button1 # drag left click
|
||||||
|
; mouse3 = button2 # drag middle click
|
||||||
|
; mouse3 = button3 # drag right click
|
||||||
|
; mouse3 = button4 # drag wheel up
|
||||||
|
; mouse3 = button5 # drag wheel down
|
||||||
|
; mouse3 = move # just move mouse along with the cursor
|
||||||
|
; mouse3 = scroll # natural scroll (experimental)
|
||||||
|
; mouse3 = scroll_reverse # reverse scroll (experimental)
|
||||||
|
|
||||||
|
# Uncomment below to enable mouse gestures (4 fingers)
|
||||||
|
; mouse4 = button1 # drag left click
|
||||||
|
; mouse4 = button2 # drag middle click
|
||||||
|
; mouse4 = button3 # drag right click
|
||||||
|
; mouse4 = button4 # drag wheel up
|
||||||
|
; mouse4 = button5 # drag wheel down
|
||||||
|
; mouse4 = move # just move mouse along with the cursor
|
||||||
|
; mouse4 = scroll # natural scroll (experimental)
|
||||||
|
; mouse4 = scroll_reverse # reverse scroll (experimental)
|
||||||
@ -1,34 +0,0 @@
|
|||||||
# Comfortable Swipe converts touchpad swipe gestures to keyboard commands. You
|
|
||||||
# may edit this configuration file if you have different keyboard shortcuts
|
|
||||||
# that you would like to use. You can ignore a gesture by commenting out with
|
|
||||||
# a pound(#) symbol.
|
|
||||||
#
|
|
||||||
# Refer to https://www.linux.org/threads/xdotool-keyboard.10528/ for a list of
|
|
||||||
# keycodes you can use.
|
|
||||||
|
|
||||||
left3 = ctrl+alt+Right
|
|
||||||
left4 = ctrl+alt+shift+Right
|
|
||||||
right3 = ctrl+alt+Left
|
|
||||||
right4 = ctrl+alt+shift+Left
|
|
||||||
up3 = ctrl+alt+Down
|
|
||||||
up4 = ctrl+alt+shift+Down
|
|
||||||
down3 = ctrl+alt+Up
|
|
||||||
down4 = ctrl+alt+shift+Up
|
|
||||||
|
|
||||||
# Tweak this value depending on the sensitivity of your mousepad to perform
|
|
||||||
# gestures. A higher value means less sensitive.
|
|
||||||
# Note: Sky is the limit! Can be as large as 1000.0
|
|
||||||
threshold = 0.0
|
|
||||||
|
|
||||||
# Uncomment below for mousedown
|
|
||||||
; hold3 = button1
|
|
||||||
; hold4 = button1
|
|
||||||
|
|
||||||
# Values: button1 (left click)
|
|
||||||
# button2 (middle click)
|
|
||||||
# button3 (right click),
|
|
||||||
# button4 (wheel up)
|
|
||||||
# button5 (wheel down),
|
|
||||||
# move (just move with cursor)
|
|
||||||
# scroll (natural scrolling)
|
|
||||||
# scroll_reverse (reversed scrolling)
|
|
||||||
6
install
6
install
@ -10,17 +10,17 @@ SOURCE="$DIR/comfortable-swipe"
|
|||||||
TARGET="/usr/local/bin/comfortable-swipe"
|
TARGET="/usr/local/bin/comfortable-swipe"
|
||||||
|
|
||||||
# compile targets
|
# compile targets
|
||||||
COMPILE="$DIR/compile.sh"
|
COMPILE="$DIR/compile"
|
||||||
COMPILE_SOURCE="$DIR/comfortable-swipe-main.cpp"
|
COMPILE_SOURCE="$DIR/comfortable-swipe-main.cpp"
|
||||||
COMPILE_TARGET="/usr/local/bin/comfortable-swipe-buffer"
|
COMPILE_TARGET="/usr/local/bin/comfortable-swipe-buffer"
|
||||||
|
|
||||||
# configurations
|
# configurations
|
||||||
CONF_SOURCE="$DIR/defaults.conf"
|
CONF_SOURCE="$DIR/config/comfortable-swipe.conf"
|
||||||
CONF_TARGET="$HOME/.config/comfortable-swipe.conf"
|
CONF_TARGET="$HOME/.config/comfortable-swipe.conf"
|
||||||
OLD_CONF_TARGET="/usr/local/share/comfortable-swipe/comfortable-swipe.conf"
|
OLD_CONF_TARGET="/usr/local/share/comfortable-swipe/comfortable-swipe.conf"
|
||||||
|
|
||||||
# autostart
|
# autostart
|
||||||
AUTOSTART_SOURCE="$DIR/comfortable-swipe.desktop"
|
AUTOSTART_SOURCE="$DIR/config/comfortable-swipe.desktop"
|
||||||
AUTOSTART_TARGET="$HOME/.config/autostart/comfortable-swipe.desktop"
|
AUTOSTART_TARGET="$HOME/.config/autostart/comfortable-swipe.desktop"
|
||||||
|
|
||||||
# stop any running comfortable-swipe if it exists
|
# stop any running comfortable-swipe if it exists
|
||||||
|
|||||||
@ -3,7 +3,7 @@
|
|||||||
set -e
|
set -e
|
||||||
|
|
||||||
DIR="$(dirname "$0")"
|
DIR="$(dirname "$0")"
|
||||||
COMPILER="$(dirname "$DIR")/compile.sh"
|
COMPILER="$(dirname "$DIR")/compile"
|
||||||
|
|
||||||
# just call abort on error
|
# just call abort on error
|
||||||
TEMPOUT="$(mktemp)"
|
TEMPOUT="$(mktemp)"
|
||||||
|
|||||||
@ -4,7 +4,7 @@ set -ex
|
|||||||
|
|
||||||
DIR="$(dirname "$0")"
|
DIR="$(dirname "$0")"
|
||||||
ROOT="$(dirname "$DIR")"
|
ROOT="$(dirname "$DIR")"
|
||||||
COMPILER="$ROOT/compile.sh"
|
COMPILER="$ROOT/compile"
|
||||||
|
|
||||||
# just call abort on error
|
# just call abort on error
|
||||||
TEMPOUT="$(mktemp)"
|
TEMPOUT="$(mktemp)"
|
||||||
@ -20,7 +20,7 @@ echo "threshold = 0.0" >> "$EMPTY_CONFIG"
|
|||||||
"$COMPILER" "$ROOT/comfortable-swipe-main.cpp" -o "$TEMPOUT" \
|
"$COMPILER" "$ROOT/comfortable-swipe-main.cpp" -o "$TEMPOUT" \
|
||||||
-DCOMFORTABLE_SWIPE_AUTOSTART="\"$ROOT/comfortable-swipe.desktop\"" \
|
-DCOMFORTABLE_SWIPE_AUTOSTART="\"$ROOT/comfortable-swipe.desktop\"" \
|
||||||
-DCOMFORTABLE_SWIPE_CONFIG="\"$EMPTY_CONFIG\"" \
|
-DCOMFORTABLE_SWIPE_CONFIG="\"$EMPTY_CONFIG\"" \
|
||||||
|| abort
|
|| abort
|
||||||
chmod +x "$TEMPOUT"
|
chmod +x "$TEMPOUT"
|
||||||
|
|
||||||
set +x
|
set +x
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user