Add mouse hold gestures (#79)

* Modularly separate keyboard swipe gesture from generic swipe

* Set destructors virtual to avoid surprises

* Prepare mouse swipe gesture skeleton

* Modify mouse move update

* Use xdo_move_mouse_relative instead of screen capture

* Restructure and add compiler tests

* Fix bash install script

* Add experimental: mouse hold on defaults.conf

* Update README and defaults.conf

* Do mousedown only for buttons 1 to 3

* Fix stop script and mouse gesture on button 4/5

* Redirect restart command to null

* Redirect using freopen

* Add comments on experimental scrolling
This commit is contained in:
Rico Tiongson 2020-04-18 03:55:13 +08:00 committed by GitHub
parent 8f6e231a5e
commit a7c5b6d578
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
36 changed files with 922 additions and 216 deletions

4
CHANGELOG Normal file
View File

@ -0,0 +1,4 @@
v1.1.0
* Added mouse hold gestures
* Added `hold3` configuration
* Added `hold4` configuration

View File

@ -2,8 +2,11 @@
[![comfortable-swipe version](https://img.shields.io/github/release/Hikari9/comfortable-swipe.svg?label=comfortable-swipe&color=orange)](https://github.com/Hikari9/comfortable-swipe/releases) [![comfortable-swipe version](https://img.shields.io/github/release/Hikari9/comfortable-swipe.svg?label=comfortable-swipe&color=orange)](https://github.com/Hikari9/comfortable-swipe/releases)
[![License: GPL v3](https://img.shields.io/badge/License-GPL%20v3-blue.svg)](https://www.gnu.org/licenses/gpl-3.0) [![License: GPL v3](https://img.shields.io/badge/License-GPL%20v3-blue.svg)](https://www.gnu.org/licenses/gpl-3.0)
> **_New in Version 1.1.0!_** Added mouse move gestures (eg. `hold3 = button1`)
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`.
## Installation ## Installation
1. Install git, libinput, and g++ 1. Install git, libinput, and g++
@ -47,28 +50,35 @@ Comfortable, seamless, and fast 3-finger (and 4-finger) touchpad swipe gestures
comfortable-swipe status comfortable-swipe status
``` ```
## Configurations ## Swipe Configurations
Comfortable swipe makes use of keyboard shortcuts for configurations. Edit by running
```
gedit $(comfortable-swipe config)
```
Make sure to run after making changes: Comfortable swipe makes use of keyboard shortcuts for configurations.
```
comfortable-swipe restart
```
Property | Description | Default Value | Default Behavior 1. Edit by running
--------- | ----------- | -------------- | ----- ```
threshold | mouse pixels to activate swipe; higher = less sensitive; floating-point (Note: Sky is the limit! Can be as large as 1000.0) | 0.0 gedit $(comfortable-swipe config)
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
right3 | 3-finger swipe right | ctrl+alt+Left | switch to left workspace 1. List of possible configurations:
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 Property | Description | Default Value | Default Behavior
up4 | 4-finger swipe up | ctrl+alt+shift+Down | move window to bottom workspace --------- | :-----------: | -------------- | -----
down3 | 3-finger swipe down | ctrl+alt+Down | switch to above workspace left3 | 3-finger swipe left | ctrl+alt+Right | switch to right workspace
down4 | 4-finger swipe down | ctrl+alt+shift+Up | move window to above workpace left4 | 4-finger swipe left | ctrl+alt+shift+Right | move window to right workspace
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+Down | 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](#mouse-configurations)
hold4 | holds a mouse button when 4 fingers are down | (none) | See [Mouse Gestures](#mouse-configurations)
1. After making changes, make sure to restart the program:
```
comfortable-swipe restart
```
Taken from `man xdotool`: Taken from `man xdotool`:
@ -86,6 +96,54 @@ 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.
## Mouse Gestures
> **Note**: Setting hold3 or hold4 will ignore its corresponding up/right/down/left command.
We have included simple mouse gestures on swipe by setting `hold3` and `hold4`.
**Possible values**:
* move - just move the mouse
* button1 - left click
* button2 - middle click
* button3 - right click
* button4 - wheel up (experimental)
* button5 - wheel down (experimental)
* scroll - natural scrolling (experimental)
* scroll_reverse - reverse scrolling (experimental)
## Example Configuration
Edit with `gedit $(comfortable-swipe config)`:
```conf
# File: comfortable-swipe.conf
# four-finger drag
hold4 = button1
# show desktop
down3 = super+d
# show workspaces
up3 = super+s
# switch workspace
left3 = ctrl+alt+Right
right3 = ctrl+alt+Left
# disabled because of hold4
left4 = ctrl+alt+shift+Right
right4 = ctrl+alt+shift+Left
# three-finger middle click (experimental)
# hold3 = button2
# three-finger scroll (experimental)
# hold3 = scroll
# hold3 = scroll_reverse
```
## Debugging ## Debugging

View File

@ -1 +1 @@
v1.0.4 v1.1.0

View File

@ -1,7 +0,0 @@
#!/bin/sh
dir="$(dirname $0)"
g++ "$dir/comfortable-swipe.cpp" \
-o "$1" \
-std=c++11 \
-O2 -lxdo -Wno-unused-result \
-DCOMFORTABLE_SWIPE_VERSION="\"$(cat $dir/VERSION | tr -d '[:space:]')\""

View File

@ -1,5 +1,12 @@
#ifndef __COMFORTABLE_SWIPE__index_hpp__ /**
#define __COMFORTABLE_SWIPE__index_hpp__ * Add header files will be imported here.
* You can import this as a shorthand:
*
* #include "../all_headers.hpp"
*/
#ifndef __COMFORTABLE_SWIPE__all_headers_hpp__
#define __COMFORTABLE_SWIPE__all_headers_hpp__
/* /*
Comfortable Swipe Comfortable Swipe
@ -36,21 +43,20 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <map> // std::map #include <map> // std::map
#include <string> // std::string #include <string> // std::string
/**
* Make sure to include your header files here so that they can be imported by other modules.
*/
#include "gesture/xdo_gesture.h"
#include "gesture/swipe_gesture.h"
extern "C" extern "C"
{ {
namespace comfortable_swipe namespace comfortable_swipe
{ {
// driver method
int driver();
// this is found in the util/ folder
namespace util namespace util
{ {
const char* autostart_filename(); const char* autostart_filename();
constexpr const char* conf_filename(); constexpr const char* conf_filename();
std::map<std::string, std::string> read_config_file(const char*); std::map<std::string, std::string> read_config_file(const char*);
} }
// this is found in the service/ folder
namespace service namespace service
{ {
void autostart(); void autostart();
@ -66,4 +72,10 @@ extern "C"
} }
} }
#endif /* __COMFORTABLE_SWIPE__index_hpp__ */ // add headers for classes here so it can be imported during include
#include "gesture/xdo_gesture.h"
#include "gesture/swipe_gesture.h"
#include "gesture/keyboard_swipe_gesture.h"
#include "gesture/mouse_hold_gesture.h"
#endif /* __COMFORTABLE_SWIPE__all_headers_hpp__ */

View File

@ -1,5 +1,5 @@
#ifndef __COMFORTABLE_SWIPE__service_buffer__ #ifndef __COMFORTABLE_SWIPE__driver__
#define __COMFORTABLE_SWIPE__service_buffer__ #define __COMFORTABLE_SWIPE__driver__
/* /*
Comfortable Swipe Comfortable Swipe
@ -21,25 +21,41 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <cstdio> // fgets_unlocked, stdin #include <cstdio> // fgets_unlocked, stdin
#include <iostream> // std::ios, std::cout, std::cin #include <iostream> // std::ios, std::cout, std::cin
#include "../index.hpp" #include "all_headers.hpp"
/** /**
* Starts the comfortable-swipe service by buffering libinput debug-events. * The main driver program.
*/ */
namespace comfortable_swipe::service namespace comfortable_swipe
{ {
void buffer() int driver()
{ {
// unsync for faster IO
std::ios::sync_with_stdio(false); std::ios::sync_with_stdio(false);
std::cin.tie(0); std::cin.tie(0);
std::cout.tie(0); std::cout.tie(0);
std::cout.flush(); std::cout.flush();
// read config file // read config file
auto config = comfortable_swipe::util::read_config_file(comfortable_swipe::util::conf_filename()); auto config = comfortable_swipe::util::read_config_file(
comfortable_swipe::util::conf_filename()
);
// initialize swipe gesture handler // initialize mouse hold gesture handler
comfortable_swipe::gesture::swipe_gesture swipe_gesture_handler // for now, this supports 3-finger and 4-finger hold
// Examples:
// hold3=move move mouse on 3 fingers
// hold3=button1 hold button 1 on 3 fingers
// hold4=button3 hold button 3 (right click) on 3 fingers
// hold3=ignore <do nothing>
comfortable_swipe::gesture::mouse_hold_gesture mouse_hold
(
config["hold3"].c_str(),
config["hold4"].c_str()
);
// initialize keyboard swipe gesture handler
comfortable_swipe::gesture::keyboard_swipe_gesture keyboard_swipe
( (
config.count("threshold") ? std::stof(config["threshold"]) : 0.0, config.count("threshold") ? std::stof(config["threshold"]) : 0.0,
config["left3"].c_str(), config["left3"].c_str(),
@ -58,10 +74,19 @@ namespace comfortable_swipe::service
// start reading lines from input one by one // start reading lines from input one by one
while (fgets_unlocked(line.data(), line.size(), stdin) != NULL) while (fgets_unlocked(line.data(), line.size(), stdin) != NULL)
{ {
// attempt to parse swipe gestures // prioritize mouse hold gesture first
swipe_gesture_handler.parse_line(line.data()); mouse_hold.parse_line(line.data());
// if mouse hold fails, try keyboard hold
if (!mouse_hold.is_mousedown())
{
// attempt to parse keyboard gestures
keyboard_swipe.parse_line(line.data());
}
} }
return 0;
} }
} }
#endif /* __COMFORTABLE_SWIPE__service_buffer__ */ #endif /* __COMFORTABLE_SWIPE__driver__ */

View File

@ -0,0 +1,195 @@
#ifndef __COMFORTABLE_SWIPE__gesture_keyboard_swipe_gesture__
#define __COMFORTABLE_SWIPE__gesture_keyboard_swipe_gesture__
/*
Comfortable Swipe
by Rico Tiongson
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <iostream> // std::cout, std::endl
#include "keyboard_swipe_gesture.h"
extern "C"
{
#include <xdo.h> // xdo, xdo_new, xdo_free,
// xdo_get_mouse_location
// CURRENT_WINDOW
}
namespace comfortable_swipe::gesture
{
/* STATICS DEFINITIONS */
const int keyboard_swipe_gesture::MSK_THREE_FINGERS = 0;
const int keyboard_swipe_gesture::MSK_FOUR_FINGERS = 1;
const int keyboard_swipe_gesture::MSK_NEGATIVE = 0;
const int keyboard_swipe_gesture::MSK_POSITIVE = 2;
const int keyboard_swipe_gesture::MSK_HORIZONTAL = 0;
const int keyboard_swipe_gesture::MSK_VERTICAL = 4;
const int keyboard_swipe_gesture::FRESH = -1;
const char * const keyboard_swipe_gesture::command_map[8] = {
"left3",
"left4",
"right3",
"right4",
"up3",
"up4",
"down3",
"down4"
};
/**
* Constructs a new keyboard-based swipe gesture, given configurations
* for certain swipe events. Here, we construct our definition based on
* the four directions (left, up, right, down) for 3-finger and 4-finger
* swipes. Note that the direction is based on the Australian natural
* scrolling direction (ie. left3 is natural movement of 3 fingers left).
*/
keyboard_swipe_gesture::keyboard_swipe_gesture
(
const float threshold,
const char* left3 /* 000 */,
const char* left4 /* 001 */,
const char* right3 /* 010 */,
const char* right4 /* 011 */,
const char* up3 /* 100 */,
const char* up4 /* 101 */,
const char* down3 /* 110 */,
const char* down4 /* 111 */
):
// construct superclass
comfortable_swipe::gesture::swipe_gesture(),
// compute square of threshold because we will use squared distances
threshold_squared(threshold*threshold),
// register our commands
commands(new const char*[8]{
left3, left4, right3, right4, up3, up4, down3, down4
})
{ }
/**
* Destructs this keyboard swipe gesture.
*/
keyboard_swipe_gesture::~keyboard_swipe_gesture()
{
delete[] commands;
}
/**
* Hook on begin of swipe gesture.
*/
void keyboard_swipe_gesture::begin()
{
// call superclass method
swipe_gesture::begin();
// assign previous gesture to FRESH
this->previous_gesture = keyboard_swipe_gesture::FRESH;
}
/**
* Hook on update of swipe gesture.
*/
void keyboard_swipe_gesture::update()
{
// call superclass method
swipe_gesture::update();
// scale threshold to 1/10 when gesture is not fresh
float scale =
this->previous_gesture == keyboard_swipe_gesture::FRESH
? 1.00f
: 0.01f; // square root of 1/10
// we are working with floating points which are not exact
// make sure we compare with a very small value (epsilon)
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;
// apply if strictly beyond threshold
if (distance_squared > beyond_threshold + EPSILON)
{
// we parse our mask based on the values obtained from the regex
int mask = 0;
if (this->fingers == 3)
mask |= keyboard_swipe_gesture::MSK_THREE_FINGERS;
else if (this->fingers == 4)
mask |= keyboard_swipe_gesture::MSK_FOUR_FINGERS;
const float absx = x >= 0 ? x : -x;
const float absy = y >= 0 ? y : -y;
if (absx > absy)
{
// gesture is horizontal
mask |= keyboard_swipe_gesture::MSK_HORIZONTAL;
if (x < 0)
mask |= keyboard_swipe_gesture::MSK_NEGATIVE;
else
mask |= keyboard_swipe_gesture::MSK_POSITIVE;
}
else /* std::abs(x) <= std::abs(y) */
{
// gesture is vertical
mask |= keyboard_swipe_gesture::MSK_VERTICAL;
if (y < 0)
mask |= keyboard_swipe_gesture::MSK_NEGATIVE;
else
mask |= keyboard_swipe_gesture::MSK_POSITIVE;
}
// send command on fresh OR opposite gesture
if (this->previous_gesture == keyboard_swipe_gesture::FRESH
|| this->previous_gesture == (mask ^ keyboard_swipe_gesture::MSK_POSITIVE))
{
this->do_keyboard_gesture(mask);
}
}
}
/**
* Apply the update given a mask.
*/
void keyboard_swipe_gesture::do_keyboard_gesture(int mask)
{
// perform our keyboard command with xdo_send_keysequence
const char * command = keyboard_swipe_gesture::commands[mask];
xdo_send_keysequence_window(this->xdo, CURRENTWINDOW, command, 0);
// reset our location variables
this->x = this->y = 0;
this->previous_gesture = mask;
// log our command name in stdout
const char * command_name = keyboard_swipe_gesture::command_map[mask];
std::cout << "SWIPE " << command_name << std::endl;
}
/**
* Hook on end of swipe gesture.
*/
void keyboard_swipe_gesture::end()
{
// call superclass method
swipe_gesture::end();
}
}
#endif /* __COMFORTABLE_SWIPE__gesture_keyboard_swipe_gesture__ */

View File

@ -1,5 +1,5 @@
#ifndef __COMFORTABLE_SWIPE__gesture_swipe_gesture_h__ #ifndef __COMFORTABLE_SWIPE__gesture_keyboard_swipe_gesture_h__
#define __COMFORTABLE_SWIPE__gesture_swipe_gesture_h__ #define __COMFORTABLE_SWIPE__gesture_keyboard_swipe_gesture_h__
/* /*
Comfortable Swipe Comfortable Swipe
@ -19,7 +19,7 @@ You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include "xdo_gesture.h" #include "swipe_gesture.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
@ -27,11 +27,11 @@ extern "C" {
namespace comfortable_swipe::gesture namespace comfortable_swipe::gesture
{ {
class swipe_gesture : protected xdo_gesture class keyboard_swipe_gesture : public swipe_gesture
{ {
public: public:
// constructor // constructor
swipe_gesture( keyboard_swipe_gesture(
const float threshold, const float threshold,
const char* left3 /* 000 */, const char* left3 /* 000 */,
const char* left4 /* 001 */, const char* left4 /* 001 */,
@ -43,43 +43,37 @@ namespace comfortable_swipe::gesture
const char* down4 /* 111 */ const char* down4 /* 111 */
); );
~swipe_gesture(); // destructor
virtual ~keyboard_swipe_gesture();
// fields for xdo // hooks that we override
int fingers; virtual void begin() override;
float dx, dy, udx, udy; virtual void update() override;
virtual void end() override;
void begin() override; // override this when keyboard gesture is to be performed
void update() override; virtual void do_keyboard_gesture(int mask);
void end() override;
bool parse_line(const char *) override;
protected: protected:
// location of mouse // stores square of threshold so we can compute faster
int screen_num, ix, iy; float threshold_squared;
// current location // stores previous gesture so we don't repeat action
float x, y, threshold_squared;
int previous_gesture; int previous_gesture;
// stores all command strings for xdo to execute
const char ** commands; const char ** commands;
// optimization flag for checking if GESTURE_SWIPE_BEGIN was dispatched
bool flag_swiping;
public: public:
// static constants // static enums we will use for gesture matching
static const int FRESH;
static const int MSK_THREE_FINGERS; static const int MSK_THREE_FINGERS;
static const int MSK_FOUR_FINGERS; static const int MSK_FOUR_FINGERS;
static const int MSK_NEGATIVE; static const int MSK_NEGATIVE;
static const int MSK_POSITIVE; static const int MSK_POSITIVE;
static const int MSK_HORIZONTAL; static const int MSK_HORIZONTAL;
static const int MSK_VERTICAL; static const int MSK_VERTICAL;
static const int FRESH;
static const char * const command_map[8]; static const char * const command_map[8];
// regex patterns
static const char* GESTURE_BEGIN_REGEX_PATTERN;
static const char* GESTURE_UPDATE_REGEX_PATTERN;
static const char* GESTURE_END_REGEX_PATTERN;
}; };
} }
@ -87,4 +81,4 @@ namespace comfortable_swipe::gesture
} }
#endif #endif
#endif /* __COMFORTABLE_SWIPE__gesture_swipe_gesture_h__ */ #endif /* __COMFORTABLE_SWIPE__gesture_keyboard_swipe_gesture_h__ */

View File

@ -0,0 +1,222 @@
#ifndef __COMFORTABLE_SWIPE__gesture_mouse_hold_gesture__
#define __COMFORTABLE_SWIPE__gesture_mouse_hold_gesture__
/*
Comfortable Swipe
by Rico Tiongson
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <iostream> // std::cout, std::endl
#include <cstdio> // std::sscanf
#include <cstring> // strncmp
#include "mouse_hold_gesture.h"
extern "C"
{
#include <xdo.h> // xdo, xdo_new, xdo_free,
// xdo_get_mouse_location
// CURRENT_WINDOW
}
namespace comfortable_swipe::gesture
{
enum {
MOUSE_NONE = -1,
MOUSE_MOVE = 0,
MOUSE_LEFT_CLICK = 1,
MOUSE_MIDDLE_CLICK = 2,
MOUSE_RIGHT_CLICK = 3,
MOUSE_WHEEL_UP = 4,
MOUSE_WHEEL_DOWN = 5,
MOUSE_SCROLL = 6,
MOUSE_SCROLL_REVERSE = 7
};
/**
* Constructs a new mouse gesture, given "hold3" and "hold4" configurations.
*/
mouse_hold_gesture::mouse_hold_gesture
(
const char* hold3,
const char* hold4
):
comfortable_swipe::gesture::swipe_gesture(),
button(MOUSE_NONE),
hold3(hold3),
hold4(hold4),
flag_mousedown(false)
{ }
/**
* Destructs this mouse swipe gesture.
*/
mouse_hold_gesture::~mouse_hold_gesture()
{ }
/**
* Run mousedown command on hold input.
*/
void mouse_hold_gesture::do_mousedown(const char * mouseinput)
{
const int button = this->button = this->parse_mouse_button(mouseinput);
if (button != MOUSE_NONE)
{
// eg. MOUSE DOWN hold3 mouse1
std::printf("MOUSE DOWN hold%d %s\n", this->fingers, mouseinput);
if (MOUSE_LEFT_CLICK <= button && button <= MOUSE_RIGHT_CLICK)
{
// send mouse down on associated button
xdo_mouse_down(this->xdo, CURRENTWINDOW, button);
}
this->flag_mousedown = true;
}
}
/**
* Run mouseup command on hold output.
*/
void mouse_hold_gesture::do_mouseup(const char * mouseinput)
{
const int button = this->button = this->parse_mouse_button(mouseinput);
if (button != MOUSE_NONE)
{
std::printf("MOUSE UP hold%d %s\n", this->fingers, mouseinput);
if (MOUSE_LEFT_CLICK <= button && button <= MOUSE_RIGHT_CLICK)
{
// send mouse up on associated button
xdo_mouse_up(this->xdo, CURRENTWINDOW, button);
}
this->flag_mousedown = false;
}
}
/**
* Utility method to parse mouse number from input.
* Returns -1 on failure.
*/
int mouse_hold_gesture::parse_mouse_button(const char * input) const
{
// just move without holding button down
if (std::strcmp(input, "move") == 0)
return MOUSE_MOVE;
if (std::strcmp(input, "scroll") == 0)
return MOUSE_SCROLL;
if (std::strcmp(input, "scroll_reverse") == 0)
return MOUSE_SCROLL_REVERSE;
// get button number
int button;
if (std::sscanf(input, "button%d", &button) == 1)
{
if (1 <= button && button <= 6)
{
return button;
}
}
return MOUSE_NONE;
}
/**
* Hook on begin of mouse swipe gesture.
*/
void mouse_hold_gesture::begin()
{
// call superclass method
swipe_gesture::begin();
// dispatch mouse down event
if (this->fingers == 3)
{
this->do_mousedown(this->hold3);
}
else if (this->fingers == 4)
{
this->do_mousedown(this->hold4);
}
}
/**
* Hook on end of mouse swipe gesture.
*/
void mouse_hold_gesture::update()
{
// call superclass method
swipe_gesture::update();
if (this->is_mousedown())
{
if (0 <= this->button && this->button <= 3)
{
// drag mouse with pointer during update
xdo_move_mouse_relative(
this->xdo,
this->udx,
this->udy
);
}
else if (this->button == MOUSE_SCROLL || this->button == MOUSE_SCROLL_REVERSE)
{
// perform naive scroll depending on vertical direction
int wheel = MOUSE_WHEEL_DOWN;
if ((this->udy > 0) == (this->button == MOUSE_SCROLL))
wheel = MOUSE_WHEEL_UP;
// click wheel on update (note: this is not precise)
xdo_mouse_down(this->xdo, CURRENTWINDOW, wheel);
xdo_mouse_up(this->xdo, CURRENTWINDOW, wheel);
}
else if (this->button == MOUSE_WHEEL_UP || this->button == MOUSE_WHEEL_DOWN)
{
// click wheel button on 4 or 5
xdo_mouse_down(this->xdo, CURRENTWINDOW, this->button);
xdo_mouse_up(this->xdo, CURRENTWINDOW, this->button);
}
}
}
/**
* Hook on end of swipe gesture.
*/
void mouse_hold_gesture::end()
{
if (this->is_mousedown())
{
if (this->fingers == 3)
{
this->do_mouseup(this->hold3);
}
else if (this->fingers == 4)
{
this->do_mouseup(this->hold4);
}
}
// call superclass method
swipe_gesture::end();
}
/**
* Utility method to check if mouse is current held.
*/
bool mouse_hold_gesture::is_mousedown() const
{
return this->flag_mousedown;
}
}
#endif /* __COMFORTABLE_SWIPE__gesture_mouse_hold_gesture__ */

