Add comfortable-swipe source file

This commit is contained in:
Rico Tiongson 2017-09-25 23:18:07 +08:00
parent 8a9d5c96ec
commit 9c2d1532c7
4 changed files with 213 additions and 1 deletions

View File

@ -1,2 +1,6 @@
# Ubuntu-Comfortable-3-Finger-Swipe # Ubuntu-Comfortable-3-Finger-Swipe
Comfortable 3-finger and 4-finger swipe gesture using Xdotool in native C++ Comfortable 3-finger and 4-finger swipe gesture using Xdotool in native C++, for Ubuntu 16.04LTS and beyond.
## Installation Instructions
1. `sudo apt install libxdo-dev`
2. `

10
install Executable file
View File

@ -0,0 +1,10 @@
#!/bin/bash
DIR=$(dirname $0)
echo "Compiling..."
g++ -std=c++11 -O2 $DIR/src/comfortable-swipe.cpp -lxdo -o ~/.local/bin/comfortable-swipe || exec echo "Installation aborted"
cat $DIR/src/comfortable-swipe-serve > ~/.local/bin/comfortable-swipe-serve
chmod +x ~/.local/bin/comfortable-swipe-serve
echo "Successfully installed. You may now try running 'comfortable-swipe-serve'."
echo "--------------------------------------------------------------------------"
echo "If you want 'comfortable-swipe-serve' to automatically load on login, add it to your Startup Applications."
echo "See https://help.ubuntu.com/stable/ubuntu-help/startup-applications.html"

View File

@ -0,0 +1,2 @@
#!/bin/sh
stdbuf -oL -eL libinput-debug-events | comfortable-swipe "$@"

196
src/comfortable-swipe.cpp Normal file
View File

@ -0,0 +1,196 @@
// you may tweak these before calling `build`
#define THRESHOLD 20
#define CMD_THREE_FINGERS_RIGHT "ctrl+alt+Left"
#define CMD_THREE_FINGERS_LEFT "ctrl+alt+Right"
#define CMD_THREE_FINGERS_UP "super+w"
#define CMD_THREE_FINGERS_DOWN "super+w"
#define CMD_FOUR_FINGERS_RIGHT "ctrl+shift+alt+Left"
#define CMD_FOUR_FINGERS_LEFT "ctrl+shift+alt+Right"
#define CMD_FOUR_FINGERS_UP "super+d"
#define CMD_FOUR_FINGERS_DOWN "super+d"
#define MSK_THREE_FINGERS 0
#define MSK_FOUR_FINGERS 1
#define MSK_NEGATIVE 0
#define MSK_POSITIVE 2
#define MSK_HORIZONTAL 0
#define MSK_VERTICAL 4
const char* commands[] = {
CMD_THREE_FINGERS_LEFT /* 000 */, CMD_FOUR_FINGERS_LEFT /* 001 */,
CMD_THREE_FINGERS_RIGHT /* 010 */ , CMD_FOUR_FINGERS_RIGHT /* 011 */,
CMD_THREE_FINGERS_UP /* 100 */ , CMD_FOUR_FINGERS_UP /* 101 */,
CMD_THREE_FINGERS_DOWN /* 110 */, CMD_FOUR_FINGERS_DOWN /* 111 */
};
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cstdarg>
#include <cassert>
#include <regex>
#include <chrono>
#include <ctime>
#include <unistd.h>
extern "C" {
// sudo apt install libxdo-dev
#include <xdo.h>
}
using namespace std;
#define cstr const string&
/* FORWARD DECLARATIONS */
namespace util {
string join(cstr, string[], int);
string build_gesture_begin();
string build_gesture_update();
string build_gesture_end();
}
struct swipe_gesture {
string device, stamp, fingers;
string dx, dy, udx, udy;
xdo_t* xdo;
virtual void on_update() = 0;
virtual void on_begin() = 0;
virtual void on_end() = 0;
swipe_gesture(): xdo(xdo_new(NULL)) {}
~swipe_gesture() {xdo_free(xdo);}
};
struct swipe_gesture_impl : swipe_gesture {
int screen_num, ix, iy;
double x, y;
bool gesture_done;
swipe_gesture_impl(): swipe_gesture() {}
~swipe_gesture_impl() {}
void key(const char* cmd) const {
xdo_send_keysequence_window(xdo, CURRENTWINDOW, cmd, 0);
}
void on_begin() override {
// cout << "BEGIN" << endl;
xdo_get_mouse_location(xdo, &ix, &iy, &screen_num);
gesture_done = false;
x = 0;
y = 0;
}
void on_update() override {
if (gesture_done) return;
// cout << "UPDATE " << x << ' ' << y << " [" << dx << ", " << dy << "]" << endl;
x += stod(dx);
y += stod(dy);
if (x*x + y*y > THRESHOLD*THRESHOLD) {
gesture_done = true;
int mask = 0;
if (fingers == "3") mask |= MSK_THREE_FINGERS; else
if (fingers == "4") mask |= MSK_FOUR_FINGERS;
if (abs(x) > abs(y)) {
mask |= MSK_HORIZONTAL;
if (x < 0) mask |= MSK_NEGATIVE;
else mask |= MSK_POSITIVE;
} else {
mask |= MSK_VERTICAL;
if (y < 0) mask |= MSK_NEGATIVE;
else mask |= MSK_POSITIVE;
}
// cout << "FLICK " << mask << ' ' << commands[mask] << endl;
key(commands[mask]);
}
}
void on_end() override {
// pass
}
};
/* MAIN DRIVER FUNCTION */
int main(int argc, char** args) {
ios::sync_with_stdio(false);
cin.tie(0);
const regex gesture_begin(util::build_gesture_begin());
const regex gesture_update(util::build_gesture_update());
const regex gesture_end(util::build_gesture_end());
string sentence;
swipe_gesture_impl swipe;
while (getline(cin, sentence)) {
auto data = sentence.data();
cmatch matches;
if (regex_match(data, matches, gesture_begin)) {
swipe.device = matches[1];
swipe.stamp = matches[2];
swipe.fingers = matches[3];
swipe.on_begin();
}
else if (regex_match(data, matches, gesture_end)) {
swipe.device = matches[1];
swipe.stamp = matches[2];
swipe.fingers = matches[3];
swipe.on_end();
}
else if (regex_match(data, matches, gesture_update)) {
swipe.device = matches[1];
swipe.stamp = matches[2];
swipe.fingers = matches[3];
swipe.dx = matches[4];
swipe.dy = matches[5];
swipe.udx = matches[6];
swipe.udy = matches[7];
swipe.on_update();
}
}
}
/* UTILITY FUNCTIONS */
namespace util {
string number_regex() {
return "-?\\d+(?:\\.\\d+)";
}
string join(cstr delim, string arr[], int n) {
string ans = arr[0];
for (int i = 1; i < n; ++i) {
ans += delim;
ans += arr[i];
}
return ans;
}
string build_gesture_begin() {
string device = "\\s*(\\S+)\\s*";
string gesture = "\\s*GESTURE_SWIPE_BEGIN\\s*";
string seconds = "\\s*(\\S+)\\s*";
string fingers = "\\s*(\\d+)\\s*";
string arr[] = {device, gesture, seconds, fingers};
return join("\\s+", arr, 4);
}
string build_gesture_update() {
string device = "\\s*(\\S+)\\s*";
string gesture = "\\s*GESTURE_SWIPE_UPDATE\\s*";
string seconds = "\\s*(\\S+)\\s*";
string fingers = "\\s*(\\d+)\\s*";
string num_1 = "\\s*(" + number_regex() + ")\\s*";
string num_2 = num_1;
string num_div = num_1 + "/" + num_2;
string num_accel = "\\s*\\(\\s*" + num_div + "\\s*unaccelerated\\s*\\)\\s*";
string arr[] = {device, gesture, seconds, fingers, num_div, num_accel};
return join("\\s+", arr, 6);
}
string build_gesture_end() {
string device = "\\s*(\\S+)\\s*";
string gesture = "\\s*GESTURE_SWIPE_END\\s*";
string seconds = "\\s*(\\S+)\\s*";
string fingers = "\\s*(\\d+)\\s*";
string arr[] = {device, gesture, seconds, fingers};
return join("\\s+", arr, 4);
}
}