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/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..a6e8ee3 100644
--- a/README.md
+++ b/README.md
@@ -5,10 +5,10 @@ Comfortable, seamless, and fast 3-finger (and 4-finger) touchpad swipe gestures
## Installation
-1. Install git, libinput, and g++
+1. Install Python3, libinput, and g++
```bash
- sudo apt-get install git libinput-tools libxdo-dev g++
+ sudo apt-get install git python3-dev libinput-tools libxdo-dev
```
2. Clone this repository
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..164a335
--- /dev/null
+++ b/comfortable_swipe/autostart.py
@@ -0,0 +1,61 @@
+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:
+ 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/lib/gesture/swipe_gesture.cpp b/cpp/gesture/swipe_gesture.cpp
similarity index 99%
rename from lib/gesture/swipe_gesture.cpp
rename to cpp/gesture/swipe_gesture.cpp
index a8ba7c9..9056911 100644
--- a/lib/gesture/swipe_gesture.cpp
+++ b/cpp/gesture/swipe_gesture.cpp
@@ -22,6 +22,7 @@ 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"
@@ -140,8 +141,6 @@ namespace comfortable_swipe::gesture
*/
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);
diff --git a/lib/gesture/swipe_gesture.h b/cpp/gesture/swipe_gesture.h
similarity index 100%
rename from lib/gesture/swipe_gesture.h
rename to cpp/gesture/swipe_gesture.h
diff --git a/lib/gesture/swipe_gesture.regex.cpp b/cpp/gesture/swipe_gesture.regex.cpp
similarity index 100%
rename from lib/gesture/swipe_gesture.regex.cpp
rename to cpp/gesture/swipe_gesture.regex.cpp
diff --git a/lib/gesture/xdo_gesture.cpp b/cpp/gesture/xdo_gesture.cpp
similarity index 100%
rename from lib/gesture/xdo_gesture.cpp
rename to cpp/gesture/xdo_gesture.cpp
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..25af404
--- /dev/null
+++ b/cpp/service/_index.hpp
@@ -0,0 +1,24 @@
+#ifndef __COMFORTABLE_SWIPE__service_index_hpp__
+#define __COMFORTABLE_SWIPE__service_index_hpp__
+
+#include