View File

@ -0,0 +1,71 @@
#ifndef __COMFORTABLE_SWIPE__gesture_mouse_hold_gesture_h__
#define __COMFORTABLE_SWIPE__gesture_mouse_hold_gesture_h__
/*
Comfortable Swipe
by Rico Tiongson
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "swipe_gesture.h"
#ifdef __cplusplus
extern "C" {
#endif
namespace comfortable_swipe::gesture
{
class mouse_hold_gesture : public swipe_gesture
{
public:
// constructor
mouse_hold_gesture(
const char* hold3, // 3 finger mouse down
const char* hold4 // 4 finger mouse down
);
// the button being clicked
int button;
virtual ~mouse_hold_gesture();
// override begin and end for mousedown
virtual void begin() override;
virtual void update() override;
virtual void end() override;
// provide our own mouse functions
virtual void do_mousedown(const char*);
virtual void do_mouseup(const char*);
virtual bool is_mousedown() const;
// utility method to parse mouse input given config characters
virtual int parse_mouse_button(const char*) const;
protected:
// command holders
const char * hold3;
const char * hold4;
// flag we can use to check if mouse is down
bool flag_mousedown;
};
}
#ifdef __cplusplus
}
#endif
#endif /* __COMFORTABLE_SWIPE__gesture_mouse_hold_gesture_h__ */

