* Use a requirements.txt

* Add initial travis configuration

* Attempt fix travis configuration

* Attempt fix g++ error

* Bugfix missing path dir on autostart

* Attempt install build-essential instead of g++

* Add missing psutil from requirements

* Modify README

* Attempt fix build errors in travis

* Update README

* Add simple build badges
This commit is contained in:
Rico Tiongson 2019-03-08 19:57:10 +08:00 committed by GitHub
parent adcb3d5e02
commit 044e215d97
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
21 changed files with 709 additions and 593 deletions

25
.travis.yml Normal file
View File

@ -0,0 +1,25 @@
dist: xenial
language: python
sudo: required
python:
- 2.7
- 3.5
- 3.6
- 3.7
- 3.8-dev
addons:
apt:
update: true
sources:
- ubuntu-toolchain-r-test
packages:
- libxdo-dev
- libinput-tools
- g++-7
env:
CC: gcc-7
CXX: g++-7
install:
- pip install .
script:
- python setup.py test

172
README.md
View File

@ -1,30 +1,62 @@
# Comfortable Swipe (Ubuntu) # Comfortable Swipe (Debian/Ubuntu)
[![License: GPL v3](https://img.shields.io/badge/License-GPL%20v3-blue.svg)](https://www.gnu.org/licenses/gpl-3.0)
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-swipe: version](https://img.shields.io/github/tag-date/Hikari9/comfortable-swipe.svg?color=informational&label=comfortable-swipe)](https://github.com/Hikari9/comfortable-swipe/releases)
[![build: master](https://img.shields.io/travis/Hikari9/comfortable-swipe/master.svg?label=master)](https://github.com/Hikari9/comfortable-swipe/commits/master)
[![build: develop](https://img.shields.io/travis/Hikari9/comfortable-swipe/develop.svg?label=develop)](https://github.com/Hikari9/comfortable-swipe/commits/develop)
[![License: GPL v3](https://img.shields.io/badge/License-GPL%20v3-orange.svg)](https://www.gnu.org/licenses/gpl-3.0)
Comfortable, seamless, and fast 3-finger (and 4-finger) touchpad swipe gestures. Tested in Ubuntu 14.04 LTS and beyond, for Unity, GNOME, and KDE desktop environments.
> **Note**: May work for other Linux distros that support `libinput` and `libxdo` (untested).
## Installation ## Installation
1. Install Python3, libinput, and g++ 1. Update and install essential tools and libraries
```bash ```bash
sudo apt-get install git python3-dev libinput-tools libxdo-dev sudo apt update && sudo apt install git g++-7 python3-pip libinput-tools libxdo-dev
``` ```
2. Clone this repository 2. Install `comfortable-swipe` for your user
```bash ```bash
git clone https://github.com/Hikari9/comfortable-swipe-ubuntu.git pip3 install --user git+https://github.com/Hikari9/comfortable-swipe
cd comfortable-swipe-ubuntu
``` ```
3. Install 3. You can check status with `comfortable-swipe status`
```bash ```bash
bash install $> comfortable-swipe status
usr/local/share/comfortable-swipe/comfortable-swipe.conf
threshold = 0.0
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
autostart is ON
comfortable-swipe program is STOPPED
``` ```
4. You may delete the downloaded `comfortable-swipe-ubuntu` folder after installation. 3. You can list down all commands with `comfortable-swipe` or `comfortable-swipe help`
```bash
$> comfortable-swipe
comfortable-swipe [start|stop|restart|autostart|buffer|help|config|debug|status]
start - starts 3/4-finger gesture service
stop - stops 3/4-finger gesture service
restart - stops then starts 3/4-finger gesture service
autostart - automatically run on startup (toggleable)
buffer - parses output of libinput debug-events
help - shows the help dialog
config - locates the config file
debug - logs raw output from input events taken from libinput
status - checks status of program and autostart
```
## How to Run ## How to Run
@ -33,27 +65,84 @@ Comfortable, seamless, and fast 3-finger (and 4-finger) touchpad swipe gestures
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 2. ***Important***: After inputing your `sudo` password, log out then log back in
3. Run 3. By default, comfortable-swipe should be running. Otherwise, run:
``` ```bash
comfortable-swipe start comfortable-swipe start
``` ```
4. _Optional_: Automatically run on startup You can see if gestures work correctly if you see `SWIPE xxx` in the output:
```bash
$> comfortable-swipe start
SWIPE left3
SWIPE right3
...
``` ```
comfortable-swipe autostart
## How to Upgrade
```bash
pip3 install -U --user git+https://github.com/Hikari9/comfortable-swipe
```
## Uninstall
```bash
# Uncomment below to COMPLETELY remove configurations (not recommended)
# rm $(comfortable-swipe config)
pip3 uninstall comfortable-swipe
```
## Other Commands
1. `comfortable-swipe config` - outputs location of configuration file
```bash
$> comfortable-swipe config
/usr/local/share/comfortable-swipe/comfortable-swipe.conf
``` ```
5. Check the status of your application by running
2. `comfortable-swipe autostart` - Toggles autostart
```bash
$> comfortable-swipe autostart
Autostart switched off
``` ```
comfortable-swipe status
3. `comfortable-swipe debug` - Debugs input (this is an unbuffered alias of `libinput debug-events`)
```bash
$> comfortable-swipe debug
...
-event9 DEVICE_ADDED TouchPad seat0 default group7 cap:pg size 70x50mm tap(dl off) left scroll-nat scroll-2fg-edge click-buttonareas-clickfinger dwt-on
...
event9 GESTURE_SWIPE_BEGIN +2.03s 3
event9 GESTURE_SWIPE_UPDATE +2.03s 3 -9.95/ 2.64 (-26.90/ 7.12 unaccelerated)
event9 GESTURE_SWIPE_UPDATE +2.03s 3 -10.44/ 3.19 (-28.22/ 8.62 unaccelerated)
event9 GESTURE_SWIPE_UPDATE +2.04s 3 -9.71/ 2.64 (-26.25/ 7.12 unaccelerated)
event9 GESTURE_SWIPE_UPDATE +2.05s 3 -8.98/ 2.64 (-24.28/ 7.12 unaccelerated)
event9 GESTURE_SWIPE_UPDATE +2.06s 3 -7.40/ 2.36 (-20.01/ 6.37 unaccelerated)
event9 GESTURE_SWIPE_UPDATE +2.06s 3 -6.31/ 2.50 (-17.06/ 6.75 unaccelerated)
event9 GESTURE_SWIPE_UPDATE +2.07s 3 -5.34/ 1.80 (-14.44/ 4.87 unaccelerated)
event9 GESTURE_SWIPE_UPDATE +2.08s 3 -4.61/ 2.08 (-12.47/ 5.62 unaccelerated)
event9 GESTURE_SWIPE_UPDATE +2.09s 3 -4.49/ 1.53 (-12.14/ 4.12 unaccelerated)
event9 GESTURE_SWIPE_UPDATE +2.09s 3 -4.01/ 1.25 (-10.83/ 3.37 unaccelerated)
event9 GESTURE_SWIPE_UPDATE +2.10s 3 -4.13/ 0.42 (-11.15/ 1.12 unaccelerated)
event9 GESTURE_SWIPE_END +2.11s 3
...
``` ```
If you can see `GESTURE_SWIPE_XXX` in your output, that means your touchpad supports multi-touch swipe gestures.
## Configurations ## Configurations
Comfortable swipe makes use of keyboard shortcuts for configurations. Edit by running Comfortable swipe makes use of keyboard shortcuts for configurations. Edit by running
```
nano $(comfortable-swipe config) ```bash
gedit $(comfortable-swipe config)
``` ```
Make sure to run after making changes: Make sure to restart after making changes:
``` ```bash
comfortable-swipe restart comfortable-swipe restart
``` ```
@ -85,45 +174,6 @@ 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.
## Debugging
You can check your touchpad driver by running
```bash
comfortable-swipe debug
```
This is an alias of `libinput debug-events`. This logs all gestures you make on your touchpad, along with other input-based events that can be captured by libinput.
A working swipe gesture will show the following:
```bash
$ comfortable-swipe debug
...
-event9 DEVICE_ADDED TouchPad seat0 default group7 cap:pg size 70x50mm tap(dl off) left scroll-nat scroll-2fg-edge click-buttonareas-clickfinger dwt-on
...
event9 GESTURE_SWIPE_BEGIN +2.03s 3
event9 GESTURE_SWIPE_UPDATE +2.03s 3 -9.95/ 2.64 (-26.90/ 7.12 unaccelerated)
event9 GESTURE_SWIPE_UPDATE +2.03s 3 -10.44/ 3.19 (-28.22/ 8.62 unaccelerated)
event9 GESTURE_SWIPE_UPDATE +2.04s 3 -9.71/ 2.64 (-26.25/ 7.12 unaccelerated)
event9 GESTURE_SWIPE_UPDATE +2.05s 3 -8.98/ 2.64 (-24.28/ 7.12 unaccelerated)
event9 GESTURE_SWIPE_UPDATE +2.06s 3 -7.40/ 2.36 (-20.01/ 6.37 unaccelerated)
event9 GESTURE_SWIPE_UPDATE +2.06s 3 -6.31/ 2.50 (-17.06/ 6.75 unaccelerated)
event9 GESTURE_SWIPE_UPDATE +2.07s 3 -5.34/ 1.80 (-14.44/ 4.87 unaccelerated)
event9 GESTURE_SWIPE_UPDATE +2.08s 3 -4.61/ 2.08 (-12.47/ 5.62 unaccelerated)
event9 GESTURE_SWIPE_UPDATE +2.09s 3 -4.49/ 1.53 (-12.14/ 4.12 unaccelerated)
event9 GESTURE_SWIPE_UPDATE +2.09s 3 -4.01/ 1.25 (-10.83/ 3.37 unaccelerated)
event9 GESTURE_SWIPE_UPDATE +2.10s 3 -4.13/ 0.42 (-11.15/ 1.12 unaccelerated)
event9 GESTURE_SWIPE_END +2.11s 3
...
```
If you can see `GESTURE_SWIPE_XXX` in your output, that means your touchpad supports multi-touch swipe gestures.
## Uninstall
Download the `uninstall` script then run `bash uninstall`
## Bug Reports ## Bug Reports
Create an issue [here](https://github.com/Hikari9/comfortable-swipe-ubuntu/issues/new) to report a bug. Create an issue [here](https://github.com/Hikari9/comfortable-swipe-ubuntu/issues/new) to report a bug.

View File

@ -45,6 +45,11 @@ def get_status():
# sets the autostart status # sets the autostart status
def set_status(status=ON): def set_status(status=ON):
if status == ON: if status == ON:
# make sure dir exists
path = target_path()
path_dir = os.path.dirname(path)
if not os.path.exists(path_dir):
os.makedirs(path_dir)
with open(target_path(), 'w') as file: with open(target_path(), 'w') as file:
file.write(template()) file.write(template())
elif status == OFF: elif status == OFF:

View File

@ -32,182 +32,185 @@ extern "C"
// CURRENT_WINDOW // CURRENT_WINDOW
} }
namespace comfortable_swipe::gesture namespace comfortable_swipe
{ {
/** namespace gesture
* Constructs a new swipe gesture, given configurations for certain swipe events.
*/
swipe_gesture::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 */
):
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)
{ {
// improve responsiveness of first gesture by pre-empting xdotool runtime /**
xdo_get_mouse_location(this->xdo, &this->ix, &this->iy, &this->screen_num); * Constructs a new swipe gesture, given configurations for certain swipe events.
} */
swipe_gesture::swipe_gesture
/** (
* Destructs this swipe gesture. const float threshold,
*/ const char* left3 /* 000 */,
swipe_gesture::~swipe_gesture() const char* left4 /* 001 */,
{ const char* right3 /* 010 */,
delete[] commands; const char* right4 /* 011 */,
} const char* up3 /* 100 */,
const char* up4 /* 101 */,
/** const char* down3 /* 110 */,
* Hook on begin of swipe gesture. const char* down4 /* 111 */
*/ ):
void swipe_gesture::begin() comfortable_swipe::gesture::xdo_gesture(),
{ threshold_squared(threshold*threshold),
xdo_get_mouse_location(this->xdo, &this->ix, &this->iy, &this->screen_num); commands(new const char*[8]{left3, left4, right3, right4, up3, up4, down3, down4}),
this->previous_gesture = swipe_gesture::FRESH; flag_swiping(false)
this->x = 0;
this->y = 0;
}
/**
* Hook on update of swipe gesture.
*/
void swipe_gesture::update()
{
this->x += this->dx;
this->y += this->dy;
// scale threshold to 1/10 when gesture is not fresh
float scale = this->previous_gesture == swipe_gesture::FRESH
? 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; // improve responsiveness of first gesture by pre-empting xdotool runtime
if (this->fingers == 3) mask |= swipe_gesture::MSK_THREE_FINGERS; xdo_get_mouse_location(this->xdo, &this->ix, &this->iy, &this->screen_num);
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. * Destructs this swipe gesture.
*/ */
void swipe_gesture::end() swipe_gesture::~swipe_gesture()
{ }
/**
* Dispatches begin/update/end depending on the regex pattern provided by this class.
*
* @param line the line from libinput debug-events to parse
* @return true if begin/update/end was dispatched
*/
bool swipe_gesture::parse_line(const char * line)
{
static const std::regex gesture_swipe_begin(swipe_gesture::GESTURE_BEGIN_REGEX_PATTERN);
static const std::regex gesture_swipe_update(swipe_gesture::GESTURE_UPDATE_REGEX_PATTERN);
static const std::regex gesture_swipe_end(swipe_gesture::GESTURE_END_REGEX_PATTERN);
// prepare holder for regex matches
static std::cmatch matches;
if (this->flag_swiping)
{ {
// currently swiping delete[] commands;
if (std::regex_match(line, matches, gesture_swipe_update) != 0)
{
// assign necessary variables for swipe update
this->fingers = std::stoi(matches[1]);
this->dx = std::stof(matches[2]);
this->dy = std::stof(matches[3]);
this->udx = std::stof(matches[4]);
this->udy = std::stof(matches[5]);
// dispatch update
this->update();
return true;
}
else if (std::regex_match(line, matches, gesture_swipe_end) != 0)
{
// assign necessary variables for swipe end
this->flag_swiping = false;
this->fingers = std::stoi(matches[1]);
// dispatch end
this->end();
return true;
}
} }
else
/**
* Hook on begin of swipe gesture.
*/
void swipe_gesture::begin()
{ {
// not swiping, check if swipe will begin xdo_get_mouse_location(this->xdo, &this->ix, &this->iy, &this->screen_num);
if (std::regex_match(line, matches, gesture_swipe_begin) != 0) this->previous_gesture = swipe_gesture::FRESH;
this->x = 0;
this->y = 0;
}
/**
* Hook on update of swipe gesture.
*/
void swipe_gesture::update()
{
this->x += this->dx;
this->y += this->dy;
// scale threshold to 1/10 when gesture is not fresh
float scale = this->previous_gesture == swipe_gesture::FRESH
? 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)
{ {
// assign necessary variables for swipe begin int mask = 0;
this->flag_swiping = true; if (this->fingers == 3) mask |= swipe_gesture::MSK_THREE_FINGERS;
this->fingers = std::stoi(matches[1]); else if (this->fingers == 4) mask |= swipe_gesture::MSK_FOUR_FINGERS;
// dispatch begin
this->begin(); const float absx = x >= 0 ? x : -x;
return true; 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;
}
} }
} }
return false; /**
} * Hook on end of swipe gesture.
*/
void swipe_gesture::end()
{ }
/* STATICS DEFINITIONS */ /**
const int swipe_gesture::MSK_THREE_FINGERS = 0; * Dispatches begin/update/end depending on the regex pattern provided by this class.
const int swipe_gesture::MSK_FOUR_FINGERS = 1; *
const int swipe_gesture::MSK_NEGATIVE = 0; * @param line the line from libinput debug-events to parse
const int swipe_gesture::MSK_POSITIVE = 2; * @return true if begin/update/end was dispatched
const int swipe_gesture::MSK_HORIZONTAL = 0; */
const int swipe_gesture::MSK_VERTICAL = 4; bool swipe_gesture::parse_line(const char * line)
const int swipe_gesture::FRESH = -1; {
const char * const swipe_gesture::command_map[8] = { static const std::regex gesture_swipe_begin(swipe_gesture::GESTURE_BEGIN_REGEX_PATTERN);
"left3", static const std::regex gesture_swipe_update(swipe_gesture::GESTURE_UPDATE_REGEX_PATTERN);
"left4", static const std::regex gesture_swipe_end(swipe_gesture::GESTURE_END_REGEX_PATTERN);
"right3",
"right4", // prepare holder for regex matches
"up3", static std::cmatch matches;
"up4",
"down3", if (this->flag_swiping)
"down4" {
}; // currently swiping
if (std::regex_match(line, matches, gesture_swipe_update) != 0)
{
// assign necessary variables for swipe update
this->fingers = std::stoi(matches[1]);
this->dx = std::stof(matches[2]);
this->dy = std::stof(matches[3]);
this->udx = std::stof(matches[4]);
this->udy = std::stof(matches[5]);
// dispatch update
this->update();
return true;
}
else if (std::regex_match(line, matches, gesture_swipe_end) != 0)
{
// assign necessary variables for swipe end
this->flag_swiping = false;
this->fingers = std::stoi(matches[1]);
// dispatch end
this->end();
return true;
}
}
else
{
// not swiping, check if swipe will begin
if (std::regex_match(line, matches, gesture_swipe_begin) != 0)
{
// assign necessary variables for swipe begin
this->flag_swiping = true;
this->fingers = std::stoi(matches[1]);
// dispatch begin
this->begin();
return true;
}
}
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

@ -21,70 +21,65 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "xdo_gesture.h" #include "xdo_gesture.h"
#ifdef __cplusplus namespace comfortable_swipe
extern "C" {
#endif
namespace comfortable_swipe::gesture
{ {
class swipe_gesture : protected xdo_gesture namespace gesture
{ {
public: class swipe_gesture : protected xdo_gesture
// constructor {
swipe_gesture( public:
const float threshold, // constructor
const char* left3 /* 000 */, swipe_gesture(
const char* left4 /* 001 */, const float threshold,
const char* right3 /* 010 */, const char* left3 /* 000 */,
const char* right4 /* 011 */, const char* left4 /* 001 */,
const char* up3 /* 100 */, const char* right3 /* 010 */,
const char* up4 /* 101 */, const char* right4 /* 011 */,
const char* down3 /* 110 */, const char* up3 /* 100 */,
const char* down4 /* 111 */ const char* up4 /* 101 */,
); const char* down3 /* 110 */,
const char* down4 /* 111 */
);
~swipe_gesture(); ~swipe_gesture();
// fields for xdo // fields for xdo
int fingers; int fingers;
float dx, dy, udx, udy; float dx, dy, udx, udy;
void begin() override; void begin() override;
void update() override; void update() override;
void end() override; void end() override;
bool parse_line(const char *) override; bool parse_line(const char *) override;
protected: protected:
// location of mouse // location of mouse
int screen_num, ix, iy; int screen_num, ix, iy;
// current location // current location
float x, y, threshold_squared; float x, y, threshold_squared;
int previous_gesture; int previous_gesture;
const char ** commands; const char ** commands;
// optimization flag for checking if GESTURE_SWIPE_BEGIN was dispatched // optimization flag for checking if GESTURE_SWIPE_BEGIN was dispatched
bool flag_swiping; bool flag_swiping;
public: public:
// static constants // static constants
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 int FRESH;
static const char * const command_map[8]; static const char * const command_map[8];
// regex patterns // regex patterns
static const char* GESTURE_BEGIN_REGEX_PATTERN; static const char* GESTURE_BEGIN_REGEX_PATTERN;
static const char* GESTURE_UPDATE_REGEX_PATTERN; static const char* GESTURE_UPDATE_REGEX_PATTERN;
static const char* GESTURE_END_REGEX_PATTERN; static const char* GESTURE_END_REGEX_PATTERN;
}; };
}
} }
#ifdef __cplusplus
}
#endif
#endif /* __COMFORTABLE_SWIPE__gesture_swipe_gesture_h__ */ #endif /* __COMFORTABLE_SWIPE__gesture_swipe_gesture_h__ */

View File

@ -21,71 +21,74 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "swipe_gesture.h" #include "swipe_gesture.h"
namespace comfortable_swipe::gesture namespace comfortable_swipe
{ {
/** namespace gesture
* Regex pattern for the libinput entry for start of swipe. {
* Extracts one match for the number of fingers used during the swipe. /**
* * Regex pattern for the libinput entry for start of swipe.
* eg. event15 GESTURE_SWIPE_BEGIN +34.33s 3 * Extracts one match for the number of fingers used during the swipe.
* ^ *
* fingers * eg. event15 GESTURE_SWIPE_BEGIN +34.33s 3
*/ * ^
const char* swipe_gesture::GESTURE_BEGIN_REGEX_PATTERN = * fingers
"^" // start of string */
"[ -]event\\d+" // event const char* swipe_gesture::GESTURE_BEGIN_REGEX_PATTERN =
"\\s+GESTURE_SWIPE_BEGIN" // gesture "^" // start of string
"\\s+\\S+" // timestamp "[ -]event\\d+" // event
"\\s+(\\d+)" // fingers "\\s+GESTURE_SWIPE_BEGIN" // gesture
"\\s*$" // end of string "\\s+\\S+" // timestamp
; "\\s+(\\d+)" // fingers
"\\s*$" // end of string
;
/** /**
* Regex pattern for the libinput entry for the end of swipe. * Regex pattern for the libinput entry for the end of swipe.
* Extracts one match for the number of fingers used during the swipe. * Extracts one match for the number of fingers used during the swipe.
* *
* eg. event15 GESTURE_SWIPE_END +35.03s 3 * eg. event15 GESTURE_SWIPE_END +35.03s 3
* ^ * ^
* fingers * fingers
*/ */
const char* swipe_gesture::GESTURE_END_REGEX_PATTERN = const char* swipe_gesture::GESTURE_END_REGEX_PATTERN =
"^" // start of string "^" // start of string
"[ -]event\\d+" // event "[ -]event\\d+" // event
"\\s+GESTURE_SWIPE_END" // gesture "\\s+GESTURE_SWIPE_END" // gesture
"\\s+\\S+" // timestamp "\\s+\\S+" // timestamp
"\\s+(\\d+)" // fingers "\\s+(\\d+)" // fingers
"\\s*$" // end of string "\\s*$" // end of string
; ;
// matches signed decimal numbers (eg. "6.02" "-1.1") // matches signed decimal numbers (eg. "6.02" "-1.1")
#define CF_NUMBER_REGEX "-?\\d+(?:\\.\\d+)" #define CF_NUMBER_REGEX "-?\\d+(?:\\.\\d+)"
// matches and extracts a space-prefixed signed fraction (eg. "-3.00/ 5.12") // matches and extracts a space-prefixed signed fraction (eg. "-3.00/ 5.12")
#define CF_NUMBER_DIVISION "\\s*(" CF_NUMBER_REGEX ")/\\s*(" CF_NUMBER_REGEX ")" #define CF_NUMBER_DIVISION "\\s*(" CF_NUMBER_REGEX ")/\\s*(" CF_NUMBER_REGEX ")"
/** /**
* Regex pattern for the libinput entry for during a swipe. * Regex pattern for the libinput entry for during a swipe.
* Extracts number of fingers used and the speed (normal and accelerated) of the swipe. * Extracts number of fingers used and the speed (normal and accelerated) of the swipe.
* *
* eg. event15 GESTURE_SWIPE_UPDATE +34.70s 3 -0.12/ 4.99 (-0.33/13.50 unaccelerated) * eg. event15 GESTURE_SWIPE_UPDATE +34.70s 3 -0.12/ 4.99 (-0.33/13.50 unaccelerated)
* ^ ^ ^ ^ ^ * ^ ^ ^ ^ ^
* fingers dx dy udx udy * fingers dx dy udx udy
*/ */
const char* swipe_gesture::GESTURE_UPDATE_REGEX_PATTERN = const char* swipe_gesture::GESTURE_UPDATE_REGEX_PATTERN =
"^" // start of string "^" // start of string
"[ -]event\\d+" // event "[ -]event\\d+" // event
"\\s+GESTURE_SWIPE_UPDATE" // gesture "\\s+GESTURE_SWIPE_UPDATE" // gesture
"\\s+\\S+" // timestamp "\\s+\\S+" // timestamp
"\\s+(\\d+)" // fingers "\\s+(\\d+)" // fingers
"\\s+" CF_NUMBER_DIVISION // speed (dx/dy) "\\s+" CF_NUMBER_DIVISION // speed (dx/dy)
"\\s+\\(" CF_NUMBER_DIVISION "\\s+unaccelerated\\)" // unaccelerated speed (udx/udy) "\\s+\\(" CF_NUMBER_DIVISION "\\s+unaccelerated\\)" // unaccelerated speed (udx/udy)
"\\s*$" // end of string "\\s*$" // end of string
; ;
// delete macros // delete macros
#undef CF_NUMBER_DIVISION #undef CF_NUMBER_DIVISION
#undef CF_NUMBER_EXTRACT #undef CF_NUMBER_EXTRACT
#undef CF_NUMBER_REGEX #undef CF_NUMBER_REGEX
}
} }
#endif /* __COMFORTABLE_SWIPE__gesture_swipe_gesture_regex__ */ #endif /* __COMFORTABLE_SWIPE__gesture_swipe_gesture_regex__ */

View File

@ -26,21 +26,24 @@ extern "C"
#include "xdo_gesture.h" #include "xdo_gesture.h"
namespace comfortable_swipe::gesture namespace comfortable_swipe
{ {
/** namespace gesture
* Constructs a new gesture handler with xdo.
*/
xdo_gesture::xdo_gesture():
xdo(xdo_new(NULL))
{ }
/**
* Constructs a new swipe gesture with xdo.
*/
xdo_gesture::~xdo_gesture()
{ {
xdo_free(this->xdo); /**
* Constructs a new gesture handler with xdo.
*/
xdo_gesture::xdo_gesture():
xdo(xdo_new(NULL))
{ }
/**
* Constructs a new swipe gesture with xdo.
*/
xdo_gesture::~xdo_gesture()
{
xdo_free(this->xdo);
}
} }
} }

View File

@ -4,20 +4,17 @@
#include <map> // std::map #include <map> // std::map
#include <string> // std::string #include <string> // std::string
extern "C" namespace comfortable_swipe
{ {
namespace comfortable_swipe namespace service
{ {
namespace service void buffer();
{ void debug();
void buffer(); void help();
void debug(); void restart();
void help(); void start();
void restart(); void stop();
void start(); void status();
void stop();
void status();
}
} }
} }

View File

@ -2,60 +2,69 @@
#define __COMFORTABLE_SWIPE__service_python__ #define __COMFORTABLE_SWIPE__service_python__
#include "_index.hpp" #include "_index.hpp"
#include <Python.h> extern "C"
{
#include <Python.h>
}
// export as python module // export as python module
namespace comfortable_swipe::service::python namespace comfortable_swipe
{ {
#define __comfortable_swipe_void_method(method) \ namespace service
static PyObject * \ {
method(PyObject * self, PyObject * args) \ namespace python
{ \ {
comfortable_swipe::service::method(); \ #define __comfortable_swipe_void_method(method) \
Py_RETURN_NONE; \ static PyObject * \
method(PyObject * self, PyObject * args) \
{ \
comfortable_swipe::service::method(); \
Py_RETURN_NONE; \
}
// create the python method signatures
__comfortable_swipe_void_method(status);
__comfortable_swipe_void_method(start);
__comfortable_swipe_void_method(stop);
__comfortable_swipe_void_method(restart);
// __comfortable_swipe_void_method(autostart);
__comfortable_swipe_void_method(buffer);
__comfortable_swipe_void_method(help);
// __comfortable_swipe_void_method(config);
__comfortable_swipe_void_method(debug);
#undef __comfortable_swipe_void_method
// create the method list for C++
static PyMethodDef methods[] =
{
{ "status", &status, METH_VARARGS , "checks status of program, autostart, and config" },
{ "start", &start, METH_VARARGS , "starts 3/4-finger gesture service" },
{ "stop", &stop, METH_VARARGS , "stops 3/4-finger gesture service" },
{ "restart", &restart, METH_VARARGS , "stops then starts 3/4-finger gesture service" },
// { "autostart", &autostart, METH_VARARGS , "automatically run on startup (toggleable)" },
{ "buffer", &buffer, METH_VARARGS , "parses output of libinput debug-events" },
{ "help", &help, METH_VARARGS , "shows the help dialog" },
// { "config", &config, METH_VARARGS , "locates the config file " },
{ "debug", &debug, METH_VARARGS , "logs raw output from input events taken from libinput" },
{ NULL, NULL, 0, NULL } // sentinel
};
// create the module configuration
#if PY_MAJOR_VERSION >= 3
static struct PyModuleDef module_def =
{
PyModuleDef_HEAD_INIT,
"service",
"Comfortable swipe service",
-1,
methods
};
#endif
PyObject * module;
} }
}
// create the python method signatures
__comfortable_swipe_void_method(status);
__comfortable_swipe_void_method(start);
__comfortable_swipe_void_method(stop);
__comfortable_swipe_void_method(restart);
// __comfortable_swipe_void_method(autostart);
__comfortable_swipe_void_method(buffer);
__comfortable_swipe_void_method(help);
// __comfortable_swipe_void_method(config);
__comfortable_swipe_void_method(debug);
#undef __comfortable_swipe_void_method
// create the method list for C++
static PyMethodDef methods[] =
{
{ "status", &status, METH_VARARGS , "checks status of program, autostart, and config" },
{ "start", &start, METH_VARARGS , "starts 3/4-finger gesture service" },
{ "stop", &stop, METH_VARARGS , "stops 3/4-finger gesture service" },
{ "restart", &restart, METH_VARARGS , "stops then starts 3/4-finger gesture service" },
// { "autostart", &autostart, METH_VARARGS , "automatically run on startup (toggleable)" },
{ "buffer", &buffer, METH_VARARGS , "parses output of libinput debug-events" },
{ "help", &help, METH_VARARGS , "shows the help dialog" },
// { "config", &config, METH_VARARGS , "locates the config file " },
{ "debug", &debug, METH_VARARGS , "logs raw output from input events taken from libinput" },
{ NULL, NULL, 0, NULL } // sentinel
};
// create the module configuration
#if PY_MAJOR_VERSION >= 3
static struct PyModuleDef module_def =
{
PyModuleDef_HEAD_INIT,
"service",
"Comfortable swipe service",
-1,
methods
};
#endif
PyObject * module;
} }
// initialize module // initialize module

View File

@ -21,14 +21,17 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <cstdlib> // std::system #include <cstdlib> // std::system
namespace comfortable_swipe::service namespace comfortable_swipe
{ {
/** namespace service
* Debugs output from `libinput debug-events`.
*/
void debug()
{ {
(void) std::system("bash -c \"stdbuf -oL -e0 libinput debug-events 2> >(grep -v 'double tracking')\""); /**
* Debugs output from `libinput debug-events`.
*/
void debug()
{
(void) std::system("bash -c \"stdbuf -oL -e0 libinput debug-events 2> >(grep -v 'double tracking')\"");
}
} }
} }

View File

@ -21,24 +21,27 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <cstdio> // std::puts, std::printf #include <cstdio> // std::puts, std::printf
namespace comfortable_swipe::service namespace comfortable_swipe
{ {
/** namespace service
* Shows the help window.
*/
void help()
{ {
std::puts("comfortable-swipe [start|stop|restart|autostart|buffer|help|config|debug|status]"); /**
std::puts(""); * Shows the help window.
std::puts("start - starts 3/4-finger gesture service"); */
std::puts("stop - stops 3/4-finger gesture service"); void help()
std::puts("restart - stops then starts 3/4-finger gesture service"); {
std::puts("autostart - automatically run on startup (toggleable)"); std::puts("comfortable-swipe [start|stop|restart|autostart|buffer|help|config|debug|status]");
std::puts("buffer - parses output of libinput debug-events"); std::puts("");
std::puts("help - shows the help dialog"); std::puts("start - starts 3/4-finger gesture service");
std::puts("config - locates the config file"); std::puts("stop - stops 3/4-finger gesture service");
std::puts("debug - logs raw output from input events taken from libinput"); std::puts("restart - stops then starts 3/4-finger gesture service");
std::puts("status - checks status of program and autostart"); std::puts("autostart - automatically run on startup (toggleable)");
std::puts("buffer - parses output of libinput debug-events");
std::puts("help - shows the help dialog");
std::puts("config - locates the config file");
std::puts("debug - logs raw output from input events taken from libinput");
std::puts("status - checks status of program and autostart");
}
} }
} }

View File

@ -21,15 +21,18 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "../service/_index.hpp" #include "../service/_index.hpp"
namespace comfortable_swipe::service namespace comfortable_swipe
{ {
/** namespace service
* Restarts the comfortable-swipe service.
*/
void restart()
{ {
comfortable_swipe::service::stop(); /**
comfortable_swipe::service::start(); * Restarts the comfortable-swipe service.
*/
void restart()
{
comfortable_swipe::service::stop();
comfortable_swipe::service::start();
}
} }
} }

View File

@ -24,39 +24,42 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <cstdlib> // std::system #include <cstdlib> // std::system
#include <unistd.h> // pipe, fork, perror, exit #include <unistd.h> // pipe, fork, perror, exit
namespace comfortable_swipe::service namespace comfortable_swipe
{ {
/** namespace service
* Starts the comfortable-swipe service by buffering libinput debug-events.
* This method is deferred. Please refer to comfortable_swipe::service::buffer()
* for the technical implementation.
*/
void start()
{ {
std::ios::sync_with_stdio(false); /**
std::cin.tie(0); * Starts the comfortable-swipe service by buffering libinput debug-events.
std::cout.tie(0); * This method is deferred. Please refer to comfortable_swipe::service::buffer()
std::cout.flush(); * for the technical implementation.
*/
void start()
{
std::ios::sync_with_stdio(false);
std::cin.tie(0);
std::cout.tie(0);
std::cout.flush();
// redirect stdout to stdin // redirect stdout to stdin
int fd[2]; int fd[2];
pipe(fd); // create the pipes pipe(fd); // create the pipes
int child; int child;
if ((child = fork()) == -1) { if ((child = fork()) == -1) {
perror("fork"); perror("fork");
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
}
if (child) {
dup2(fd[1], STDOUT_FILENO);
comfortable_swipe::service::debug();
close(fd[0]);
} else {
dup2(fd[0], STDIN_FILENO);
comfortable_swipe::service::buffer();
close(fd[1]);
}
comfortable_swipe::service::stop();
} }
if (child) {
dup2(fd[1], STDOUT_FILENO);
comfortable_swipe::service::debug();
close(fd[0]);
} else {
dup2(fd[0], STDIN_FILENO);
comfortable_swipe::service::buffer();
close(fd[1]);
}
comfortable_swipe::service::stop();
} }
} }

View File

@ -30,44 +30,47 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#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
namespace comfortable_swipe::service namespace comfortable_swipe
{ {
/** namespace service
* Prints the status of comfortable-swipe.
*/
void status()
{ {
// std::printf("autostart is %s\n", autostart_on ? "ON" : "OFF"); /**
* Prints the status of comfortable-swipe.
// check status of configuration file */
try void status()
{ {
std::puts(COMFORTABLE_SWIPE_CONFIG); // std::printf("autostart is %s\n", autostart_on ? "ON" : "OFF");
auto config = comfortable_swipe::util::read_config_file(COMFORTABLE_SWIPE_CONFIG);
// print threshold
if (config.count("threshold") > 0)
{
auto & threshold = config["threshold"];
// std::cmatch matches;
// bool ok = (std::regex_match(threshold.data(), matches, std::regex("^\\d+(?:\\.\\d+)??$")) != 0);
// print status of threshold
std::printf(" %9s = %s\n", "threshold", threshold.data()); // ok ? "VALID" : "INVALID"
}
else
std::printf(" %9s is OFF\n", "threshold");
// print swipe commands // check status of configuration file
for (auto &command : comfortable_swipe::gesture::swipe_gesture::command_map) try
{ {
if (config.count(command) > 0) std::puts(COMFORTABLE_SWIPE_CONFIG);
std::printf(" %9s = %s\n", command, config[command].data()); auto config = comfortable_swipe::util::read_config_file(COMFORTABLE_SWIPE_CONFIG);
// print threshold
if (config.count("threshold") > 0)
{
auto & threshold = config["threshold"];
// std::cmatch matches;
// bool ok = (std::regex_match(threshold.data(), matches, std::regex("^\\d+(?:\\.\\d+)??$")) != 0);
// print status of threshold
std::printf(" %9s = %s\n", "threshold", threshold.data()); // ok ? "VALID" : "INVALID"
}
else else
std::printf(" %9s NOT SET\n", command); std::printf(" %9s is OFF\n", "threshold");
// print swipe commands
for (auto &command : comfortable_swipe::gesture::swipe_gesture::command_map)
{
if (config.count(command) > 0)
std::printf(" %9s = %s\n", command, config[command].data());
else
std::printf(" %9s NOT SET\n", command);
}
}
catch (const std::runtime_error& e)
{
std::printf("config error: %s\n", e.what());
} }
}
catch (const std::runtime_error& e)
{
std::printf("config error: %s\n", e.what());
} }
} }
} }

View File

@ -29,41 +29,44 @@ 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 #include <cstdio> // FILE, std::feof, std::fgets
namespace comfortable_swipe::service namespace comfortable_swipe
{ {
/** namespace service
* Stops all comfortable-swipe instances.
*/
void stop()
{ {
/**
// read all service names from process (pgrep) * Stops all comfortable-swipe instances.
std::array<char, 128> buffer; */
std::unique_ptr<FILE, decltype(&pclose)> pipe(popen("pgrep -f comfortable-swipe", "r"), pclose); void stop()
// make sure pipe exists
if (!pipe)
throw std::runtime_error("stop command failed");
// buffer what to kill
std::string kill = "kill";
// read until end of line
while (!std::feof(pipe.get()))
{ {
if (std::fgets(buffer.data(), buffer.size(), pipe.get()) != NULL)
// read all service names from process (pgrep)
std::array<char, 128> buffer;
std::unique_ptr<FILE, decltype(&pclose)> pipe(popen("pgrep -f comfortable-swipe", "r"), pclose);
// make sure pipe exists
if (!pipe)
throw std::runtime_error("stop command failed");
// buffer what to kill
std::string kill = "kill";
// read until end of line
while (!std::feof(pipe.get()))
{ {
int pid = std::atoi(buffer.data()); if (std::fgets(buffer.data(), buffer.size(), pipe.get()) != NULL)
if (pid != getpid())
{ {
kill += " "; int pid = std::atoi(buffer.data());
kill += std::to_string(pid); if (pid != getpid())
{
kill += " ";
kill += std::to_string(pid);
}
} }
} }
}
// run "kill {pid1} {pid2}..." // run "kill {pid1} {pid2}..."
(void) std::system(kill.data()); (void) std::system(kill.data());
}
} }
} }

View File

@ -4,14 +4,11 @@
#include <map> // std::map #include <map> // std::map
#include <string> // std::string #include <string> // std::string
extern "C" namespace comfortable_swipe
{ {
namespace comfortable_swipe namespace util
{ {
namespace util std::map<std::string, std::string> read_config_file(const char*);
{
std::map<std::string, std::string> read_config_file(const char*);
}
} }
} }

View File

@ -22,82 +22,86 @@ 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
#include <fstream> // std::ifstream #include <fstream> // std::ifstream
#include <sstream> // std::ostringstream
#include <iostream> // std::endl, std::getline #include <iostream> // std::endl, std::getline
#include <sstream> // std::ostringstream
#include <cstdlib> // exit #include <cstdlib> // exit
#include <cctype> // std::isspace #include <cctype> // std::isspace
#include <stdexcept> // std::runtime_error #include <stdexcept> // std::runtime_error
namespace comfortable_swipe::util namespace comfortable_swipe
{ {
/** namespace util
* A utility method for reading the config file.
*
* @param filename (const char*) the path of the config file.
*/
std::map<std::string, std::string> read_config_file(const char* filename)
{ {
/**
std::map<std::string, std::string> conf; * A utility method for reading the config file.
std::ifstream fin(filename); *
* @param filename (const char*) the path of the config file.
if (!fin.is_open()) */
std::map<std::string, std::string> read_config_file(const char* filename)
{ {
throw std::runtime_error("config file does not exist");
}
static std::string line, token[2]; std::map<std::string, std::string> conf;
int line_number = 0; std::ifstream fin(filename, std::ios::in);
while (std::getline(fin, line)) if (!fin.is_open())
{
++line_number;
token[0].clear();
token[1].clear();
int length = line.length();
int equal_flag = 0;
// tokenize comfig config
for (int i = 0; i < length; ++i)
{ {
if (line[i] == '#') // skip comments throw std::runtime_error("config file does not exist");
break; }
if (line[i] == '=') // flag equal sign
static std::string line, token[2];
int line_number = 0;
while (std::getline(fin, line))
{
++line_number;
token[0].clear();
token[1].clear();
int length = line.length();
int equal_flag = 0;
// tokenize comfig config
for (int i = 0; i < length; ++i)
{ {
if (++equal_flag > 1) if (line[i] == '#') // skip comments
break;
if (line[i] == '=') // flag equal sign
{ {
std::ostringstream stream; if (++equal_flag > 1)
stream << "error in conf file " << filename << std::endl; {
stream << "multiple equal signs in line " << line_number << std::endl; std::ostringstream stream;
throw std::runtime_error(stream.str()); stream << "error in conf file " << filename << std::endl;
stream << "multiple equal signs in line " << line_number << std::endl;
throw std::runtime_error(stream.str());
}
}
else if (!std::isspace(line[i]))
{
// add to buffer
token[equal_flag].push_back(line[i]);
} }
} }
else if (!std::isspace(line[i]))
// ignore empty lines
if (equal_flag == 0 && token[0].length() == 0)
continue;
// no equal sign found in non-empty line
if (equal_flag == 0)
{ {
// add to buffer std::ostringstream stream;
token[equal_flag].push_back(line[i]); stream << "error in conf file: " << filename << std::endl;
stream << "equal sign expected in line " << line_number << std::endl;
throw std::runtime_error(stream.str());
} }
// equal sign found, add to tokens
if (token[1].length() > 0)
conf[token[0]] = token[1];
} }
// ignore empty lines return conf;
if (equal_flag == 0 && token[0].length() == 0)
continue;
// no equal sign found in non-empty line
if (equal_flag == 0)
{
std::ostringstream stream;
stream << "error in conf file: " << filename << std::endl;
stream << "equal sign expected in line " << line_number << std::endl;
throw std::runtime_error(stream.str());
}
// equal sign found, add to tokens
if (token[1].length() > 0)
conf[token[0]] = token[1];
} }
return conf;
} }
} }
#endif /* __COMFORTABLE_SWIPE__util_read_config_file__ */ #endif /* __COMFORTABLE_SWIPE__util_read_config_file__ */

1
requirements.txt Normal file
View File

@ -0,0 +1 @@
psutil==5.6.0

2
setup.cfg Normal file
View File

@ -0,0 +1,2 @@
[build]
compiler = unix

View File

@ -54,7 +54,7 @@ try:
name='{}.cpp.{}'.format(PYTHON_NAME, extension_name), name='{}.cpp.{}'.format(PYTHON_NAME, extension_name),
define_macros=list(cpp_macros.items()), define_macros=list(cpp_macros.items()),
sources=[os.path.join('cpp', '_python.cpp')], sources=[os.path.join('cpp', '_python.cpp')],
extra_compile_args=['-O2', '-Wno-unused-result'], extra_compile_args=['-O2', '-Wno-unused-result', '-std=c++11', '-lstdc++'],
libraries=['xdo'] libraries=['xdo']
) for extension_name in extension_names] ) for extension_name in extension_names]
@ -134,6 +134,10 @@ try:
bdist_wheel=wrap_command(bdist_wheel) bdist_wheel=wrap_command(bdist_wheel)
) )
# install requiremenh open('requirements.txt', 'r') as requirements:
with open('requirements.txt', 'r') as requirements:
install_requires = requirements.read().splitlines()
# classifiers # classifiers
# https://pypi.org/classifiers/ # https://pypi.org/classifiers/
classifiers = [ classifiers = [
@ -166,7 +170,7 @@ try:
entry_points=dict(console_scripts=['{}={}.__main__:main'.format(NAME, PYTHON_NAME)]), entry_points=dict(console_scripts=['{}={}.__main__:main'.format(NAME, PYTHON_NAME)]),
ext_modules=extensions, ext_modules=extensions,
cmdclass=cmdclass, cmdclass=cmdclass,
install_requires=['psutil'], install_requires=install_requires,
classifiers=classifiers classifiers=classifiers
) )

View File

@ -3,4 +3,4 @@
DIR=$(dirname $0) DIR=$(dirname $0)
g++ -std=c++11 -O2 $DIR/test_regex.cpp -lxdo -o test.out || exec "Test aborted" g++ -std=c++11 -O2 $DIR/test_regex.cpp -lxdo -o test.out || exec "Test aborted"
./test.out || rm test.out ./test.out || rm test.out
rm test.out rm test.out