From 044e215d97ceba364a4b861fb1dbc8fc4597e043 Mon Sep 17 00:00:00 2001 From: Rico Tiongson Date: Fri, 8 Mar 2019 19:57:10 +0800 Subject: [PATCH] Travis (#62) * 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 --- .travis.yml | 25 +++ README.md | 172 +++++++++------ comfortable_swipe/autostart.py | 5 + cpp/gesture/swipe_gesture.cpp | 329 ++++++++++++++-------------- cpp/gesture/swipe_gesture.h | 105 +++++---- cpp/gesture/swipe_gesture.regex.cpp | 121 +++++----- cpp/gesture/xdo_gesture.cpp | 29 +-- cpp/service/_index.hpp | 21 +- cpp/service/_python.cpp | 109 ++++----- cpp/service/debug.cpp | 15 +- cpp/service/help.cpp | 35 +-- cpp/service/restart.cpp | 17 +- cpp/service/start.cpp | 59 ++--- cpp/service/status.cpp | 65 +++--- cpp/service/stop.cpp | 57 ++--- cpp/util/_index.hpp | 9 +- cpp/util/read_config_file.cpp | 116 +++++----- requirements.txt | 1 + setup.cfg | 2 + setup.py | 8 +- tests/run_tests | 2 +- 21 files changed, 709 insertions(+), 593 deletions(-) create mode 100644 .travis.yml create mode 100644 requirements.txt create mode 100644 setup.cfg diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..885a2d6 --- /dev/null +++ b/.travis.yml @@ -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 diff --git a/README.md b/README.md index a6e8ee3..81dddfa 100644 --- a/README.md +++ b/README.md @@ -1,30 +1,62 @@ -# Comfortable Swipe (Ubuntu) -[![License: GPL v3](https://img.shields.io/badge/License-GPL%20v3-blue.svg)](https://www.gnu.org/licenses/gpl-3.0) +# Comfortable Swipe (Debian/Ubuntu) -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 -1. Install Python3, libinput, and g++ +1. Update and install essential tools and libraries ```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 - git clone https://github.com/Hikari9/comfortable-swipe-ubuntu.git - cd comfortable-swipe-ubuntu + pip3 install --user git+https://github.com/Hikari9/comfortable-swipe ``` -3. Install +3. You can check status with `comfortable-swipe status` ```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 @@ -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) ``` 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 ``` -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 + 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 ``` @@ -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. - -## 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 + Create an issue [here](https://github.com/Hikari9/comfortable-swipe-ubuntu/issues/new) to report a bug. diff --git a/comfortable_swipe/autostart.py b/comfortable_swipe/autostart.py index 164a335..2580e97 100644 --- a/comfortable_swipe/autostart.py +++ b/comfortable_swipe/autostart.py @@ -45,6 +45,11 @@ def get_status(): # sets the autostart status def set_status(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: file.write(template()) elif status == OFF: diff --git a/cpp/gesture/swipe_gesture.cpp b/cpp/gesture/swipe_gesture.cpp index 9056911..b1c7ebc 100644 --- a/cpp/gesture/swipe_gesture.cpp +++ b/cpp/gesture/swipe_gesture.cpp @@ -32,182 +32,185 @@ extern "C" // CURRENT_WINDOW } -namespace comfortable_swipe::gesture +namespace comfortable_swipe { - /** - * 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) + namespace gesture { - // improve responsiveness of first gesture by pre-empting xdotool runtime - xdo_get_mouse_location(this->xdo, &this->ix, &this->iy, &this->screen_num); - } - - /** - * Destructs this swipe gesture. - */ - swipe_gesture::~swipe_gesture() - { - delete[] commands; - } - - /** - * Hook on begin of swipe gesture. - */ - void swipe_gesture::begin() - { - xdo_get_mouse_location(this->xdo, &this->ix, &this->iy, &this->screen_num); - 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) + /** + * 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) { - 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; - } + // improve responsiveness of first gesture by pre-empting xdotool runtime + xdo_get_mouse_location(this->xdo, &this->ix, &this->iy, &this->screen_num); } - } - /** - * Hook on end of swipe gesture. - */ - void swipe_gesture::end() - { } - - /** - * 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) + /** + * Destructs this swipe gesture. + */ + swipe_gesture::~swipe_gesture() { - // 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; - } + delete[] commands; } - else + + /** + * Hook on begin of swipe gesture. + */ + void swipe_gesture::begin() { - // not swiping, check if swipe will begin - if (std::regex_match(line, matches, gesture_swipe_begin) != 0) + xdo_get_mouse_location(this->xdo, &this->ix, &this->iy, &this->screen_num); + 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 - this->flag_swiping = true; - this->fingers = std::stoi(matches[1]); - // dispatch begin - this->begin(); - return true; + 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; + } } } - return false; - } + /** + * Hook on end of swipe gesture. + */ + void swipe_gesture::end() + { } - /* 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" - }; + /** + * 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 + 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__ */ diff --git a/cpp/gesture/swipe_gesture.h b/cpp/gesture/swipe_gesture.h index 86ec3bd..4e843d6 100644 --- a/cpp/gesture/swipe_gesture.h +++ b/cpp/gesture/swipe_gesture.h @@ -21,70 +21,65 @@ along with this program. If not, see . #include "xdo_gesture.h" -#ifdef __cplusplus -extern "C" { -#endif - -namespace comfortable_swipe::gesture +namespace comfortable_swipe { - class swipe_gesture : protected xdo_gesture + namespace gesture { - public: - // constructor - 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 */ - ); + class swipe_gesture : protected xdo_gesture + { + public: + // constructor + 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 */ + ); - ~swipe_gesture(); + ~swipe_gesture(); - // fields for xdo - int fingers; - float dx, dy, udx, udy; + // fields for xdo + int fingers; + float dx, dy, udx, udy; - void begin() override; - void update() override; - void end() override; - bool parse_line(const char *) override; + void begin() override; + void update() override; + void end() override; + bool parse_line(const char *) override; - protected: - // location of mouse - int screen_num, ix, iy; + protected: + // location of mouse + int screen_num, ix, iy; - // current location - float x, y, threshold_squared; - int previous_gesture; - const char ** commands; + // current location + float x, y, threshold_squared; + int previous_gesture; + const char ** commands; - // optimization flag for checking if GESTURE_SWIPE_BEGIN was dispatched - bool flag_swiping; + // optimization flag for checking if GESTURE_SWIPE_BEGIN was dispatched + bool flag_swiping; - public: - // static constants - static const int MSK_THREE_FINGERS; - static const int MSK_FOUR_FINGERS; - static const int MSK_NEGATIVE; - static const int MSK_POSITIVE; - static const int MSK_HORIZONTAL; - static const int MSK_VERTICAL; - static const int FRESH; - 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; - }; + public: + // static constants + static const int MSK_THREE_FINGERS; + static const int MSK_FOUR_FINGERS; + static const int MSK_NEGATIVE; + static const int MSK_POSITIVE; + static const int MSK_HORIZONTAL; + static const int MSK_VERTICAL; + static const int FRESH; + 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; + }; + } } -#ifdef __cplusplus -} -#endif - #endif /* __COMFORTABLE_SWIPE__gesture_swipe_gesture_h__ */ diff --git a/cpp/gesture/swipe_gesture.regex.cpp b/cpp/gesture/swipe_gesture.regex.cpp index 7dd1d04..ded720f 100644 --- a/cpp/gesture/swipe_gesture.regex.cpp +++ b/cpp/gesture/swipe_gesture.regex.cpp @@ -21,71 +21,74 @@ along with this program. If not, see . #include "swipe_gesture.h" -namespace comfortable_swipe::gesture +namespace comfortable_swipe { - /** - * Regex pattern for the libinput entry for start of swipe. - * Extracts one match for the number of fingers used during the swipe. - * - * eg. event15 GESTURE_SWIPE_BEGIN +34.33s 3 - * ^ - * fingers - */ - const char* swipe_gesture::GESTURE_BEGIN_REGEX_PATTERN = - "^" // start of string - "[ -]event\\d+" // event - "\\s+GESTURE_SWIPE_BEGIN" // gesture - "\\s+\\S+" // timestamp - "\\s+(\\d+)" // fingers - "\\s*$" // end of string - ; + namespace gesture + { + /** + * Regex pattern for the libinput entry for start of swipe. + * Extracts one match for the number of fingers used during the swipe. + * + * eg. event15 GESTURE_SWIPE_BEGIN +34.33s 3 + * ^ + * fingers + */ + const char* swipe_gesture::GESTURE_BEGIN_REGEX_PATTERN = + "^" // start of string + "[ -]event\\d+" // event + "\\s+GESTURE_SWIPE_BEGIN" // gesture + "\\s+\\S+" // timestamp + "\\s+(\\d+)" // fingers + "\\s*$" // end of string + ; - /** - * Regex pattern for the libinput entry for the end of swipe. - * Extracts one match for the number of fingers used during the swipe. - * - * eg. event15 GESTURE_SWIPE_END +35.03s 3 - * ^ - * fingers - */ - const char* swipe_gesture::GESTURE_END_REGEX_PATTERN = - "^" // start of string - "[ -]event\\d+" // event - "\\s+GESTURE_SWIPE_END" // gesture - "\\s+\\S+" // timestamp - "\\s+(\\d+)" // fingers - "\\s*$" // end of string - ; + /** + * Regex pattern for the libinput entry for the end of swipe. + * Extracts one match for the number of fingers used during the swipe. + * + * eg. event15 GESTURE_SWIPE_END +35.03s 3 + * ^ + * fingers + */ + const char* swipe_gesture::GESTURE_END_REGEX_PATTERN = + "^" // start of string + "[ -]event\\d+" // event + "\\s+GESTURE_SWIPE_END" // gesture + "\\s+\\S+" // timestamp + "\\s+(\\d+)" // fingers + "\\s*$" // end of string + ; - // matches signed decimal numbers (eg. "6.02" "-1.1") - #define CF_NUMBER_REGEX "-?\\d+(?:\\.\\d+)" + // matches signed decimal numbers (eg. "6.02" "-1.1") + #define CF_NUMBER_REGEX "-?\\d+(?:\\.\\d+)" - // 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 ")" + // 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 ")" - /** - * Regex pattern for the libinput entry for during a 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) - * ^ ^ ^ ^ ^ - * fingers dx dy udx udy - */ - const char* swipe_gesture::GESTURE_UPDATE_REGEX_PATTERN = - "^" // start of string - "[ -]event\\d+" // event - "\\s+GESTURE_SWIPE_UPDATE" // gesture - "\\s+\\S+" // timestamp - "\\s+(\\d+)" // fingers - "\\s+" CF_NUMBER_DIVISION // speed (dx/dy) - "\\s+\\(" CF_NUMBER_DIVISION "\\s+unaccelerated\\)" // unaccelerated speed (udx/udy) - "\\s*$" // end of string - ; + /** + * Regex pattern for the libinput entry for during a 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) + * ^ ^ ^ ^ ^ + * fingers dx dy udx udy + */ + const char* swipe_gesture::GESTURE_UPDATE_REGEX_PATTERN = + "^" // start of string + "[ -]event\\d+" // event + "\\s+GESTURE_SWIPE_UPDATE" // gesture + "\\s+\\S+" // timestamp + "\\s+(\\d+)" // fingers + "\\s+" CF_NUMBER_DIVISION // speed (dx/dy) + "\\s+\\(" CF_NUMBER_DIVISION "\\s+unaccelerated\\)" // unaccelerated speed (udx/udy) + "\\s*$" // end of string + ; - // delete macros - #undef CF_NUMBER_DIVISION - #undef CF_NUMBER_EXTRACT - #undef CF_NUMBER_REGEX + // delete macros + #undef CF_NUMBER_DIVISION + #undef CF_NUMBER_EXTRACT + #undef CF_NUMBER_REGEX + } } #endif /* __COMFORTABLE_SWIPE__gesture_swipe_gesture_regex__ */ diff --git a/cpp/gesture/xdo_gesture.cpp b/cpp/gesture/xdo_gesture.cpp index 3afda7d..7b044c7 100644 --- a/cpp/gesture/xdo_gesture.cpp +++ b/cpp/gesture/xdo_gesture.cpp @@ -26,21 +26,24 @@ extern "C" #include "xdo_gesture.h" -namespace comfortable_swipe::gesture +namespace comfortable_swipe { - /** - * 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() + namespace 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); + } } } diff --git a/cpp/service/_index.hpp b/cpp/service/_index.hpp index 25af404..584787e 100644 --- a/cpp/service/_index.hpp +++ b/cpp/service/_index.hpp @@ -4,20 +4,17 @@ #include // std::map #include // std::string -extern "C" +namespace comfortable_swipe { - namespace comfortable_swipe + namespace service { - namespace service - { - void buffer(); - void debug(); - void help(); - void restart(); - void start(); - void stop(); - void status(); - } + void buffer(); + void debug(); + void help(); + void restart(); + void start(); + void stop(); + void status(); } } diff --git a/cpp/service/_python.cpp b/cpp/service/_python.cpp index 1316948..2274233 100644 --- a/cpp/service/_python.cpp +++ b/cpp/service/_python.cpp @@ -2,60 +2,69 @@ #define __COMFORTABLE_SWIPE__service_python__ #include "_index.hpp" -#include +extern "C" +{ + #include +} // export as python module -namespace comfortable_swipe::service::python +namespace comfortable_swipe { - #define __comfortable_swipe_void_method(method) \ - static PyObject * \ - method(PyObject * self, PyObject * args) \ - { \ - comfortable_swipe::service::method(); \ - Py_RETURN_NONE; \ + namespace service + { + namespace python + { + #define __comfortable_swipe_void_method(method) \ + 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 diff --git a/cpp/service/debug.cpp b/cpp/service/debug.cpp index 2efa702..b078bde 100644 --- a/cpp/service/debug.cpp +++ b/cpp/service/debug.cpp @@ -21,14 +21,17 @@ along with this program. If not, see . #include // std::system -namespace comfortable_swipe::service +namespace comfortable_swipe { - /** - * Debugs output from `libinput debug-events`. - */ - void debug() + namespace service { - (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')\""); + } } } diff --git a/cpp/service/help.cpp b/cpp/service/help.cpp index 68f9528..2ffbddd 100644 --- a/cpp/service/help.cpp +++ b/cpp/service/help.cpp @@ -21,24 +21,27 @@ along with this program. If not, see . #include // std::puts, std::printf -namespace comfortable_swipe::service +namespace comfortable_swipe { - /** - * Shows the help window. - */ - void help() + namespace service { - std::puts("comfortable-swipe [start|stop|restart|autostart|buffer|help|config|debug|status]"); - std::puts(""); - std::puts("start - starts 3/4-finger gesture service"); - std::puts("stop - stops 3/4-finger gesture service"); - std::puts("restart - stops then starts 3/4-finger gesture service"); - 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"); + /** + * Shows the help window. + */ + void help() + { + std::puts("comfortable-swipe [start|stop|restart|autostart|buffer|help|config|debug|status]"); + std::puts(""); + std::puts("start - starts 3/4-finger gesture service"); + std::puts("stop - stops 3/4-finger gesture service"); + std::puts("restart - stops then starts 3/4-finger gesture service"); + 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"); + } } } diff --git a/cpp/service/restart.cpp b/cpp/service/restart.cpp index b66beb1..6559f4e 100644 --- a/cpp/service/restart.cpp +++ b/cpp/service/restart.cpp @@ -21,15 +21,18 @@ along with this program. If not, see . #include "../service/_index.hpp" -namespace comfortable_swipe::service +namespace comfortable_swipe { - /** - * Restarts the comfortable-swipe service. - */ - void restart() + namespace service { - comfortable_swipe::service::stop(); - comfortable_swipe::service::start(); + /** + * Restarts the comfortable-swipe service. + */ + void restart() + { + comfortable_swipe::service::stop(); + comfortable_swipe::service::start(); + } } } diff --git a/cpp/service/start.cpp b/cpp/service/start.cpp index c7e0e50..618d901 100644 --- a/cpp/service/start.cpp +++ b/cpp/service/start.cpp @@ -24,39 +24,42 @@ along with this program. If not, see . #include // std::system #include // pipe, fork, perror, exit -namespace comfortable_swipe::service +namespace comfortable_swipe { - /** - * 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() + namespace service { - std::ios::sync_with_stdio(false); - std::cin.tie(0); - std::cout.tie(0); - std::cout.flush(); + /** + * 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); + std::cout.tie(0); + std::cout.flush(); - // redirect stdout to stdin - int fd[2]; - pipe(fd); // create the pipes + // redirect stdout to stdin + int fd[2]; + pipe(fd); // create the pipes - int child; - if ((child = fork()) == -1) { - perror("fork"); - exit(EXIT_FAILURE); + int child; + if ((child = fork()) == -1) { + perror("fork"); + 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(); } } diff --git a/cpp/service/status.cpp b/cpp/service/status.cpp index 0aae353..e56fad7 100644 --- a/cpp/service/status.cpp +++ b/cpp/service/status.cpp @@ -30,44 +30,47 @@ along with this program. If not, see . #include // FILE, std::feof, std::fgets, std::printf #include // std::cmatch, std::regex, std::regex_match -namespace comfortable_swipe::service +namespace comfortable_swipe { - /** - * Prints the status of comfortable-swipe. - */ - void status() + namespace service { - // std::printf("autostart is %s\n", autostart_on ? "ON" : "OFF"); - - // check status of configuration file - try + /** + * Prints the status of comfortable-swipe. + */ + void status() { - std::puts(COMFORTABLE_SWIPE_CONFIG); - 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"); + // std::printf("autostart is %s\n", autostart_on ? "ON" : "OFF"); - // print swipe commands - for (auto &command : comfortable_swipe::gesture::swipe_gesture::command_map) + // check status of configuration file + try { - if (config.count(command) > 0) - std::printf(" %9s = %s\n", command, config[command].data()); + std::puts(COMFORTABLE_SWIPE_CONFIG); + 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 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()); } } } diff --git a/cpp/service/stop.cpp b/cpp/service/stop.cpp index 7469c69..a4836a0 100644 --- a/cpp/service/stop.cpp +++ b/cpp/service/stop.cpp @@ -29,41 +29,44 @@ along with this program. If not, see . #include // std::atoi #include // FILE, std::feof, std::fgets -namespace comfortable_swipe::service +namespace comfortable_swipe { - /** - * Stops all comfortable-swipe instances. - */ - void stop() + namespace service { - - // read all service names from process (pgrep) - std::array buffer; - std::unique_ptr 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())) + /** + * Stops all comfortable-swipe instances. + */ + void stop() { - if (std::fgets(buffer.data(), buffer.size(), pipe.get()) != NULL) + + // read all service names from process (pgrep) + std::array buffer; + std::unique_ptr 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 (pid != getpid()) + if (std::fgets(buffer.data(), buffer.size(), pipe.get()) != NULL) { - kill += " "; - kill += std::to_string(pid); + int pid = std::atoi(buffer.data()); + if (pid != getpid()) + { + kill += " "; + kill += std::to_string(pid); + } } } - } - // run "kill {pid1} {pid2}..." - (void) std::system(kill.data()); + // run "kill {pid1} {pid2}..." + (void) std::system(kill.data()); + } } } diff --git a/cpp/util/_index.hpp b/cpp/util/_index.hpp index 2fbfe7b..77226b3 100644 --- a/cpp/util/_index.hpp +++ b/cpp/util/_index.hpp @@ -4,14 +4,11 @@ #include // std::map #include // std::string -extern "C" +namespace comfortable_swipe { - namespace comfortable_swipe + namespace util { - namespace util - { - std::map read_config_file(const char*); - } + std::map read_config_file(const char*); } } diff --git a/cpp/util/read_config_file.cpp b/cpp/util/read_config_file.cpp index 9fd5f0b..6512bd2 100644 --- a/cpp/util/read_config_file.cpp +++ b/cpp/util/read_config_file.cpp @@ -22,82 +22,86 @@ along with this program. If not, see . #include // std::map #include // std::string #include // std::ifstream -#include // std::ostringstream #include // std::endl, std::getline +#include // std::ostringstream #include // exit #include // std::isspace #include // std::runtime_error -namespace comfortable_swipe::util +namespace comfortable_swipe { - /** - * A utility method for reading the config file. - * - * @param filename (const char*) the path of the config file. - */ - std::map read_config_file(const char* filename) + namespace util { - - std::map conf; - std::ifstream fin(filename); - - if (!fin.is_open()) + /** + * A utility method for reading the config file. + * + * @param filename (const char*) the path of the config file. + */ + std::map read_config_file(const char* filename) { - throw std::runtime_error("config file does not exist"); - } - static std::string line, token[2]; - int line_number = 0; + std::map conf; + std::ifstream fin(filename, std::ios::in); - 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 (!fin.is_open()) { - if (line[i] == '#') // skip comments - break; - if (line[i] == '=') // flag equal sign + throw std::runtime_error("config file does not exist"); + } + + 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; - stream << "error in conf file " << filename << std::endl; - stream << "multiple equal signs in line " << line_number << std::endl; - throw std::runtime_error(stream.str()); + if (++equal_flag > 1) + { + std::ostringstream stream; + 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 - token[equal_flag].push_back(line[i]); + 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]; } - // ignore empty lines - 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; } - - return conf; } } + #endif /* __COMFORTABLE_SWIPE__util_read_config_file__ */ diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..dbdd38b --- /dev/null +++ b/requirements.txt @@ -0,0 +1 @@ +psutil==5.6.0 diff --git a/setup.cfg b/setup.cfg new file mode 100644 index 0000000..066439e --- /dev/null +++ b/setup.cfg @@ -0,0 +1,2 @@ +[build] +compiler = unix diff --git a/setup.py b/setup.py index 40288c4..8405c71 100644 --- a/setup.py +++ b/setup.py @@ -54,7 +54,7 @@ try: name='{}.cpp.{}'.format(PYTHON_NAME, extension_name), define_macros=list(cpp_macros.items()), 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'] ) for extension_name in extension_names] @@ -134,6 +134,10 @@ try: 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 # https://pypi.org/classifiers/ classifiers = [ @@ -166,7 +170,7 @@ try: entry_points=dict(console_scripts=['{}={}.__main__:main'.format(NAME, PYTHON_NAME)]), ext_modules=extensions, cmdclass=cmdclass, - install_requires=['psutil'], + install_requires=install_requires, classifiers=classifiers ) diff --git a/tests/run_tests b/tests/run_tests index 20da97d..28c429a 100755 --- a/tests/run_tests +++ b/tests/run_tests @@ -3,4 +3,4 @@ DIR=$(dirname $0) g++ -std=c++11 -O2 $DIR/test_regex.cpp -lxdo -o test.out || exec "Test aborted" ./test.out || rm test.out -rm test.out \ No newline at end of file +rm test.out