View File

@ -34,100 +34,52 @@ extern "C"
namespace comfortable_swipe::gesture namespace comfortable_swipe::gesture
{ {
/** /**
* Constructs a new swipe gesture, given configurations for certain swipe events. * Constructs a new fresh swipe gesture container.
*/ */
swipe_gesture::swipe_gesture swipe_gesture::swipe_gesture
( ():
const float threshold, // construct our superclass
const char* left3 /* 000 */,
const char* left4 /* 001 */,
const char* right3 /* 010 */,
const char* right4 /* 011 */,
const char* up3 /* 100 */,
const char* up4 /* 101 */,
const char* down3 /* 110 */,
const char* down4 /* 111 */
):
comfortable_swipe::gesture::xdo_gesture(), comfortable_swipe::gesture::xdo_gesture(),
threshold_squared(threshold*threshold),
commands(new const char*[8]{left3, left4, right3, right4, up3, up4, down3, down4}),
flag_swiping(false) flag_swiping(false)
{ {
// improve responsiveness of first gesture by pre-empting xdotool runtime // improve responsiveness of first gesture by pre-empting xdotool
xdo_get_mouse_location(this->xdo, &this->ix, &this->iy, &this->screen_num); xdo_get_mouse_location(this->xdo, &this->ix, &this->iy,
&this->screen_num);
} }
/** /**
* Destructs this swipe gesture. * Destructs this swipe gesture.
*/ */
swipe_gesture::~swipe_gesture() swipe_gesture::~swipe_gesture()
{ { }
delete[] commands;
}
/** /**
* Hook on begin of swipe gesture. * Hook on begin of swipe gesture (you can override this).
*/ */
void swipe_gesture::begin() void swipe_gesture::begin()
{ {
xdo_get_mouse_location(this->xdo, &this->ix, &this->iy, &this->screen_num); // save current screen location for gestured mouse movement
this->previous_gesture = swipe_gesture::FRESH; xdo_get_mouse_location(this->xdo, &this->ix, &this->iy,
&this->screen_num);
this->x = 0; this->x = 0;
this->y = 0; this->y = 0;
this->ux = 0;
this->uy = 0;
} }
/** /**
* Hook on update of swipe gesture. * Hook on update of swipe gesture (you can override this).
*/ */
void swipe_gesture::update() void swipe_gesture::update()
{ {
this->x += this->dx; this->x += this->dx;
this->y += this->dy; this->y += this->dy;
// scale threshold to 1/10 when gesture is not fresh this->ux += this->udx;
float scale = this->previous_gesture == swipe_gesture::FRESH this->uy += this->udy;
? 1.00f
: 0.01f; // square root of 1/10
static const float EPSILON = 1e-6f;
if (this->x * this->x + this->y * this->y
> this->threshold_squared * scale + EPSILON)
{
int mask = 0;
if (this->fingers == 3) mask |= swipe_gesture::MSK_THREE_FINGERS;
else if (this->fingers == 4) mask |= swipe_gesture::MSK_FOUR_FINGERS;
const float absx = x >= 0 ? x : -x;
const float absy = y >= 0 ? y : -y;
if (absx > absy)
{ // horizontal
mask |= swipe_gesture::MSK_HORIZONTAL;
if (x < 0)
mask |= swipe_gesture::MSK_NEGATIVE;
else
mask |= swipe_gesture::MSK_POSITIVE;
}
else /* std::abs(x) <= std::abs(y) */
{ // vertical
mask |= swipe_gesture::MSK_VERTICAL;
if (y < 0)
mask |= swipe_gesture::MSK_NEGATIVE;
else
mask |= swipe_gesture::MSK_POSITIVE;
}
// send command on fresh OR opposite gesture
if (this->previous_gesture == swipe_gesture::FRESH
|| this->previous_gesture == (mask ^ swipe_gesture::MSK_POSITIVE))
{
xdo_send_keysequence_window(this->xdo, CURRENTWINDOW, swipe_gesture::commands[mask], 0);
this->x = this->y = 0;
this->previous_gesture = mask;
std::cout << "SWIPE " << swipe_gesture::command_map[mask] << std::endl;
}
}
} }
/** /**
* Hook on end of swipe gesture. * Hook on end of swipe gesture (you can override this).
*/ */
void swipe_gesture::end() void swipe_gesture::end()
{ } { }
@ -141,10 +93,11 @@ namespace comfortable_swipe::gesture
bool swipe_gesture::parse_line(const char * line) bool swipe_gesture::parse_line(const char * line)
{ {
// prepare regex matchers (will only load at most once) // prepare regex matchers statically (will only load at most once)
static const std::regex gesture_swipe_begin(swipe_gesture::GESTURE_BEGIN_REGEX_PATTERN); static const std::regex
static const std::regex gesture_swipe_update(swipe_gesture::GESTURE_UPDATE_REGEX_PATTERN); gesture_swipe_begin(swipe_gesture::GESTURE_BEGIN_REGEX_PATTERN),
static const std::regex gesture_swipe_end(swipe_gesture::GESTURE_END_REGEX_PATTERN); gesture_swipe_update(swipe_gesture::GESTURE_UPDATE_REGEX_PATTERN),
gesture_swipe_end(swipe_gesture::GESTURE_END_REGEX_PATTERN);
// prepare holder for regex matches // prepare holder for regex matches
static std::cmatch matches; static std::cmatch matches;
@ -191,25 +144,6 @@ namespace comfortable_swipe::gesture
return false; return false;
} }
/* STATICS DEFINITIONS */
const int swipe_gesture::MSK_THREE_FINGERS = 0;
const int swipe_gesture::MSK_FOUR_FINGERS = 1;
const int swipe_gesture::MSK_NEGATIVE = 0;
const int swipe_gesture::MSK_POSITIVE = 2;
const int swipe_gesture::MSK_HORIZONTAL = 0;
const int swipe_gesture::MSK_VERTICAL = 4;
const int swipe_gesture::FRESH = -1;
const char * const swipe_gesture::command_map[8] = {
"left3",
"left4",
"right3",
"right4",
"up3",
"up4",
"down3",
"down4"
};
} }
#endif /* __COMFORTABLE_SWIPE__gesture_swipe_gesture__ */ #endif /* __COMFORTABLE_SWIPE__gesture_swipe_gesture__ */

