Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use comfortable-swipe as systemd service #15

Closed
wants to merge 8 commits into from
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
.log
64 changes: 32 additions & 32 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,43 +28,39 @@ Comfortable, seamless, and fast 3-finger (and 4-finger) touchpad swipe gestures

## How to Run

1. Make sure `~/.local/bin/` is added to your PATH.
2. Run

```
comfortable-swipe start
```

3. Optional: Automatically run on startup
Comfortable swipe should already be running as a service upon installation. Some notes:

```
comfortable-swipe autostart
```
- The program makes use of **keyboard gestures** for swiping (e.g. `ctrl+alt+Right`)
- By default, comfortable swipe uses Ubuntu workspace shortcuts (see [configurations](#configurations)).

### Permissions
Sometimes, you'll need some permissions to read touchpad input data.
Useful References:

1. Find out your permission group with `ls -l /dev/input/event*`
```bash
$ ls -l /dev/input/event*
- [Xdotool keycodes](https://www.linux.org/threads/xdotool-keyboard.10528/)
- [How to turn on Workspaces?](https://askubuntu.com/questions/260510/how-do-i-turn-on-workspaces-why-do-i-only-have-one-workspace)
- [How to set keyboard shortcuts in Ubuntu](https://help.ubuntu.com/stable/ubuntu-help/keyboard-shortcuts-set.html)

crw-rw---- 1 root input 13, 64 Oct 23 23:09 /dev/input/event0
crw-rw---- 1 root input 13, 65 Oct 23 23:09 /dev/input/event1
crw-rw---- 1 root input 13, 66 Oct 23 23:09 /dev/input/event2
crw-rw---- 1 root input 13, 67 Oct 23 23:09 /dev/input/event3
```
### Other Commands

2. Check the fourth column (e.g. `input`) then run:
```bash
sudo gpasswd -a $USER input
```
> Note: Don't forget to input your `sudo` password!
You can run `comfortable-swipe help` to see a list of commands:

```
$ comfortable-swipe help

3. ***Important***: Log out / Log back in
comfortable-swipe [start|stop|status|restart|buffer|help]

## Configurations
The configuration file is located at `~/.config/comfortable-swipe.conf`.
Make sure to run `comfortable-swipe restart` after making changes.
start - starts 3/4-finger gesture service
stop - stops 3/4-finger gesture service
status - shows the status of the program (service log)
restart - stops then starts 3/4-finger gesture service
buffer - parses output of libinput-debug-events
help - shows the help dialog

Configuration file can be found in /usr/local/share/comfortable-swipe.conf
```

### Configurations
The configuration file is located at `/usr/local/share/comfortable-swipe.conf`.
Run `comfortable-swipe restart` after making changes.

Property | Description | Default Value | Default Behavior
--------- | ----------- | -------------- | -----
Expand All @@ -79,7 +75,11 @@ down3 | 3-finger swipe down | ctrl+shift+Down | switch to above workspace
down4 | 4-finger swipe down | ctrl+alt+shift+Up | move window to above workpace

## Uninstall
Download the `uninstall` script then run `bash uninstall`
Clone the repository then run `bash uninstall`.

## Bug Reports
Create an issue [here](https://github.com/Hikari9/comfortable-swipe-ubuntu/issues/new) to report a bug.
Create an issue [here](https://github.com/Hikari9/comfortable-swipe-ubuntu/issues/new) to report a bug. Please make sure
to add the following to your issue:

1. Content of `.log` (found in the cloned folder)
2. Output of `comfortable-swipe status`
78 changes: 63 additions & 15 deletions install
Original file line number Diff line number Diff line change
@@ -1,20 +1,37 @@
#!/bin/bash
# prefer running as root
if [ $(id -u) != "0" ]; then
sudo bash "$0" "$@"
exit $?
fi

echo "
Install $(date)" >> .log

DIR=$(dirname $0)
PROGRAM=/usr/local/bin/comfortable-swipe
CONF_PATH=/usr/local/share/comfortable-swipe.conf
OLD_CONF_PATH=${XDG_CONFIG_HOME:-$HOME/.config}/comfortable-swipe.conf
DCONF_PATH=$DIR/src/defaults.conf

if [ -x "$(command -v $PROGRAM)" ]; then
# stop any running comfortable-swipe if it exists
$PROGRAM stop
# remove existing comfortable-swipe
rm $(which comfortable-swipe)
systemctl stop comfortable-swipe.service >> .log 2>> .log
systemctl disable comfortable-swipe.service >> .log 2>> .log
fi

#copy config file
mkdir -p ~/.config
DCONF_PATH=$DIR/src/defaults.conf
CONF_PATH=${XDG_CONFIG_HOME:-$HOME/.config}/comfortable-swipe.conf
mkdir -p $(dirname $CONF_PATH)

# copy config file
if [ ! -f $CONF_PATH ]; then
cat $DCONF_PATH > $CONF_PATH
if [ ! -f $OLD_CONF_PATH ]; then
# old config file not found, create from scratch
cp -a $DCONF_PATH $(dirname $CONF_PATH) >> .log 2>> .log
else
# old config file found, move to the new path
echo "Configuration copied from $OLD_CONF_PATH to $CONF_PATH"
cp -a $OLD_CONF_PATH $(dirname $CONF_PATH) >> .log 2>> .log
fi
else
# config file found, ask user if overwrite
echo "Old conf file found in $CONF_PATH"
Expand All @@ -24,18 +41,49 @@ else
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
cp -a $DCONF_PATH $(dirname $CONF_PATH) >> .log 2>> .log
else
echo "Installation aborted." >> .log
exec echo "Installation aborted."
fi
fi
fi

# install with g++
echo "Installing..."
# mkdir -p ~/.local/bin
g++ -std=c++11 -O2 $DIR/src/comfortable-swipe.cpp -lxdo -o $PROGRAM || exec echo "Installation aborted"
echo "
Install $(date)" >> .log
echo "Running g++" >> .log
g++ -std=c++11 -O2 $DIR/src/comfortable-swipe.cpp -lxdo -o $PROGRAM >> .log 2>> .log || exec echo "Installation aborted"

# add as service
SERVICE_PATH="/lib/systemd/system/comfortable-swipe.service"

echo "[Unit]
Description=Comfortable 3 or 4 finger gestures
After=display-manager.service keyboard-setup.service

[Service]
Environment=DISPLAY=$DISPLAY XAUTHORITY=$XAUTHORITY
ExecStart=$PROGRAM exec
Restart=always
RestartSec=2

[Install]
WantedBy=graphical.target" \
> $SERVICE_PATH

# run immediately
systemctl daemon-reload >> .log 2>> .log
systemctl enable comfortable-swipe.service >> .log 2>> .log
systemctl start comfortable-swipe.service >> .log 2>> .log
echo "Installation successful" >> .log

# toggle autostart twice to refresh any changes
$PROGRAM autostart > /dev/null || exec echo "Installation aborted"
$PROGRAM autostart > /dev/null || exec echo "Installation aborted"
# prvide success message
echo ""
echo "Successfully installed comfortable-swipe. Try swiping and see if it works."
echo "Configuration file is located at $CONF_PATH"

echo "Successfully installed. You may now run 'comfortable-swipe start'."
echo ""
echo "[Report bugs to https://github.com/Hikari9/comfortable-swipe-ubuntu/issues/new]"
echo ""
106 changes: 24 additions & 82 deletions src/comfortable-swipe.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,10 @@ namespace service {
void buffer();
void start();
void stop();
void status();
void restart();
void autostart();
void help();
void exec();
}

/* MAIN DRIVER FUNCTION */
Expand All @@ -79,9 +80,10 @@ int main(int argc, char** args) {
// select based on argument
if (arg == "start") service::start();
else if (arg == "stop") service::stop();
else if (arg == "status") service::status();
else if (arg == "restart") service::restart();
else if (arg == "buffer") service::buffer();
else if (arg == "autostart") service::autostart();
else if (arg == "exec") service::exec();
else service::help();
} else {
service::help();
Expand Down Expand Up @@ -186,36 +188,17 @@ namespace service {
// get the full path of the .conf file
string conf_filename() {
static string *filename = NULL;
if (filename == NULL) {
const char* xdg_config = getenv("XDG_CONFIG_HOME");
string config(
xdg_config == NULL
? string(getenv("HOME")) + "/.config"
: xdg_config
);
filename = new string(config + "/comfortable-swipe.conf");
}
return *filename;
}
// get the full path of the .desktop file associated
// with the autostart feature
string autostart_filename() {
static string *filename = NULL;
if (filename == NULL) {
const char* xdg_config = getenv("XDG_CONFIG_HOME");
string config(
xdg_config == NULL
? string(getenv("HOME")) + "/.config"
: xdg_config
);
filename = new string(config
+ "/autostart/comfortable-swipe.desktop");
}
if (filename == NULL)
filename = new string("/usr/local/share/comfortable-swipe.conf");
return *filename;
}
}

namespace service {
namespace service {
void exec() {
sleep(1);
Copy link
Owner Author

@Hikari9 Hikari9 Nov 15, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@schigum in issue #16

Hey, thanks so much for providing this.
It is exactly what I was looking for.

I'm running this on Ubuntu 17.10.
One oddity I noticed is that I have a delay of ~1s before the swipe gets executed and the output in >console appears (e.g. SWIPE down 4).
So I (quickly) swipe, take the fingers of the pad and after about 1s it gets executed.
The main question is, is that normal? And can anything be done about that?

Thanks and cheers!

Indeed, the cause of this is the sleep(1) which delays 1 second before executing. This was intended delay for the autostart, but I guess your point makes sense that there's no such need when one just wants to run it normally.

I'm looking for ways to activate it without the delay (using purely dependencies), but I still can't find an appropriate line of code for this to work. If it helps, the current service unit looks like:

[Unit]
Description=Comfortable 3 or 4 finger gestures
After=display-manager.service keyboard-setup.service

[Service]
Environment=DISPLAY=$DISPLAY XAUTHORITY=$XAUTHORITY
ExecStart=/usr/local/bin/comfortable-swipe exec
Restart=always
RestartSec=2

[Install]
WantedBy=graphical.target

As of now, autostart won't work without the delay, so maybe I'm missing a dependency? I'm not sure. If anyone knows someone who can help out with this, that will be helpful.

Cheers!

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure if I fully understand.
I'm using the master branch (sorry for not clarifying earlier). So there's no sleep(1) in the cpp file.
Was that introduced to "workaround" the mentioned delay?
To me it sounds like the delay in the code concerns the start of the program. The delay I mentioned happens for the execution of a swipe while the program is running.

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for misunderstanding, @schigum , I thought it was related to this PR, but it seems I was mistaken. Will reopen issue #16

exit(system("/usr/bin/stdbuf -oL -eL /usr/bin/libinput-debug-events 2>&1 | " PROGRAM " buffer"));
}
// parses output from libinput-debug-events
void buffer() {
// check first if $user
Expand Down Expand Up @@ -263,78 +246,37 @@ namespace service {
swipe.udx = matches[6];
swipe.udy = matches[7];
swipe.on_update();
} else if (sentence.find("Segmentation fault") != string::npos) {
exit(EXIT_FAILURE);
} else if (sentence.find("Error") != string::npos) {
exit(EXIT_FAILURE);
}
}
}
// starts service
void start() {
int x = system("stdbuf -oL -eL libinput-debug-events | " PROGRAM " buffer");
exit(system("systemctl start comfortable-swipe.service"));
}
// stops service
void stop() {
// kill all comfortable-swipe, except self
char* buffer = new char[20];
FILE* pipe = popen("pgrep -f comfortable-swipe", "r");
if (!pipe) throw std::runtime_error("stop command failed");
string kill = "kill";
while (!feof(pipe)) {
if (fgets(buffer, 20, pipe) != NULL) {
int pid = atoi(buffer);
if (pid != getpid()) {
kill += " " + to_string(pid);
}
}
}
int result = system(kill.data());
delete[] buffer;
pclose(pipe);
exit(system("systemctl stop comfortable-swipe.service"));
}
// shows the status of the program
void status() {
exit(system("systemctl status comfortable-swipe.service"));
}
// stops then starts service
void restart() {
service::stop();
service::start();
}
// toggle automatically start application on startup
void autostart() {
string path = autostart_filename();
if (ifstream(path.data()).good()) {
// file found, delete it
if (remove(path.data()) != 0)
cerr << "Error: failed to switch off autostart. "
<< "Maybe the autostart file is in use?"
<< endl;
else
cout << "Autostart switched off" << endl;
} else {
// file not found, create it
int result = system(("mkdir -p $(dirname " + path + ")").data());
ofstream fout(path.data());
if (result != 0 || !fout.good())
cerr << "Error: failed to switch on autostart. "
<< "Are you sure you have the permissions?"
<< endl;
else {
fout <<
"[Desktop Entry]\n"
"Type=Application\n"
"Exec=bash -c \"" 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";
cout << "Autostart switched on" << endl;
}
}
exit(system("systemctl restart comfortable-swipe.service"));
}
// shows help
void help() {
puts("comfortable-swipe [start|stop|restart|autostart|buffer|help]");
puts("comfortable-swipe [start|stop|status|restart|buffer|help]");
puts("");
puts("start - starts 3/4-finger gesture service");
puts("stop - stops 3/4-finger gesture service");
puts("status - shows the status of the program (service log)");
puts("restart - stops then starts 3/4-finger gesture service");
puts("autostart - automatically run on startup (toggleable)");
puts("buffer - parses output of libinput-debug-events");
puts("help - shows the help dialog");
puts("");
Expand Down
27 changes: 23 additions & 4 deletions uninstall
Original file line number Diff line number Diff line change
@@ -1,7 +1,26 @@
#!/bin/bash
if [ $(id -u) != "0" ]; then
sudo bash "$0" "$@"
exit $?
fi
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
rm /usr/local/bin/comfortable-swipe 2> /dev/null
echo "
Uninstall $(date)" >> .log

# stop service
systemctl stop comfortable-swipe.service >> .log 2>> .log
systemctl disable comfortable-swipe.service >> .log 2>> .log
systemctl daemon-reload

# remove service
SERVICE_PATH="/lib/systemd/system/comfortable-swipe.service"
rm $SERVICE_PATH >> .log 2>> .log

# remove old program
OLD_PROGRAM=$HOME/.local/bin/comfortable-swipe
rm $OLD_PROGRAM >> .log 2>> .log # compat

# remove program
PROGRAM=/usr/local/bin/comfortable-swipe
rm $PROGRAM >> .log 2>> .log
echo "Successfully uninstalled comfortable-swipe"