diff --git a/.gitignore b/.gitignore index 2fca53d..05bf491 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,123 @@ # IDE-specific .idea .vscode + +# PYTHON + +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +!/lib +lib64/ +parts/ +sdist/ +var/ +wheels/ +pip-wheel-metadata/ +share/python-wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.nox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +.hypothesis/ +.pytest_cache/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py +db.sqlite3 + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# IPython +profile_default/ +ipython_config.py + +# pyenv +.python-version + +# celery beat schedule file +celerybeat-schedule + +# SageMath parsed files +*.sage.py + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ +.dmypy.json +dmypy.json + +# Pyre type checker +.pyre/ 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/MANIFEST.in b/MANIFEST.in new file mode 100644 index 0000000..99782df --- /dev/null +++ b/MANIFEST.in @@ -0,0 +1 @@ +include comfortable_swipe/res/comfortable-swipe.desktop diff --git a/README.md b/README.md index d1b85a0..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 git, libinput, and g++ +1. Update and install essential tools and libraries ```bash - sudo apt-get install git libinput-tools libxdo-dev g++ + 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.compile.sh b/comfortable-swipe.compile.sh deleted file mode 100755 index d839b64..0000000 --- a/comfortable-swipe.compile.sh +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/sh -g++ $(dirname $0)/comfortable-swipe.cpp -std=c++11 -O2 -lxdo -Wno-unused-result -o $1 diff --git a/comfortable-swipe.cpp b/comfortable-swipe.cpp deleted file mode 100644 index 65359b5..0000000 --- a/comfortable-swipe.cpp +++ /dev/null @@ -1,70 +0,0 @@ -/* -Comfortable Swipe -by Rico Tiongson - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program. If not, see . -*/ - -#include // std::ios -#include // std::cin, std::cout, std::cerr -#include // std::string -#include "lib/comfortable_swipe" - -/* MAIN DRIVER FUNCTION */ - -int main(int argc, char** args) -{ - // improve buffering by decoupling loggers from stdio - std::ios::sync_with_stdio(false); - std::cin.tie(0); - std::cout.tie(0); - std::cerr.tie(0); - - if (argc > 1) - { - std::string arg = args[1]; - - // select based on argument - if (arg == "start") - comfortable_swipe::service::start(); - - else if (arg == "stop") - comfortable_swipe::service::stop(); - - else if (arg == "restart") - comfortable_swipe::service::restart(); - - else if (arg == "buffer") - comfortable_swipe::service::buffer(); - - else if (arg == "autostart") - comfortable_swipe::service::autostart(); - - else if (arg == "config") - comfortable_swipe::service::config(); - - else if (arg == "debug") - comfortable_swipe::service::debug(); - - else if (arg == "status") - comfortable_swipe::service::status(); - - else /* if (arg == "help") */ - comfortable_swipe::service::help(); - } - else - comfortable_swipe::service::help(); - - return 0; -} diff --git a/comfortable_swipe/__init__.py b/comfortable_swipe/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/comfortable_swipe/__main__.py b/comfortable_swipe/__main__.py new file mode 100644 index 0000000..ef34de2 --- /dev/null +++ b/comfortable_swipe/__main__.py @@ -0,0 +1,28 @@ +from __future__ import print_function + +import sys + +from comfortable_swipe.autostart import toggle_status +from comfortable_swipe.constants import CONFIG +from comfortable_swipe.status import print_status + +from comfortable_swipe.cpp import service as cpp_service + +def main(): + if len(sys.argv) <= 1: + cpp_service.help() + else: + dict( + start=cpp_service.start, + stop=cpp_service.stop, + restart=cpp_service.restart, + buffer=cpp_service.buffer, + help=cpp_service.help, + debug=cpp_service.debug, + status=print_status, + autostart=lambda: print('Autostart switched', toggle_status()), + config=lambda: print(CONFIG), + )[sys.argv[1]]() + +if __name__ == '__main__': + main() diff --git a/comfortable_swipe/autostart.py b/comfortable_swipe/autostart.py new file mode 100644 index 0000000..2580e97 --- /dev/null +++ b/comfortable_swipe/autostart.py @@ -0,0 +1,66 @@ +from __future__ import print_function + +import os +import sys + +from comfortable_swipe.constants import NAME, RES, exe + + +# status enums +OFF = 'off' +ON = 'on' + + +# the target path to the autostart desktop file +def target_path(): + return os.path.join( + os.getenv( + 'XDG_CONFIG_HOME', + os.path.join(os.getenv('HOME'), '.config') + ), + 'autostart', + '{}.desktop'.format(NAME) + ) + + +# path to the autostart template file to be copied +def template_path(): + return os.path.join(RES, '{}.desktop'.format(NAME)) + + +# parsed contents of the template file +def template(raw=False): + with open(template_path(), 'r') as file: + contents = file.read() + if raw: + return contents + return contents.replace('Exec=' + NAME, 'Exec={} {}'.format(sys.executable, exe())) + + +# gets the current autostart status +def get_status(): + return ON if os.path.exists(target_path()) else OFF + + +# 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: + if os.path.exists(target_path()): + os.remove(target_path()) + else: + raise ValueError('invalid status for autostart') + + return status + + +# toggles autostart status +def toggle_status(): + return set_status(OFF if get_status() == ON else ON) diff --git a/comfortable_swipe/constants.py b/comfortable_swipe/constants.py new file mode 100644 index 0000000..f27af9e --- /dev/null +++ b/comfortable_swipe/constants.py @@ -0,0 +1,17 @@ +import os +import sys + +from distutils.spawn import find_executable + + +NAME = 'comfortable-swipe' +DESCRIPTION = 'Comfortable 3-finger and 4-finger swipe gestures' +BIN = os.path.dirname(sys.executable) +DIR = os.path.dirname(os.path.abspath(__file__)) +PYTHON_NAME = os.path.basename(DIR) +RES = os.path.join(DIR, 'res') +CONFIG = os.path.join(sys.prefix, 'local', 'share', NAME, '{}.conf'.format(NAME)) +DEFAULT_CONFIG = os.path.join(RES, 'defaults.conf') + +def exe(): + return find_executable(NAME) diff --git a/comfortable_swipe/cpp/__init__.py b/comfortable_swipe/cpp/__init__.py new file mode 100644 index 0000000..ded284d --- /dev/null +++ b/comfortable_swipe/cpp/__init__.py @@ -0,0 +1 @@ +# This is a placeholder module that will contain the C++ libraries. diff --git a/comfortable_swipe/res/comfortable-swipe.desktop b/comfortable_swipe/res/comfortable-swipe.desktop new file mode 100644 index 0000000..fc0cf02 --- /dev/null +++ b/comfortable_swipe/res/comfortable-swipe.desktop @@ -0,0 +1,8 @@ +[Desktop Entry] +Type=Application +Exec=comfortable-swipe start +Hidden=false +NoDisplay=false +X-GNOME-Autostart-enabled=true +Name=Comfortable Swipe +Comment=3 or 4 finger swipe gestures diff --git a/defaults.conf b/comfortable_swipe/res/defaults.conf similarity index 99% rename from defaults.conf rename to comfortable_swipe/res/defaults.conf index 7d201e3..9bb095b 100644 --- a/defaults.conf +++ b/comfortable_swipe/res/defaults.conf @@ -5,59 +5,46 @@ # # Refer to https://www.linux.org/threads/xdotool-keyboard.10528/ for a list of # keycodes you can use. - ################# # MISCELLANEOUS # ################# - # Threshold # Tweak this value depending on the sensitivity of your mousepad to perform # gestures. A higher value means less sensitive. -# # (Note: Sky is the limit! Can be as large as 1000.0) -# # Default: threshold = 0.0 threshold = 0.0 - ############################# # THREE / FOUR FINGER SWIPE # ############################# - # 3-finger swipe left # The default shortcut is switching to the right workspace. # Default: left3 = ctrl+alt+Right left3 = ctrl+alt+Right - -# 4-finger swipe left -# The default shortcut is moving current window to the right workspace. -# Default: left4=ctrl+alt+shift+Right -left4 = ctrl+alt+shift+Right - # 3-finger swipe right # The default shortcut is switching to the left workspace. # Default: right3 = ctrl+alt+Left right3 = ctrl+alt+Left - +# 4-finger swipe left +# The default shortcut is moving current window to the right workspace. +# Default: left4=ctrl+alt+shift+Right +left4 = ctrl+alt+shift+Right # 4-finger swipe right # The default shortcut is moving current window to the left workspace. # Default: right4=ctrl+alt+shift+Left right4 = ctrl+alt+shift+Left - # 3-finger swipe up # The default shortcut is switching to the workspace below. # Default: up3 = ctrl+alt+Down up3 = ctrl+alt+Down - -# 4-finger swipe up -# The default shortcut is moving current window to the bottom workspace. -# Default: ctrl+alt+shift+Down -up4 = ctrl+alt+shift+Down - # 3-finger swipe down # The default shortcut is switching to the workspace above. # Default: down3 = ctrl+alt+Up down3 = ctrl+alt+Up - +# 4-finger swipe up +# The default shortcut is moving current window to the bottom workspace. +# Default: ctrl+alt+shift+Down +up4 = ctrl+alt+shift+Down # 4-finger swipe down # The default shortcut is moving current window to the above workspace. # Default: ctrl+alt+shift+Up diff --git a/comfortable_swipe/status.py b/comfortable_swipe/status.py new file mode 100644 index 0000000..6a51500 --- /dev/null +++ b/comfortable_swipe/status.py @@ -0,0 +1,22 @@ +from __future__ import print_function + +import os + +from comfortable_swipe import autostart +from comfortable_swipe.cpp import service +from comfortable_swipe.constants import NAME, exe + +def print_status(): + service.status() + print('autostart is', autostart.get_status().upper()) + print('{} program is {}'.format(NAME, 'RUNNING' if is_running() else 'STOPPED')) + + +def is_running(): + import psutil + for process in psutil.process_iter(): + process_args = [process.name()] + process.cmdline() + for index in range(len(process_args) - 1): + if process_args[index + 1] == 'start' and process_args[index].endswith(NAME): + return True + return False diff --git a/cpp/_index.cpp b/cpp/_index.cpp new file mode 100644 index 0000000..e274cfb --- /dev/null +++ b/cpp/_index.cpp @@ -0,0 +1,8 @@ +#ifndef __COMFORTABLE_SWIPE__index_cpp__ +#define __COMFORTABLE_SWIPE__index_cpp__ + +#include "gesture/_index.cpp" +#include "service/_index.cpp" +#include "util/_index.cpp" + +#endif /* __COMFORTABLE_SWIPE__index_cpp__ */ diff --git a/cpp/_index.hpp b/cpp/_index.hpp new file mode 100644 index 0000000..ce0849d --- /dev/null +++ b/cpp/_index.hpp @@ -0,0 +1,8 @@ +#ifndef __COMFORTABLE_SWIPE__index_hpp__ +#define __COMFORTABLE_SWIPE__index_hpp__ + +#include "gesture/_index.hpp" +#include "service/_index.hpp" +#include "util/_index.hpp" + +#endif /* __COMFORTABLE_SWIPE__index_hpp__ */ diff --git a/cpp/_macro.cpp b/cpp/_macro.cpp new file mode 100644 index 0000000..bffa78a --- /dev/null +++ b/cpp/_macro.cpp @@ -0,0 +1,12 @@ +#ifndef __COMFORTABLE_SWIPE__macro_hpp__ +#define __COMFORTABLE_SWIPE__macro_hpp__ + +#ifndef COMFORTABLE_SWIPE_CONFIG +#error "COMFORTABLE_SWIPE_CONFIG must be defined." +#endif /* COMFORTABLE_SWIPE_CONFIG */ + +#ifndef COMFORTABLE_SWIPE_VERSION +#warning "COMFORTABLE_SWIPE_VERSION is not defined." +#endif /* COMFORTABLE_SWIPE_VERSION */ + +#endif /* __COMFORTABLE_SWIPE__macro_hpp__ */ diff --git a/cpp/_python.cpp b/cpp/_python.cpp new file mode 100644 index 0000000..4f1cd9a --- /dev/null +++ b/cpp/_python.cpp @@ -0,0 +1,7 @@ +#ifndef __COMFORTABLE_SWIPE__python_cpp__ +#define __COMFORTABLE_SWIPE__python_cpp__ + +#include "service/_python.cpp" +#include "comfortable-swipe.cpp" + +#endif /* __COMFORTABLE_SWIPE__python_cpp__ */ diff --git a/cpp/comfortable-swipe b/cpp/comfortable-swipe new file mode 100644 index 0000000..6465c73 --- /dev/null +++ b/cpp/comfortable-swipe @@ -0,0 +1 @@ +#include "comfortable-swipe.cpp" diff --git a/lib/util/conf_filename.cpp b/cpp/comfortable-swipe.cpp similarity index 62% rename from lib/util/conf_filename.cpp rename to cpp/comfortable-swipe.cpp index 5de5ae9..1f10dd1 100644 --- a/lib/util/conf_filename.cpp +++ b/cpp/comfortable-swipe.cpp @@ -1,5 +1,5 @@ -#ifndef __COMFORTABLE_SWIPE__util_conf_filename__ -#define __COMFORTABLE_SWIPE__util_conf_filename__ +#ifndef __COMFORTABLE_SWIPE__ +#define __COMFORTABLE_SWIPE__ /* Comfortable Swipe @@ -19,17 +19,8 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . */ -#include "../index.hpp" +#include "_macro.cpp" +#include "_index.hpp" +#include "_index.cpp" -namespace comfortable_swipe::util -{ - /** - * The path where the configuration file is located. - */ - constexpr const char* conf_filename() - { - return __COMFORTABLE_SWIPE__CONFIG__; - } -} - -#endif /* __COMFORTABLE_SWIPE__util_conf_filename__ */ +#endif /* __COMFORTABLE_SWIPE__ */ diff --git a/cpp/gesture/_index.cpp b/cpp/gesture/_index.cpp new file mode 100644 index 0000000..5de8bb2 --- /dev/null +++ b/cpp/gesture/_index.cpp @@ -0,0 +1,9 @@ +#ifndef __COMFORTABLE_SWIPE__gesture_index_cpp__ +#define __COMFORTABLE_SWIPE__gesture_index_cpp__ + +#include "_index.hpp" +#include "xdo_gesture.cpp" +#include "swipe_gesture.cpp" +#include "swipe_gesture.regex.cpp" + +#endif /* __COMFORTABLE_SWIPE__gesture_index_cpp__ */ diff --git a/cpp/gesture/_index.hpp b/cpp/gesture/_index.hpp new file mode 100644 index 0000000..9c097c5 --- /dev/null +++ b/cpp/gesture/_index.hpp @@ -0,0 +1,7 @@ +#ifndef __COMFORTABLE_SWIPE__gesture_index_hpp__ +#define __COMFORTABLE_SWIPE__gesture_index_hpp__ + +#include "xdo_gesture.h" +#include "swipe_gesture.h" + +#endif /* __COMFORTABLE_SWIPE__gesture_index_hpp__ */ diff --git a/cpp/gesture/swipe_gesture.cpp b/cpp/gesture/swipe_gesture.cpp new file mode 100644 index 0000000..b1c7ebc --- /dev/null +++ b/cpp/gesture/swipe_gesture.cpp @@ -0,0 +1,216 @@ +#ifndef __COMFORTABLE_SWIPE__gesture_swipe_gesture__ +#define __COMFORTABLE_SWIPE__gesture_swipe_gesture__ + +/* +Comfortable Swipe +by Rico Tiongson + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ + +#include // std::cout, std::endl +#include // std::stoi, std::stof +#include // std::regex, std::regex_match, std::cmatch +#include +#include "swipe_gesture.h" + +extern "C" +{ + #include // xdo, xdo_new, xdo_free, + // xdo_get_mouse_location + // CURRENT_WINDOW +} + +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); + } + + /** + * 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) + { + int mask = 0; + if (this->fingers == 3) mask |= swipe_gesture::MSK_THREE_FINGERS; + else if (this->fingers == 4) mask |= swipe_gesture::MSK_FOUR_FINGERS; + + const float absx = x >= 0 ? x : -x; + const float absy = y >= 0 ? y : -y; + if (absx > absy) + { // horizontal + mask |= swipe_gesture::MSK_HORIZONTAL; + if (x < 0) + mask |= swipe_gesture::MSK_NEGATIVE; + else + mask |= swipe_gesture::MSK_POSITIVE; + } + else /* std::abs(x) <= std::abs(y) */ + { // vertical + mask |= swipe_gesture::MSK_VERTICAL; + if (y < 0) + mask |= swipe_gesture::MSK_NEGATIVE; + else + mask |= swipe_gesture::MSK_POSITIVE; + } + + // send command on fresh OR opposite gesture + if (this->previous_gesture == swipe_gesture::FRESH + || this->previous_gesture == (mask ^ swipe_gesture::MSK_POSITIVE)) + { + xdo_send_keysequence_window(this->xdo, CURRENTWINDOW, swipe_gesture::commands[mask], 0); + this->x = this->y = 0; + this->previous_gesture = mask; + std::cout << "SWIPE " << swipe_gesture::command_map[mask] << std::endl; + } + } + } + + /** + * Hook on end of swipe gesture. + */ + 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) + { + // 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 new file mode 100644 index 0000000..4e843d6 --- /dev/null +++ b/cpp/gesture/swipe_gesture.h @@ -0,0 +1,85 @@ +#ifndef __COMFORTABLE_SWIPE__gesture_swipe_gesture_h__ +#define __COMFORTABLE_SWIPE__gesture_swipe_gesture_h__ + +/* +Comfortable Swipe +by Rico Tiongson + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ + +#include "xdo_gesture.h" + +namespace comfortable_swipe +{ + namespace gesture + { + 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(); + + // 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; + + protected: + // location of mouse + int screen_num, ix, iy; + + // 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; + + 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; + }; + } +} + +#endif /* __COMFORTABLE_SWIPE__gesture_swipe_gesture_h__ */ diff --git a/cpp/gesture/swipe_gesture.regex.cpp b/cpp/gesture/swipe_gesture.regex.cpp new file mode 100644 index 0000000..ded720f --- /dev/null +++ b/cpp/gesture/swipe_gesture.regex.cpp @@ -0,0 +1,94 @@ +#ifndef __COMFORTABLE_SWIPE__gesture_swipe_gesture_regex__ +#define __COMFORTABLE_SWIPE__gesture_swipe_gesture_regex__ + +/* +Comfortable Swipe +by Rico Tiongson + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ + +#include "swipe_gesture.h" + +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. + * + * 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 + ; + + // 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 ")" + + /** + * 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 + } +} + +#endif /* __COMFORTABLE_SWIPE__gesture_swipe_gesture_regex__ */ diff --git a/lib/gesture/xdo_gesture.cpp b/cpp/gesture/xdo_gesture.cpp similarity index 70% rename from lib/gesture/xdo_gesture.cpp rename to cpp/gesture/xdo_gesture.cpp index 3afda7d..7b044c7 100644 --- a/lib/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/lib/gesture/xdo_gesture.h b/cpp/gesture/xdo_gesture.h similarity index 100% rename from lib/gesture/xdo_gesture.h rename to cpp/gesture/xdo_gesture.h diff --git a/cpp/service/_index.cpp b/cpp/service/_index.cpp new file mode 100644 index 0000000..3aeb559 --- /dev/null +++ b/cpp/service/_index.cpp @@ -0,0 +1,13 @@ +#ifndef __COMFORTABLE_SWIPE__service_index_cpp__ +#define __COMFORTABLE_SWIPE__service_index_cpp__ + +#include "_index.hpp" +#include "buffer.cpp" +#include "debug.cpp" +#include "help.cpp" +#include "restart.cpp" +#include "start.cpp" +#include "status.cpp" +#include "stop.cpp" + +#endif /* __COMFORTABLE_SWIPE__service_index_cpp__ */ diff --git a/cpp/service/_index.hpp b/cpp/service/_index.hpp new file mode 100644 index 0000000..584787e --- /dev/null +++ b/cpp/service/_index.hpp @@ -0,0 +1,21 @@ +#ifndef __COMFORTABLE_SWIPE__service_index_hpp__ +#define __COMFORTABLE_SWIPE__service_index_hpp__ + +#include // std::map +#include // std::string + +namespace comfortable_swipe +{ + namespace service + { + void buffer(); + void debug(); + void help(); + void restart(); + void start(); + void stop(); + void status(); + } +} + +#endif /* __COMFORTABLE_SWIPE__service_index_hpp__ */ diff --git a/cpp/service/_python.cpp b/cpp/service/_python.cpp new file mode 100644 index 0000000..2274233 --- /dev/null +++ b/cpp/service/_python.cpp @@ -0,0 +1,91 @@ +#ifndef __COMFORTABLE_SWIPE__service_python__ +#define __COMFORTABLE_SWIPE__service_python__ + +#include "_index.hpp" +extern "C" +{ + #include +} + +// export as python module +namespace comfortable_swipe +{ + 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; + } + } +} + +// initialize module +#if PY_MAJOR_VERSION >= 3 + PyMODINIT_FUNC + PyInit_service(void) + { + using comfortable_swipe::service::python::module_def; + using comfortable_swipe::service::python::module; + if (module != NULL) return module; + return module = PyModule_Create(&module_def); + } +#else /* PY_MAJOR_VERSION < 3 */ + PyMODINIT_FUNC + initservice(void) + { + using comfortable_swipe::service::python::methods; + using comfortable_swipe::service::python::module; + if (module != NULL) return; + module = Py_InitModule("service", methods); + } +#endif /* PY_MAJOR_VERSION */ + +#endif /* __COMFORTABLE_SWIPE__service_python__ */ diff --git a/lib/service/buffer.cpp b/cpp/service/buffer.cpp similarity index 88% rename from lib/service/buffer.cpp rename to cpp/service/buffer.cpp index 7edd7b6..082943e 100644 --- a/lib/service/buffer.cpp +++ b/cpp/service/buffer.cpp @@ -19,9 +19,10 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . */ +#include "../_macro.cpp" +#include "../util/_index.hpp" +#include "../gesture/_index.hpp" #include // fgets_unlocked, stdin -#include // std::ios, std::cout, std::cin -#include "../index.hpp" /** * Starts the comfortable-swipe service by buffering libinput debug-events. @@ -30,13 +31,8 @@ namespace comfortable_swipe::service { void buffer() { - std::ios::sync_with_stdio(false); - std::cin.tie(0); - std::cout.tie(0); - std::cout.flush(); - // read config file - auto config = comfortable_swipe::util::read_config_file(comfortable_swipe::util::conf_filename()); + auto config = comfortable_swipe::util::read_config_file(COMFORTABLE_SWIPE_CONFIG); // initialize swipe gesture handler comfortable_swipe::gesture::swipe_gesture swipe_gesture_handler diff --git a/lib/service/debug.cpp b/cpp/service/debug.cpp similarity index 74% rename from lib/service/debug.cpp rename to cpp/service/debug.cpp index 2efa702..b078bde 100644 --- a/lib/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 new file mode 100644 index 0000000..2ffbddd --- /dev/null +++ b/cpp/service/help.cpp @@ -0,0 +1,48 @@ +#ifndef __COMFORTABLE_SWIPE__service_help__ +#define __COMFORTABLE_SWIPE__service_help__ + +/* +Comfortable Swipe +by Rico Tiongson + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ + +#include // std::puts, std::printf + +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(""); + 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"); + } + } +} + +#endif /* __COMFORTABLE_SWIPE__service_help__ */ diff --git a/lib/service/restart.cpp b/cpp/service/restart.cpp similarity index 73% rename from lib/service/restart.cpp rename to cpp/service/restart.cpp index 28191c8..6559f4e 100644 --- a/lib/service/restart.cpp +++ b/cpp/service/restart.cpp @@ -19,17 +19,20 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . */ -#include "../index.hpp" +#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 new file mode 100644 index 0000000..618d901 --- /dev/null +++ b/cpp/service/start.cpp @@ -0,0 +1,66 @@ +#ifndef __COMFORTABLE_SWIPE__service_start__ +#define __COMFORTABLE_SWIPE__service_start__ + +/* +Comfortable Swipe +by Rico Tiongson + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ + +#include "_index.hpp" +#include // std::cin, std::cout, std::ios +#include // std::system +#include // pipe, fork, perror, exit + +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); + std::cout.tie(0); + std::cout.flush(); + + // redirect stdout to stdin + int fd[2]; + pipe(fd); // create the pipes + + 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(); + } + } +} + +#endif /* __COMFORTABLE_SWIPE__service_start__ */ diff --git a/cpp/service/status.cpp b/cpp/service/status.cpp new file mode 100644 index 0000000..e56fad7 --- /dev/null +++ b/cpp/service/status.cpp @@ -0,0 +1,78 @@ +#ifndef __COMFORTABLE_SWIPE__service_status__ +#define __COMFORTABLE_SWIPE__service_status__ + +/* +Comfortable Swipe +by Rico Tiongson + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ + +#include "../_macro.cpp" +#include "../util/_index.hpp" +#include "../gesture/_index.hpp" +#include // std::runtime_error +#include // popen, pclose, getpid, access, F_OK +#include // std::unique_ptr +#include // std::array +#include // std::atoi +#include // FILE, std::feof, std::fgets, std::printf +#include // std::cmatch, std::regex, std::regex_match + +namespace comfortable_swipe +{ + namespace service + { + /** + * Prints the status of comfortable-swipe. + */ + void status() + { + // std::printf("autostart is %s\n", autostart_on ? "ON" : "OFF"); + + // check status of configuration file + try + { + 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"); + + // 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()); + } + } + } +} + +#endif /* __COMFORTABLE_SWIPE__service_restart__ */ diff --git a/lib/service/stop.cpp b/cpp/service/stop.cpp similarity index 55% rename from lib/service/stop.cpp rename to cpp/service/stop.cpp index 7469c69..a4836a0 100644 --- a/lib/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.cpp b/cpp/util/_index.cpp new file mode 100644 index 0000000..6dc6d8c --- /dev/null +++ b/cpp/util/_index.cpp @@ -0,0 +1,7 @@ +#ifndef __COMFORTABLE_SWIPE__util_index_cpp__ +#define __COMFORTABLE_SWIPE__util_index_cpp__ + +#include "_index.hpp" +#include "read_config_file.cpp" + +#endif /* __COMFORTABLE_SWIPE__util_index_cpp__ */ diff --git a/cpp/util/_index.hpp b/cpp/util/_index.hpp new file mode 100644 index 0000000..77226b3 --- /dev/null +++ b/cpp/util/_index.hpp @@ -0,0 +1,15 @@ +#ifndef __COMFORTABLE_SWIPE__util_index_hpp__ +#define __COMFORTABLE_SWIPE__util_index_hpp__ + +#include // std::map +#include // std::string + +namespace comfortable_swipe +{ + namespace util + { + std::map read_config_file(const char*); + } +} + +#endif /* __COMFORTABLE_SWIPE__util_index_hpp__ */ diff --git a/cpp/util/read_config_file.cpp b/cpp/util/read_config_file.cpp new file mode 100644 index 0000000..6512bd2 --- /dev/null +++ b/cpp/util/read_config_file.cpp @@ -0,0 +1,107 @@ +#ifndef __COMFORTABLE_SWIPE__util_read_config_file__ +#define __COMFORTABLE_SWIPE__util_read_config_file__ + +/* +Comfortable Swipe +by Rico Tiongson + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ + +#include // std::map +#include // std::string +#include // std::ifstream +#include // std::endl, std::getline +#include // std::ostringstream +#include // exit +#include // std::isspace +#include // std::runtime_error + +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 read_config_file(const char* filename) + { + + std::map conf; + std::ifstream fin(filename, std::ios::in); + + if (!fin.is_open()) + { + 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 (line[i] == '#') // skip comments + break; + if (line[i] == '=') // flag equal sign + { + 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]); + } + } + + // 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; + } + } +} + +#endif /* __COMFORTABLE_SWIPE__util_read_config_file__ */ diff --git a/install b/install deleted file mode 100755 index 9de80c6..0000000 --- a/install +++ /dev/null @@ -1,82 +0,0 @@ -#!/bin/bash -# prefer running as root -DIR=$(dirname $0) -PROGRAM=/usr/local/bin/comfortable-swipe -COMPILE=$DIR/comfortable-swipe.compile.sh -CONF_PATH=/usr/local/share/comfortable-swipe/comfortable-swipe.conf -DCONF_PATH=$DIR/defaults.conf -OLD_CONF_PATH=${XDG_CONFIG_HOME:-$HOME/.config}/comfortable-swipe.conf - -if [ -x "$(command -v $PROGRAM)" ]; then - # stop any running comfortable-swipe if it exists - $PROGRAM stop -fi - -#copy config file -abort () { - exec echo "Installation aborted" -} -sudo mkdir -p $(dirname $CONF_PATH) || abort - -# check if "-y" or "--yes" is passed as an argument -YES=false -while test $# -gt 0 -do - case "$1" in - -y) YES=true - ;; - --yes) YES=true - ;; - esac - shift -done - -sudo chown $USER $(dirname $CONF_PATH) -if [ ! -f $CONF_PATH ]; then - if [ ! -f $OLD_CONF_PATH ]; then - # old config file not found, create from scratch - cat $DCONF_PATH > $CONF_PATH || abort - else - # old config file found, move to the new path - cat $OLD_CONF_PATH > $CONF_PATH || abort - echo "Configuration copied from $OLD_CONF_PATH to $CONF_PATH" - fi -else - # config file found, ask user if overwrite - echo "Old conf file found in $CONF_PATH" - if [ $YES == false ]; then - read -r -p "Keep the old conf file? (default: yes) [Y/n] " response - response=${response,,} # tolower - if [[ "$response" =~ ^(no|n)$ ]]; then - read -r -p "Conf file will be overwritten. Are you sure? [Y/n] " response - response=${response,,} - if [[ "$response" =~ ^(yes|y)$ ]]; then - cat $DCONF_PATH > $CONF_PATH || abort - else - abort - fi - fi - fi -fi - -echo "Installing..." - -# remove existing comfortable-swipe -if [ -x "$(command -v $PROGRAM)" ]; then - sudo rm -f $(which comfortable-swipe) -fi - -# compile library -sudo $COMPILE $PROGRAM || abort - -# add permissions to input group (defer) -# GROUP=$(ls -l /dev/input/event* | awk '{print $4}' | head --line=1) || abort - -# toggle autostart twice to refresh any changes -$PROGRAM autostart > /dev/null || abort -$PROGRAM autostart > /dev/null || abort - -echo "Successfully installed comfortable-swipe." -echo "Configuration file is located at $CONF_PATH" -echo "" -echo "Try running 'comfortable-swipe start' to test." diff --git a/lib/comfortable_swipe b/lib/comfortable_swipe deleted file mode 100644 index 3ee260a..0000000 --- a/lib/comfortable_swipe +++ /dev/null @@ -1,44 +0,0 @@ -#ifndef __COMFORTABLE_SWIPE__ -#define __COMFORTABLE_SWIPE__ - -/* -Comfortable Swipe -by Rico Tiongson - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program. If not, see . -*/ - -#include "index.hpp" - -/** - * Make sure to include all implementation (.cpp) files below to be ready for export. - */ - -#include "gesture/xdo_gesture.cpp" -#include "gesture/swipe_gesture.cpp" -#include "gesture/swipe_gesture.regex.cpp" -#include "service/autostart.cpp" -#include "service/buffer.cpp" -#include "service/config.cpp" -#include "service/debug.cpp" -#include "service/help.cpp" -#include "service/restart.cpp" -#include "service/start.cpp" -#include "service/status.cpp" -#include "service/stop.cpp" -#include "util/autostart_filename.cpp" -#include "util/conf_filename.cpp" -#include "util/read_config_file.cpp" - -#endif /* __COMFORTABLE_SWIPE__ */ diff --git a/lib/gesture/swipe_gesture.cpp b/lib/gesture/swipe_gesture.cpp deleted file mode 100644 index a8ba7c9..0000000 --- a/lib/gesture/swipe_gesture.cpp +++ /dev/null @@ -1,214 +0,0 @@ -#ifndef __COMFORTABLE_SWIPE__gesture_swipe_gesture__ -#define __COMFORTABLE_SWIPE__gesture_swipe_gesture__ - -/* -Comfortable Swipe -by Rico Tiongson - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program. If not, see . -*/ - -#include // std::cout, std::endl -#include // std::stoi, std::stof -#include // std::regex, std::regex_match, std::cmatch -#include "swipe_gesture.h" - -extern "C" -{ - #include // xdo, xdo_new, xdo_free, - // xdo_get_mouse_location - // CURRENT_WINDOW -} - -namespace comfortable_swipe::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); - } - - /** - * 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) - { - int mask = 0; - if (this->fingers == 3) mask |= swipe_gesture::MSK_THREE_FINGERS; - else if (this->fingers == 4) mask |= swipe_gesture::MSK_FOUR_FINGERS; - - const float absx = x >= 0 ? x : -x; - const float absy = y >= 0 ? y : -y; - if (absx > absy) - { // horizontal - mask |= swipe_gesture::MSK_HORIZONTAL; - if (x < 0) - mask |= swipe_gesture::MSK_NEGATIVE; - else - mask |= swipe_gesture::MSK_POSITIVE; - } - else /* std::abs(x) <= std::abs(y) */ - { // vertical - mask |= swipe_gesture::MSK_VERTICAL; - if (y < 0) - mask |= swipe_gesture::MSK_NEGATIVE; - else - mask |= swipe_gesture::MSK_POSITIVE; - } - - // send command on fresh OR opposite gesture - if (this->previous_gesture == swipe_gesture::FRESH - || this->previous_gesture == (mask ^ swipe_gesture::MSK_POSITIVE)) - { - xdo_send_keysequence_window(this->xdo, CURRENTWINDOW, swipe_gesture::commands[mask], 0); - this->x = this->y = 0; - this->previous_gesture = mask; - std::cout << "SWIPE " << swipe_gesture::command_map[mask] << std::endl; - } - } - } - - /** - * Hook on end of swipe gesture. - */ - 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) - { - - // prepare regex matchers (will only load at most once) - 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/lib/gesture/swipe_gesture.h b/lib/gesture/swipe_gesture.h deleted file mode 100644 index 86ec3bd..0000000 --- a/lib/gesture/swipe_gesture.h +++ /dev/null @@ -1,90 +0,0 @@ -#ifndef __COMFORTABLE_SWIPE__gesture_swipe_gesture_h__ -#define __COMFORTABLE_SWIPE__gesture_swipe_gesture_h__ - -/* -Comfortable Swipe -by Rico Tiongson - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program. If not, see . -*/ - -#include "xdo_gesture.h" - -#ifdef __cplusplus -extern "C" { -#endif - -namespace comfortable_swipe::gesture -{ - 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(); - - // 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; - - protected: - // location of mouse - int screen_num, ix, iy; - - // 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; - - 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/lib/gesture/swipe_gesture.regex.cpp b/lib/gesture/swipe_gesture.regex.cpp deleted file mode 100644 index 7dd1d04..0000000 --- a/lib/gesture/swipe_gesture.regex.cpp +++ /dev/null @@ -1,91 +0,0 @@ -#ifndef __COMFORTABLE_SWIPE__gesture_swipe_gesture_regex__ -#define __COMFORTABLE_SWIPE__gesture_swipe_gesture_regex__ - -/* -Comfortable Swipe -by Rico Tiongson - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program. If not, see . -*/ - -#include "swipe_gesture.h" - -namespace comfortable_swipe::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 - ; - - // 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 ")" - - /** - * 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 -} - -#endif /* __COMFORTABLE_SWIPE__gesture_swipe_gesture_regex__ */ diff --git a/lib/index.hpp b/lib/index.hpp deleted file mode 100644 index b54cc3e..0000000 --- a/lib/index.hpp +++ /dev/null @@ -1,64 +0,0 @@ -#ifndef __COMFORTABLE_SWIPE__index_hpp__ -#define __COMFORTABLE_SWIPE__index_hpp__ - -/* -Comfortable Swipe -by Rico Tiongson - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program. If not, see . -*/ - -// global defines -#ifndef __COMFORTABLE_SWIPE__PROGRAM__ -#define __COMFORTABLE_SWIPE__PROGRAM__ "/usr/local/bin/comfortable-swipe" -#endif /* __COMFORTABLE_SWIPE__PROGRAM__ */ - -#ifndef __COMFORTABLE_SWIPE__CONFIG__ -#define __COMFORTABLE_SWIPE__CONFIG__ "/usr/local/share/comfortable-swipe/comfortable-swipe.conf" -#endif /* __COMFORTABLE_SWIPE__CONFIG__ */ - -#include // std::map -#include // std::string - -/** - * Make sure to include your header files here so that they can be imported by other modules. - */ -#include "gesture/xdo_gesture.h" -#include "gesture/swipe_gesture.h" -extern "C" -{ - namespace comfortable_swipe - { - namespace util - { - const char* autostart_filename(); - constexpr const char* conf_filename(); - std::map read_config_file(const char*); - } - namespace service - { - void autostart(); - void buffer(); - void config(); - void debug(); - void help(); - void restart(); - void start(); - void status(); - void stop(); - } - } -} - -#endif /* __COMFORTABLE_SWIPE__index_hpp__ */ diff --git a/lib/service/autostart.cpp b/lib/service/autostart.cpp deleted file mode 100644 index 1a4575f..0000000 --- a/lib/service/autostart.cpp +++ /dev/null @@ -1,75 +0,0 @@ -#ifndef __COMFORTABLE_SWIPE__service_autostart__ -#define __COMFORTABLE_SWIPE__service_autostart__ - -/* -Comfortable Swipe -by Rico Tiongson - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program. If not, see . -*/ - -#include // std::cerr, std::cout, std::endl -#include // std::ifstream, std::ofstream -#include // std::string -#include // std::remove -#include // std::system -#include "../index.hpp" - -namespace comfortable_swipe::service -{ - /** - * Toggles automatic startup of comfortable swipe. - */ - void autostart() - { - using comfortable_swipe::util::autostart_filename; - - const std::string& path = autostart_filename(); - if (std::ifstream(path.data()).good()) - { - // file found, delete it - if (std::remove(path.data()) != 0) - std::cerr << "Error: failed to switch off autostart. " - << "Maybe the autostart file is in use?" - << std::endl; - else - std::cout << "Autostart switched off" << std::endl; - } - else { - // file not found, create it - int result = std::system(("mkdir -p $(dirname " + path + ")").data()); - std::ofstream fout(path.data()); - if (result != 0 || !fout.good()) - std::cerr << "Error: failed to switch on autostart. " - << "Are you sure you have the permissions?" - << std::endl; - else { - fout << - "[Desktop Entry]\n" - "Type=Application\n" - "Exec=bash -c \"" - __COMFORTABLE_SWIPE__PROGRAM__ - " start\"\n" - "Hidden=false\n" - "NoDisplay=false\n" - "X-GNOME-Autostart-enabled=true\n" - "Name=Comfortable Swipe\n" - "Comment=3 or 4 touchpad gestures\n"; - std::cout << "Autostart switched on" << std::endl; - } - } - } -} - -#endif /* __COMFORTABLE_SWIPE__service_autostart__ */ diff --git a/lib/service/config.cpp b/lib/service/config.cpp deleted file mode 100644 index 6bb02bd..0000000 --- a/lib/service/config.cpp +++ /dev/null @@ -1,38 +0,0 @@ -#ifndef __COMFORTABLE_SWIPE__service_config__ -#define __COMFORTABLE_SWIPE__service_config__ - -/* -Comfortable Swipe -by Rico Tiongson - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program. If not, see . -*/ - -#include "../index.hpp" -#include // std::puts - -namespace comfortable_swipe::service -{ - /** - * Prints where the config file of comfortable swipe is located. - * - * Usage: nano $(comfortable-swipe config) - */ - void config() - { - std::puts(comfortable_swipe::util::conf_filename()); - } -} - -#endif /* __COMFORTABLE_SWIPE__service_config__ */ diff --git a/lib/service/help.cpp b/lib/service/help.cpp deleted file mode 100644 index 80c2c85..0000000 --- a/lib/service/help.cpp +++ /dev/null @@ -1,49 +0,0 @@ -#ifndef __COMFORTABLE_SWIPE__service_help__ -#define __COMFORTABLE_SWIPE__service_help__ - -/* -Comfortable Swipe -by Rico Tiongson - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program. If not, see . -*/ - -#include // std::puts, std::printf -#include "../index.hpp" - -namespace comfortable_swipe::service -{ - /** - * Shows the help window. - */ - void help() - { - using comfortable_swipe::util::conf_filename; - 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 [/usr/share/comfortable-swipe/comfortable-swipe.conf]"); - std::puts("debug - logs raw output from input events taken from libinput"); - std::puts("status - checks status of program and autostart"); - std::puts(""); - std::printf("Configuration file can be found in %s\n", conf_filename()); - } -} - -#endif /* __COMFORTABLE_SWIPE__service_help__ */ diff --git a/lib/service/start.cpp b/lib/service/start.cpp deleted file mode 100644 index 9ab566e..0000000 --- a/lib/service/start.cpp +++ /dev/null @@ -1,38 +0,0 @@ -#ifndef __COMFORTABLE_SWIPE__service_start__ -#define __COMFORTABLE_SWIPE__service_start__ - -/* -Comfortable Swipe -by Rico Tiongson - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program. If not, see . -*/ - -#include "../index.hpp" -#include // std::system - -namespace comfortable_swipe::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() - { - (void) std::system(__COMFORTABLE_SWIPE__PROGRAM__ " debug | " __COMFORTABLE_SWIPE__PROGRAM__ " buffer"); - } -} - -#endif /* __COMFORTABLE_SWIPE__service_start__ */ diff --git a/lib/service/status.cpp b/lib/service/status.cpp deleted file mode 100644 index a084de4..0000000 --- a/lib/service/status.cpp +++ /dev/null @@ -1,97 +0,0 @@ -#ifndef __COMFORTABLE_SWIPE__service_status__ -#define __COMFORTABLE_SWIPE__service_status__ - -/* -Comfortable Swipe -by Rico Tiongson - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program. If not, see . -*/ - -#include "../index.hpp" -#include // std::runtime_error -#include // popen, pclose, getpid, access, F_OK -#include // std::unique_ptr -#include // std::array -#include // std::atoi -#include // FILE, std::feof, std::fgets, std::printf -#include // std::cmatch, std::regex, std::regex_match - -namespace comfortable_swipe::service -{ - /** - * Prints the status of comfortable-swipe. - */ - void status() - { - // check if comfortable-swipe is running - bool running = false; - std::array buffer; - std::unique_ptr pipe(popen("pgrep -f comfortable-swipe", "r"), pclose); - if (pipe && !std::feof(pipe.get()) && std::fgets(buffer.data(), buffer.size(), pipe.get()) != NULL) - { - int pid = std::atoi(buffer.data()); - if (pid != getpid()) - running = true; - } - - // check if autostart is on - auto autostart_f = comfortable_swipe::util::autostart_filename(); - bool autostart_on = access(autostart_f, F_OK) != -1; - - // print status - std::printf("program is %s\n", running ? "ON" : "OFF"); - std::printf("autostart is %s\n", autostart_on ? "ON" : "OFF"); - std::printf("config file at %s\n", comfortable_swipe::util::conf_filename()); - - // check status of configuration file - try - { - auto config = comfortable_swipe::util::read_config_file(comfortable_swipe::util::conf_filename()); - - // print keys and values of config file - std::printf("\nConfigurations:\n"); - - // print threshold - if (config.count("threshold") > 0) - { - auto & threshold = config["threshold"]; - - // check if regex pattern matches threshold - std::cmatch matches; - bool ok = (std::regex_match(threshold.data(), matches, std::regex("^\\d+(?:\\.\\d+)??$")) != 0); - - // print status of threshold - std::printf(" %9s is %s (%s)\n", "threshold", ok ? "OK" : "INVALID", threshold.data()); - } - else - 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 is OK (%s)\n", command, config[command].data()); - else - std::printf(" %9s is OFF\n", command); - } - } - catch (const std::runtime_error& e) - { - std::printf("config error: %s\n", e.what()); - } - } -} - -#endif /* __COMFORTABLE_SWIPE__service_restart__ */ diff --git a/lib/util/autostart_filename.cpp b/lib/util/autostart_filename.cpp deleted file mode 100644 index d3b0046..0000000 --- a/lib/util/autostart_filename.cpp +++ /dev/null @@ -1,46 +0,0 @@ -#ifndef __COMFORTABLE_SWIPE__util_autostart_filename__ -#define __COMFORTABLE_SWIPE__util_autostart_filename__ - -/* -Comfortable Swipe -by Rico Tiongson - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program. If not, see . -*/ - -#include // std::string -#include // getenv - -namespace comfortable_swipe::util -{ - /** - * The path where the autostart configuration is located. - */ - const char* autostart_filename() - { - static std::string filename; - if (filename.empty()) { - const char* xdg_config = getenv("XDG_CONFIG_HOME"); - std::string config( - xdg_config == NULL - ? std::string(getenv("HOME")) + "/.config" - : xdg_config - ); - filename = config + "/autostart/comfortable-swipe.desktop"; - } - return filename.data(); - } -} - -#endif /* __COMFORTABLE_SWIPE__util_autostart_filename__ */ diff --git a/lib/util/read_config_file.cpp b/lib/util/read_config_file.cpp deleted file mode 100644 index 9fd5f0b..0000000 --- a/lib/util/read_config_file.cpp +++ /dev/null @@ -1,103 +0,0 @@ -#ifndef __COMFORTABLE_SWIPE__util_read_config_file__ -#define __COMFORTABLE_SWIPE__util_read_config_file__ - -/* -Comfortable Swipe -by Rico Tiongson - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program. If not, see . -*/ - -#include // std::map -#include // std::string -#include // std::ifstream -#include // std::ostringstream -#include // std::endl, std::getline -#include // exit -#include // std::isspace -#include // std::runtime_error - -namespace comfortable_swipe::util -{ - /** - * 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) - { - - std::map conf; - std::ifstream fin(filename); - - if (!fin.is_open()) - { - 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 (line[i] == '#') // skip comments - break; - if (line[i] == '=') // flag equal sign - { - 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]); - } - } - - // 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; - } -} -#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 new file mode 100644 index 0000000..8405c71 --- /dev/null +++ b/setup.py @@ -0,0 +1,179 @@ +from __future__ import print_function + +import os +import sys +import setuptools + +from shutil import copyfile +from setuptools import setup, find_packages +from setuptools.extension import Extension +from setuptools.command.develop import develop +from setuptools.command.install import install +from setuptools.command.easy_install import easy_install +from wheel.bdist_wheel import bdist_wheel + + +VERSION = '1.1.0-beta' +__CWD__ = os.getcwd() +__DIR__ = os.path.dirname(os.path.abspath(__file__)) +__URL__ = 'https://github.com/Hikari9/comfortable-swipe-ubuntu' + +extension_names = ['service'] + + + +try: + # make sure working directory is here + os.chdir(__DIR__) + + + # save README as long_description + with open('README.md', 'r') as README_file: + README = README_file.read() + + + # match constants with source + from comfortable_swipe.constants import * + + # include old conf paths to list from previous versions + conf_paths = [ + DEFAULT_CONFIG, + os.path.join(os.getenv('HOME', ''), '.config', 'comfortable-swipe', 'comfortable-swipe.conf'), + os.path.join('/usr/local/share', 'comfortable-swipe', 'comfortable-swipe.conf'), + CONFIG + ] + + # for C++ library + cpp_macros = dict( + COMFORTABLE_SWIPE_VERSION='"{}"'.format(VERSION), + COMFORTABLE_SWIPE_CONFIG='"{}"'.format(CONFIG) + ) + + # read C++ libraries for comfortable swipe + extensions = [Extension( + 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', '-std=c++11', '-lstdc++'], + libraries=['xdo'] + ) for extension_name in extension_names] + + + class Command: + outer_installer = None + outer_uninstaller = None + + def pre_install(self): + # make sure only outer install script will run post_install + if self.__class__.outer_installer is not None: return + self.__class__.outer_installer = self + print('running pre_install') + + def post_install(self): + # make sure post_install will only run when command is outer installer + if self.__class__.outer_installer is not self: return + print('running post_install') + + # create program/config directories + if not os.path.exists(os.path.dirname(CONFIG)): + os.makedirs(os.path.dirname(CONFIG)) + + # copy any of the old config files + conf_files = [path for path in conf_paths if os.path.exists(path) and os.path.isfile(path)] + print('Using configuration file at', conf_files[-1]) + + if conf_files[-1] != CONFIG: + # new installation or upgrading from old version, copy to new location + copyfile(conf_files[-1], CONFIG) + if conf_files[-1] == DEFAULT_CONFIG: + # new installation - copy default configuration + print('Copying configuration file to', CONFIG) + else: + # upgrading - delete the deprecated config file (failsafe) + print('warning: depcrecated configuration file at', conf_files[-1]) + print(' you have to remove this manually') + + # enable autostart by default + from comfortable_swipe import autostart + autostart.set_status(autostart.ON) + print('Autostart created at', autostart.target_path()) + print('\nInstallation successful\nTry running: {} start'.format(NAME)) + + def pre_uninstall(self): + # make sure only outer uninstall script will run post_uninstall + if self.__class__.outer_uninstaller is not None: return + self.__class__.outer_uninstaller = self + print('running pre_uninstall') + + + def post_uninstall(self): + # make sure post_uninstall will only run when command is outer uninstaller + if self.__class__.outer_uninstaller is not self: return + print('running post_uninstall') + from comfortable_swipe import autostart + if autostart.get_status() is autostart.ON: + print('Removing autostart at', autostart.target_path()) + autostart.set_status(autostart.OFF) + + # add post_install script to install method + def wrap_command(base_cls, uninstall=False): + class InstallCommand(Command, base_cls): + def run(self): + self.pre_uninstall() if uninstall and self.uninstall else self.pre_install() + base_cls.run(self) + self.post_uninstall() if uninstall and self.uninstall else self.post_install() + + InstallCommand.__name__ = base_cls.__name__ + return InstallCommand + + # Override command classes here + cmdclass = dict( + install=wrap_command(install), + easy_install=wrap_command(easy_install), + develop=wrap_command(develop, uninstall=True), + 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 = [ + 'Development Status :: 4 - Beta' + 'Intended Audience :: End Users/Desktop', + 'Operating System :: POSIX :: Linux', + 'Operating System :: Unix', + 'Programming Language :: C++', + 'Programming Language :: Python :: 2.7', + 'Programming Language :: Python :: 3.5', + 'Programming Language :: Python :: 3.6', + 'Programming Language :: Python :: 3.7', + 'Programming Language :: Python :: 3.8', + 'Environment :: Console' + ] + + # setup python script + setup_script = setup( + name=NAME, + version=VERSION, + description=DESCRIPTION, + long_description=README, + license='MIT', + author='Rico Tiongson', + author_email='thericotiongson@gmail.com', + url=__URL__, + zip_safe=False, + packages=find_packages(), + include_package_data=True, + entry_points=dict(console_scripts=['{}={}.__main__:main'.format(NAME, PYTHON_NAME)]), + ext_modules=extensions, + cmdclass=cmdclass, + install_requires=install_requires, + classifiers=classifiers + ) + +finally: + # move working directory back to where it was before + os.chdir(__CWD__) 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 diff --git a/uninstall b/uninstall deleted file mode 100644 index 900c2f5..0000000 --- a/uninstall +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/bash -echo "Uninstalling..." -rm ${XDG_CONFIG_HOME:-$HOME/.config}/autostart/comfortable-swipe.desktop 2> /dev/null -comfortable-swipe stop 2> /dev/null -rm $HOME/.local/bin/comfortable-swipe 2> /dev/null # compat -sudo rm /usr/local/bin/comfortable-swipe 2> /dev/null -echo "Successfully uninstalled comfortable-swipe"