View File

@ -0,0 +1,73 @@
#ifndef __COMFORTABLE_SWIPE__gesture_swipe_gesture_h__
#define __COMFORTABLE_SWIPE__gesture_swipe_gesture_h__
/*
Comfortable Swipe
by Rico Tiongson
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "xdo_gesture.h"
#ifdef __cplusplus
extern "C" {
#endif
namespace comfortable_swipe::gesture
{
class swipe_gesture : public xdo_gesture
{
public:
// constructor
swipe_gesture();
// destructor
virtual ~swipe_gesture();
// fields for xdo
int fingers;
// normal values (for touchpad mapping)
float x, y, dx, dy;
// unaccelerated values (for screen mapping)
float ux, uy, udx, udy;
// hooks that we can override (mark as virtual)
virtual void begin();
virtual void update();
virtual void end();
virtual bool parse_line(const char *);
protected:
// location of mouse
int screen_num, ix, iy;
// optimization flag for checking if GESTURE_SWIPE_BEGIN was dispatched
bool flag_swiping;
public:
// regex patterns
static const char* GESTURE_BEGIN_REGEX_PATTERN;
static const char* GESTURE_UPDATE_REGEX_PATTERN;
static const char* GESTURE_END_REGEX_PATTERN;
};
}
#ifdef __cplusplus
}
#endif
#endif /* __COMFORTABLE_SWIPE__gesture_swipe_gesture_h__ */

View File

@ -39,13 +39,7 @@ namespace comfortable_swipe
public: public:
xdo_gesture(); xdo_gesture();
~xdo_gesture(); virtual ~xdo_gesture();
// hooks
virtual void begin() = 0;
virtual void update() = 0;
virtual void end() = 0;
virtual bool parse_line(const char *) = 0;
}; };
} }
} }

View File

@ -19,15 +19,17 @@ You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include "index.hpp" #include "all_headers.hpp"
/** /**
* Make sure to include all implementation (.cpp) files below to be ready for export. * Add all cpp files below to be ready for export.
*/ */
#include "gesture/xdo_gesture.cpp" #include "gesture/xdo_gesture.cpp"
#include "gesture/swipe_gesture.cpp" #include "gesture/swipe_gesture.cpp"
#include "gesture/swipe_gesture.regex.cpp" #include "gesture/swipe_gesture.regex.cpp"
#include "gesture/keyboard_swipe_gesture.cpp"
#include "gesture/mouse_hold_gesture.cpp"
#include "service/autostart.cpp" #include "service/autostart.cpp"
#include "service/buffer.cpp" #include "service/buffer.cpp"
#include "service/config.cpp" #include "service/config.cpp"
@ -40,5 +42,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "util/autostart_filename.cpp" #include "util/autostart_filename.cpp"
#include "util/conf_filename.cpp" #include "util/conf_filename.cpp"
#include "util/read_config_file.cpp" #include "util/read_config_file.cpp"
#include "driver.cpp"
#endif /* __COMFORTABLE_SWIPE__ */ #endif /* __COMFORTABLE_SWIPE__ */

View File

@ -24,7 +24,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <string> // std::string #include <string> // std::string
#include <cstdio> // std::remove #include <cstdio> // std::remove
#include <cstdlib> // std::system #include <cstdlib> // std::system
#include "../index.hpp" #include "../all_headers.hpp"
namespace comfortable_swipe::service namespace comfortable_swipe::service
{ {
@ -45,7 +45,7 @@ namespace comfortable_swipe::service
<< std::endl; << std::endl;
else else
std::cout << "Autostart switched off" << std::endl; std::cout << "Autostart switched off" << std::endl;
} }
else { else {
// file not found, create it // file not found, create it
int result = std::system(("mkdir -p $(dirname " + path + ")").data()); int result = std::system(("mkdir -p $(dirname " + path + ")").data());

View File

@ -0,0 +1,36 @@
#ifndef __COMFORTABLE_SWIPE__service_buffer__
#define __COMFORTABLE_SWIPE__service_buffer__
/*
Comfortable Swipe
by Rico Tiongson
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <cstdlib> // std::exit
#include "../all_headers.hpp"
/**
* Starts the comfortable-swipe service by buffering libinput debug-events.
*/
namespace comfortable_swipe::service
{
void buffer()
{
std::exit(comfortable_swipe::driver());
}
}
#endif /* __COMFORTABLE_SWIPE__service_buffer__ */

View File

@ -19,8 +19,8 @@ You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include "../index.hpp"
#include <cstdio> // std::puts #include <cstdio> // std::puts
#include "../all_headers.hpp"
namespace comfortable_swipe::service namespace comfortable_swipe::service
{ {

View File

@ -20,7 +20,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include <cstdio> // std::puts, std::printf #include <cstdio> // std::puts, std::printf
#include "../index.hpp" #include "../all_headers.hpp"
namespace comfortable_swipe::service namespace comfortable_swipe::service
{ {

View File

@ -19,7 +19,9 @@ You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include "../index.hpp"
#include <cstdio> // freopen, stdout
#include "../all_headers.hpp"
namespace comfortable_swipe::service namespace comfortable_swipe::service
{ {
@ -28,7 +30,12 @@ namespace comfortable_swipe::service
*/ */
void restart() void restart()
{ {
// dont show stdout on stop
freopen("/dev/null", "a", stdout);
comfortable_swipe::service::stop(); comfortable_swipe::service::stop();
// show back on start
freopen ("/dev/tty", "a", stdout);
comfortable_swipe::service::start(); comfortable_swipe::service::start();
} }
} }

View File

@ -19,8 +19,8 @@ You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include "../index.hpp"
#include <cstdlib> // std::system #include <cstdlib> // std::system
#include "../all_headers.hpp"
namespace comfortable_swipe::service namespace comfortable_swipe::service
{ {

View File

@ -19,7 +19,6 @@ You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include "../index.hpp"
#include <stdexcept> // std::runtime_error #include <stdexcept> // std::runtime_error
#include <unistd.h> // popen, pclose, getpid, access, F_OK #include <unistd.h> // popen, pclose, getpid, access, F_OK
#include <memory> // std::unique_ptr #include <memory> // std::unique_ptr
@ -27,6 +26,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <cstdlib> // std::atoi #include <cstdlib> // std::atoi
#include <cstdio> // FILE, std::feof, std::fgets, std::printf #include <cstdio> // FILE, std::feof, std::fgets, std::printf
#include <regex> // std::cmatch, std::regex, std::regex_match #include <regex> // std::cmatch, std::regex, std::regex_match
#include "../all_headers.hpp"
namespace comfortable_swipe::service namespace comfortable_swipe::service
{ {
@ -73,7 +73,7 @@ namespace comfortable_swipe::service
std::printf(" %9s is OFF\n", "threshold"); std::printf(" %9s is OFF\n", "threshold");
// print swipe commands // print swipe commands
for (auto &command : comfortable_swipe::gesture::swipe_gesture::command_map) for (auto &command : comfortable_swipe::gesture::keyboard_swipe_gesture::command_map)
{ {
if (config.count(command) > 0) if (config.count(command) > 0)
std::printf(" %9s is OK (%s)\n", command, config[command].data()); std::printf(" %9s is OK (%s)\n", command, config[command].data());

View File

@ -1,9 +1,6 @@
#ifndef __COMFORTABLE_SWIPE__service_stop__ #ifndef __COMFORTABLE_SWIPE__service_stop__
#define __COMFORTABLE_SWIPE__service_stop__ #define __COMFORTABLE_SWIPE__service_stop__
#include <cstdio> // std::FILE, std::feof, std::fgets
#include <cstdlib> // std::atoi, std::system
#include <string> // std::string, std::to_string
/* /*
Comfortable Swipe Comfortable Swipe
by Rico Tiongson by Rico Tiongson
@ -26,8 +23,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <unistd.h> // popen, pclose, getpid #include <unistd.h> // popen, pclose, getpid
#include <memory> // std::unique_ptr #include <memory> // std::unique_ptr
#include <array> // std::array #include <array> // std::array
#include <cstdlib> // std::atoi #include <cstdio> // std::FILE, std::feof, std::fgets
#include <cstdio> // FILE, std::feof, std::fgets #include <cstdlib> // std::atoi, std::system
#include <string> // std::string, std::to_string
namespace comfortable_swipe::service namespace comfortable_swipe::service
{ {
@ -39,14 +37,14 @@ namespace comfortable_swipe::service
// read all service names from process (pgrep) // read all service names from process (pgrep)
std::array<char, 128> buffer; std::array<char, 128> buffer;
std::unique_ptr<FILE, decltype(&pclose)> pipe(popen("pgrep -f comfortable-swipe", "r"), pclose); std::unique_ptr<FILE, decltype(&pclose)> pipe(popen("pgrep -f \"$(which comfortable-swipe)\"", "r"), pclose);
// make sure pipe exists // make sure pipe exists
if (!pipe) if (!pipe)
throw std::runtime_error("stop command failed"); throw std::runtime_error("stop command failed");
// buffer what to kill // buffer what to kill
std::string kill = "kill"; std::string kill = "";
// read until end of line // read until end of line
while (!std::feof(pipe.get())) while (!std::feof(pipe.get()))
@ -63,7 +61,15 @@ namespace comfortable_swipe::service
} }
// run "kill {pid1} {pid2}..." // run "kill {pid1} {pid2}..."
(void) std::system(kill.data()); if (kill.length())
{
std::printf("Stopped%s\n", kill.c_str());
(void) std::system(("kill" + kill).c_str());
}
else
{
std::printf("No program to stop\n");
}
} }
} }

View File

@ -19,7 +19,7 @@ You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include "../index.hpp" #include "../all_headers.hpp"
namespace comfortable_swipe::util namespace comfortable_swipe::util
{ {

View File

@ -19,9 +19,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <ios> // std::ios #include <ios> // std::ios
#include <iostream> // std::cin, std::cout, std::cerr #include <iostream> // std::cin, std::cout, std::cerr
#include <string> // std::string #include <string> // std::string
#include "lib/comfortable_swipe" #include "comfortable_swipe/lib"
/* MAIN DRIVER FUNCTION */ /* Command-line function. */
int main(int argc, char** args) int main(int argc, char** args)
{ {

9
cpp.compile.sh Executable file
View File

@ -0,0 +1,9 @@
#!/bin/bash
dir="$(dirname $0)"
version="$(cat "$dir/VERSION" | tr -d '[:space:]')"
exec g++ $@ \
-std=c++11 \
-O2 -lxdo -Wno-unused-result \
-DCOMFORTABLE_SWIPE_VERSION="\"$version\""

View File

@ -6,19 +6,6 @@
# Refer to https://www.linux.org/threads/xdotool-keyboard.10528/ for a list of # Refer to https://www.linux.org/threads/xdotool-keyboard.10528/ for a list of
# keycodes you can use. # keycodes you can use.
#################
# MISCELLANEOUS #
#################
# Threshold
# 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)
#
# Default: threshold = 0.0
threshold = 0.0
############################# #############################
# THREE / FOUR FINGER SWIPE # # THREE / FOUR FINGER SWIPE #
############################# #############################
@ -62,3 +49,32 @@ down3 = ctrl+alt+Up
# The default shortcut is moving current window to the above workspace. # The default shortcut is moving current window to the above workspace.
# Default: ctrl+alt+shift+Up # Default: ctrl+alt+shift+Up
down4 = ctrl+alt+shift+Up down4 = ctrl+alt+shift+Up
#################
# MISCELLANEOUS #
#################
# Threshold
# Tweak this value depending on the sensitivity of your mousepad to perform
# gestures. A higher value means less sensitive (Sky is the limit! Can be as
# large as 1000.0).
# Default: threshold = 0.0
threshold = 0.0
#############################
# Experimental: MOUSE HOLD #
#############################
# (1: left click, 2: middle click, 3: right click, 4: wheel up, 5: wheel down)
# You can set mouse buttons to hold
# hold3 = button1
# hold3 = button2
# hold3 = button3
# Or you can just let the mouse move with the cursor
# hold3 = move
# Use wheel scroll (experimental)
# hold4 = scroll
# hold4 = scroll_reverse

View File

@ -1,11 +1,14 @@
#!/bin/bash #!/bin/bash
set -e
function install { function install {
# prefer running as root # prefer running as root
local dir="$(dirname $0)" local dir="$(dirname "$0")"
local program=comfortable-swipe local program=comfortable-swipe
local program_exe=/usr/local/bin/$program local program_exe=/usr/local/bin/$program
local compile_command="$dir/$program.compile.sh" local compile_command="$dir/cpp.compile.sh"
local compile_target="$dir/command_line.cpp"
local conf_path=/usr/local/share/$program/$program.conf local conf_path=/usr/local/share/$program/$program.conf
local dconf_path="$dir/defaults.conf" local dconf_path="$dir/defaults.conf"
local old_conf_path="${XDG_CONFIG_HOME:-$HOME/.config}/$program.conf" local old_conf_path="${XDG_CONFIG_HOME:-$HOME/.config}/$program.conf"
@ -70,7 +73,7 @@ function install {
fi fi
# compile library # compile library
sudo "$compile_command" "$program_exe" || abort sudo "$compile_command" "$compile_target" -o "$program_exe" || abort
# add permissions to input group (defer) # add permissions to input group (defer)
# GROUP=$(ls -l /dev/input/event* | awk '{print $4}' | head --line=1) || abort # GROUP=$(ls -l /dev/input/event* | awk '{print $4}' | head --line=1) || abort

View File

@ -1,6 +1,24 @@
#!/bin/sh #!/bin/bash
DIR=$(dirname $0) set -e
g++ -std=c++11 -O2 $DIR/test_regex.cpp -lxdo -o test.out || exec "Test aborted"
./test.out || rm test.out DIR="$(dirname "$0")"
rm test.out
# just call abort on error
tempout="$(mktemp)"
abort () {
rm "$tempout"
echo "Test aborted"
exit 1
}
# run all shell files in this directory
for sh in "$DIR/test_"*.sh; do
/bin/bash "$sh" || abort
done
# run all cpp files in this directory
for cpp in "$DIR/test_"*.cpp; do
g++ -std=c++11 -O2 "$cpp" -lxdo -o "$tempout" || abort
"$tempout" || abort
done

32
tests/test_compiler.sh Executable file
View File

@ -0,0 +1,32 @@
#!/bin/bash
set -ex
DIR="$(dirname "$0")"
root="$(dirname "$DIR")"
compiler="$root/cpp.compile.sh"
command_line="$root/command_line.cpp"
module="$root/comfortable_swipe"
# just call abort on error
tempout="$(mktemp)"
abort () {
rm "$tempout"
echo "Test aborted"
exit 1
}
# try to compile every cpp/hpp file in module
# header files first
# then compile cpp files
# finally, compile command line
shopt -s nullglob
for cpp in \
"$module"/**/*.h \
"$module"/**/*.hpp \
"$module"/**/*.cpp \
"$module"/lib \
"$command_line"
do
"$compiler" -c "$cpp" -o "$tempout" || abort
done

4
tests/test_regex.cpp Normal file → Executable file
View File

@ -2,8 +2,8 @@
#include <cassert> #include <cassert>
#include <regex> #include <regex>
#include <string> #include <string>
#include "../lib/gesture/swipe_gesture.h" #include "../comfortable_swipe/gesture/swipe_gesture.h"
#include "../lib/gesture/swipe_gesture.regex.cpp" #include "../comfortable_swipe/gesture/swipe_gesture.regex.cpp"
/* /*
Comfortable Swipe Comfortable Swipe

View File

@ -1,7 +1,8 @@
#!/bin/bash #!/bin/bash
echo "Uninstalling..." echo "Uninstalling..."
rm ${XDG_CONFIG_HOME:-$HOME/.config}/autostart/comfortable-swipe.desktop 2> /dev/null rm "${XDG_CONFIG_HOME:-$HOME/.config}/autostart/comfortable-swipe.desktop" 2> /dev/null
comfortable-swipe stop 2> /dev/null comfortable-swipe stop 2> /dev/null
rm $HOME/.local/bin/comfortable-swipe 2> /dev/null # compat rm "$HOME/.local/bin/comfortable-swipe" 2> /dev/null # compat
sudo rm /usr/local/bin/comfortable-swipe 2> /dev/null sudo rm /usr/local/bin/comfortable-swipe 2> /dev/null
echo "Successfully uninstalled comfortable-swipe" echo "Successfully uninstalled comfortable-swipe"