Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ on: [push, pull_request]

jobs:
lint:
runs-on: ubuntu-22.04
runs-on: ubuntu-24.04
steps:
- name: Checkout code
uses: actions/checkout@v3
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/release-ppa.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ on:

jobs:
update-ppa-branch:
runs-on: ubuntu-22.04
runs-on: ubuntu-24.04
steps:
- name: Checkout code
uses: actions/checkout@v3
Expand Down
61 changes: 31 additions & 30 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,14 @@ on:
jobs:

deb-package:
runs-on: ubuntu-22.04
runs-on: ubuntu-24.04
env:
target_docker_image: debian:bookworm-backports
target_distribution: bookworm
strategy:
matrix:
target_arch: ["amd64", "armhf", "arm64"]
target_arch: ["amd64"]
# target_arch: ["amd64", "armhf", "arm64"]
steps:
- name: GitHub Environment Variables Action
uses: FranzDiebold/github-env-vars-action@v1.2.1
Expand Down Expand Up @@ -50,13 +51,13 @@ jobs:
dpkg_buildpackage_opts: "--no-sign --no-check-builddeps --post-clean"

- name: Upload Debian package artifacts
uses: "actions/upload-artifact@v2"
uses: "actions/upload-artifact@v4"
with:
name: "${{ env.GITHUB_REPOSITORY_NAME }}_${{ env.GITHUB_REF_NAME }}_${{matrix.target_arch}}.deb"
path: "${{ github.workspace }}/artifacts/${{ env.GITHUB_REPOSITORY_NAME }}_${{ env.GITHUB_REF_NAME }}_${{matrix.target_arch}}.deb"

rpm-package-rhel:
runs-on: ubuntu-22.04
runs-on: ubuntu-24.04
container:
image: almalinux:8
steps:
Expand Down Expand Up @@ -91,20 +92,20 @@ jobs:
rpmbuild -ba ${{ env.GITHUB_REPOSITORY_NAME }}/rpm/${{ env.GITHUB_REPOSITORY_NAME }}.spec

- name: Upload RPM package
uses: "actions/upload-artifact@v2"
uses: "actions/upload-artifact@v4"
with:
name: "rhel8_${{ env.GITHUB_REPOSITORY_NAME }}-${{ env.GITHUB_REF_NAME }}-1.x86_64.rpm"
path: "~/rpmbuild/RPMS/x86_64/${{ env.GITHUB_REPOSITORY_NAME }}-${{ env.GITHUB_REF_NAME }}-1.x86_64.rpm"

rpm-package-fedora:
runs-on: ubuntu-22.04
runs-on: ubuntu-24.04
container:
image: fedora:38
image: fedora:42
steps:
- name: Install dependencies
run: |
dnf upgrade -y
dnf groupinstall -y "Development Tools"
dnf group install -y "development-tools"
dnf install -y gcc gcc-c++ cmake rpm-build libudev-devel libinput-devel pugixml-devel cairo-devel libX11-devel libXtst-devel libXrandr-devel libXi-devel glib2-devel gtk3-devel

- name: GitHub Environment Variables Action
Expand All @@ -128,20 +129,20 @@ jobs:
rpmbuild -ba ${{ env.GITHUB_REPOSITORY_NAME }}/rpm/${{ env.GITHUB_REPOSITORY_NAME }}.spec

- name: Upload RPM package
uses: "actions/upload-artifact@v2"
uses: "actions/upload-artifact@v4"
with:
name: "fedora34_${{ env.GITHUB_REPOSITORY_NAME }}-${{ env.GITHUB_REF_NAME }}-1.x86_64.rpm"
path: "~/rpmbuild/RPMS/x86_64/${{ env.GITHUB_REPOSITORY_NAME }}-${{ env.GITHUB_REF_NAME }}-1.x86_64.rpm"

create-release:
runs-on: ubuntu-22.04
runs-on: ubuntu-24.04
needs: [ deb-package, rpm-package-rhel, rpm-package-fedora ]
steps:
- name: GitHub Environment Variables Action
uses: FranzDiebold/github-env-vars-action@v1.2.1

- name: Download packages
uses: "actions/download-artifact@v2"
uses: "actions/download-artifact@v4"
with:
path: ./

Expand All @@ -166,25 +167,25 @@ jobs:
asset_name: "${{ env.GITHUB_REPOSITORY_NAME }}_${{ env.GITHUB_REF_NAME }}_amd64.deb"
asset_content_type: application/vnd.debian.binary-package

- name: Upload Debian package (armhf)
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: "${{ env.GITHUB_REPOSITORY_NAME }}_${{ env.GITHUB_REF_NAME }}_armhf.deb/${{ env.GITHUB_REPOSITORY_NAME }}_${{ env.GITHUB_REF_NAME }}_armhf.deb"
asset_name: "${{ env.GITHUB_REPOSITORY_NAME }}_${{ env.GITHUB_REF_NAME }}_armhf.deb"
asset_content_type: application/vnd.debian.binary-package

- name: Upload Debian package (arm64)
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: "${{ env.GITHUB_REPOSITORY_NAME }}_${{ env.GITHUB_REF_NAME }}_arm64.deb/${{ env.GITHUB_REPOSITORY_NAME }}_${{ env.GITHUB_REF_NAME }}_arm64.deb"
asset_name: "${{ env.GITHUB_REPOSITORY_NAME }}_${{ env.GITHUB_REF_NAME }}_arm64.deb"
asset_content_type: application/vnd.debian.binary-package
# - name: Upload Debian package (armhf)
# uses: actions/upload-release-asset@v1
# env:
# GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# with:
# upload_url: ${{ steps.create_release.outputs.upload_url }}
# asset_path: "${{ env.GITHUB_REPOSITORY_NAME }}_${{ env.GITHUB_REF_NAME }}_armhf.deb/${{ env.GITHUB_REPOSITORY_NAME }}_${{ env.GITHUB_REF_NAME }}_armhf.deb"
# asset_name: "${{ env.GITHUB_REPOSITORY_NAME }}_${{ env.GITHUB_REF_NAME }}_armhf.deb"
# asset_content_type: application/vnd.debian.binary-package

# - name: Upload Debian package (arm64)
# uses: actions/upload-release-asset@v1
# env:
# GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# with:
# upload_url: ${{ steps.create_release.outputs.upload_url }}
# asset_path: "${{ env.GITHUB_REPOSITORY_NAME }}_${{ env.GITHUB_REF_NAME }}_arm64.deb/${{ env.GITHUB_REPOSITORY_NAME }}_${{ env.GITHUB_REF_NAME }}_arm64.deb"
# asset_name: "${{ env.GITHUB_REPOSITORY_NAME }}_${{ env.GITHUB_REF_NAME }}_arm64.deb"
# asset_content_type: application/vnd.debian.binary-package

- name: Upload RPM package (RHEL)
uses: actions/upload-release-asset@v1
Expand Down
19 changes: 19 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,24 @@
# Changelog

## 2.0.18 - 2025-05-24

- Allow to execute actions on gesture begin and end

Until now, it was only possible to execute the MOUSE_CLICK, SEND_KEYS an
RUN_COMMAND actions when the gesture started or when the gesture ended.

Include a third option, <on>begin-and-end</on> allowing to run the actions
both when the gesture starts and ends.

When this new setting is used, MOUSE_CLICK starts presses the mouse button
when the gesture starts and releases it when the gesture ends.

In the case of RUN_COMMAND, a environment variable is set
(TOUCHEGG_GESTURE_ON) allowing the executed script to take different actions
at the beginning and the end of the gesture.

https://github.com/JoseExposito/touchegg/pull/670

## 2.0.17 - 2023-08-13

This version does not include any new features, but the deb and rpm packages
Expand Down
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 3.0.0)
project(touchegg)
set(MAJOR_VERSION "2")
set(MINOR_VERSION "0")
set(PATCH_VERSION "17")
set(PATCH_VERSION "18")
add_definitions(-D_VERSION="v${MAJOR_VERSION}.${MINOR_VERSION}.${PATCH_VERSION}")

set(CMAKE_CXX_STANDARD 17)
Expand Down
2 changes: 1 addition & 1 deletion HACKING.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ $ sudo apt-get install git build-essential gdb cmake debhelper \
libgtk-3-dev # GTK is optional, see "Compilation flags"

# Red Hat, Fedora, CentOS and derivatives:
$ sudo dnf groupinstall "Development Tools"
$ sudo dnf group install "development-tools"
$ sudo dnf install git gcc gcc-c++ gdb cmake rpm-build \
libudev-devel libinput-devel pugixml-devel cairo-devel libX11-devel libXtst-devel libXrandr-devel libXi-devel glib2-devel \
gtk3-devel # GTK is optional, see "Compilation flags"
Expand Down
10 changes: 6 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -544,7 +544,7 @@ Options:
| repeat | `true`/`false` | Whether to execute the keyboard shortcut multiple times (default: `false`). This is useful to perform actions like pinch to zoom. |
| modifiers | Keysym | Typical values are: `Shift_L`, `Control_L`, `Alt_L`, `Alt_R`, `Meta_L`, `Super_L`, `Hyper_L`. You can use multiple keysyms: `Control_L+Alt_L`.See "Keysyms" below for more information. |
| keys | Keysym | Shortcut keys. You can use multiple keysyms: `A+B+C`. See "Keysyms" below for more information. |
| on | `begin`/`end` | Only used when `repeat` is `false`. Whether to execute the shortcut at the beginning or at the end of the gesture. |
| on | `begin`/`end`/`begin-and-end` | Only used when `repeat` is `false`. Whether to execute the shortcut at the beginning and/or at the end of the gesture. |
| decreaseKeys | Keysym | Only used when `repeat` is `true`. Keys to press when you change the gesture direction to the opposite. You can use multiple keysyms: `A+B+C`. This is useful to perform actions like pinch to zoom, check `Example 2` below. |
| times | 2...15 | Only used when `repeat` is `true`. Number of times to repeat the action. |
| animate | `true`/`false` | Set it to `true` to display the animation set in `animation`. `false` otherwise. |
Expand Down Expand Up @@ -640,7 +640,7 @@ Options:
| - | - | - |
| repeat | `true`/`false` | `true` if the command should be executed multiple times. `false` otherwise. |
| command | Command | The command to execute. |
| on | `begin`/`end` | Only used when `repeat` is `false`. If the command should be executed on the beginning or on the end of the gesture. |
| on | `begin`/`end`/`begin-and-end` | Only used when `repeat` is `false`. If the command should be executed and/on the beginning or on the end of the gesture. |
| decreaseCommand | Command | Only used when `repeat` is `true`. Command to run when you change the gesture direction to the opposite. Check `Example 2` below. |
| times | 2...15 | Only used when `repeat` is `true`. Number of times to repeat the action. |
| animate | `true`/`false` | Set it to `true` to display the animation set in `animation`. `false` otherwise. |
Expand All @@ -654,7 +654,7 @@ Example 1:
<gesture type="SWIPE" fingers="4" direction="DOWN">
<action type="RUN_COMMAND">
<repeat>false</repeat>
<command>notify-send 'Hello World' "Swipe down, DEVICE_TYPE=$TOUCHEGG_DEVICE_TYPE"</command>
<command>notify-send 'Hello World' "Swipe down, DEVICE_TYPE=$TOUCHEGG_DEVICE_TYPE TOUCHEGG_GESTURE_ON=$TOUCHEGG_GESTURE_ON"</command>
<on>begin</on>
</action>
</gesture>
Expand All @@ -681,7 +681,9 @@ Options:
| Option | Value | Description |
| - | - | - |
| button | `1`/`2`/`3`/`8`/`9` | Left click (1), middle click (2), right click (3), back button (8) or forward button (9) |
| on | `begin`/`end` | If the command should be executed on the beginning or on the end of the gesture. |
| on | `begin`/`end`/`begin-and-end` | If the mouse click should be executed on the beginning and/or on the end of the gesture. |

When the `begin-and-end` option is used, the mouse button is down when the gesture begins and up when the gesture ends.

Example:

Expand Down
6 changes: 6 additions & 0 deletions debian/changelog
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
touchegg (2.0.18) focal; urgency=medium

* Allow to execute actions on gesture begin and end

-- José Expósito <jose.exposito89@gmail.com> Sat, 24 May 2025 12:00:00 +0100

touchegg (2.0.17) focal; urgency=medium

* Upgrade the target Debian version on CI
Expand Down
6 changes: 4 additions & 2 deletions rpm/touchegg.spec
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
Name: touchegg
Summary: Multi-touch gesture recognizer
Url: https://github.com/JoseExposito/touchegg
Version: 2.0.17
Version: 2.0.18
Release: 1
License: GPLv3+
Group: Applications/Productivity
Expand Down Expand Up @@ -84,8 +84,10 @@ fi


%changelog
* Sat May 24 2025 José Expósito <jose.exposito89@gmail.com> - 2.0.18-1
- Allow to execute actions on gesture begin and end

* Sun Aug 13 2023 José Expósito <jose.exposito89@gmail.com> - 2.0.16-1
* Sun Aug 13 2023 José Expósito <jose.exposito89@gmail.com> - 2.0.17-1
- Upgrade the target Fedora and RHEL version on CI

* Mon Feb 06 2023 José Expósito <jose.exposito89@gmail.com> - 2.0.16-1
Expand Down
58 changes: 58 additions & 0 deletions src/actions/execute-action-on.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/**
* Copyright 2011 - 2024 José Expósito <jose.exposito89@gmail.com>
*
* This file is part of Touchégg.
*
* Touchégg 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.
*
* Touchégg 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
* Touchégg. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef ACTIONS_EXECUTE_ACTION_ON_H_
#define ACTIONS_EXECUTE_ACTION_ON_H_

#include <string>

enum class ExecuteActionOn {
NOT_SUPPORTED,
BEGIN,
END,
BEGIN_AND_END,
// Adding a new value? Don't forget to add it in executeActionOnFromStr and
// shouldExecuteAction
};

inline ExecuteActionOn executeActionOnFromStr(const std::string &str) {
if (str == "begin") {
return ExecuteActionOn::BEGIN;
}
if (str == "end") {
return ExecuteActionOn::END;
}
if (str == "begin-and-end") {
return ExecuteActionOn::BEGIN_AND_END;
}
return ExecuteActionOn::NOT_SUPPORTED;
}

inline bool shouldExecuteAction(ExecuteActionOn phase, ExecuteActionOn config) {
switch (config) {
case ExecuteActionOn::BEGIN:
return phase == ExecuteActionOn::BEGIN;
case ExecuteActionOn::END:
return phase == ExecuteActionOn::END;
case ExecuteActionOn::BEGIN_AND_END:
return true;
default:
return false;
}
}

#endif // ACTIONS_EXECUTE_ACTION_ON_H_
18 changes: 13 additions & 5 deletions src/actions/mouse-click.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,18 +23,26 @@ void MouseClick::onGestureBegin(const Gesture& /*gesture*/) {
}

if (this->settings.count("on") == 1) {
this->onBegin = (this->settings.at("on") == "begin");
this->executeActionOn = executeActionOnFromStr(this->settings.at("on"));
}

if (this->onBegin) {
this->windowSystem.sendMouseClick(this->button);
if (shouldExecuteAction(ExecuteActionOn::BEGIN, this->executeActionOn)) {
this->windowSystem.sendMouseDown(this->button);

if (this->executeActionOn != ExecuteActionOn::BEGIN_AND_END) {
this->windowSystem.sendMouseUp(this->button);
}
}
}

void MouseClick::onGestureUpdate(const Gesture& /*gesture*/) {}

void MouseClick::onGestureEnd(const Gesture& /*gesture*/) {
if (!this->onBegin) {
this->windowSystem.sendMouseClick(this->button);
if (shouldExecuteAction(ExecuteActionOn::END, this->executeActionOn)) {
if (this->executeActionOn != ExecuteActionOn::BEGIN_AND_END) {
this->windowSystem.sendMouseDown(this->button);
}

this->windowSystem.sendMouseUp(this->button);
}
}
3 changes: 2 additions & 1 deletion src/actions/mouse-click.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include <string>

#include "actions/action.h"
#include "actions/execute-action-on.h"

/**
* Action to emulate a shortcut.
Expand All @@ -35,7 +36,7 @@ class MouseClick : public Action {

private:
int button = 1;
bool onBegin = true;
ExecuteActionOn executeActionOn = ExecuteActionOn::BEGIN;
};

#endif // ACTIONS_MOUSE_CLICK_H_
13 changes: 9 additions & 4 deletions src/actions/repeated-action.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,15 @@ void RepeatedAction::onGestureBegin(const Gesture &gesture) {
}

if (this->settings.count("on") == 1) {
this->onBegin = (this->settings.at("on") == "begin");
this->executeActionOn = executeActionOnFromStr(this->settings.at("on"));
}

// execute supplied prelude
this->executePrelude();

// run action on begin
if (!this->repeat && this->onBegin) {
if (!this->repeat &&
shouldExecuteAction(ExecuteActionOn::BEGIN, this->executeActionOn)) {
this->executeAction(gesture);
}
}
Expand Down Expand Up @@ -70,8 +71,12 @@ void RepeatedAction::onGestureUpdate(const Gesture &gesture) {
}

void RepeatedAction::onGestureEnd(const Gesture &gesture) {
if (!this->repeat && !this->onBegin) {
if (gesture.percentage() >= this->threshold) {
if (!this->repeat &&
shouldExecuteAction(ExecuteActionOn::END, this->executeActionOn)) {
// Do not take into account the threshold is the action is executed on begin
// and end. Otherwise, we could miss could execute only the on begin part.
if (this->executeActionOn == ExecuteActionOn::BEGIN_AND_END ||
gesture.percentage() >= this->threshold) {
this->executeAction(gesture);
}
}
Expand Down
Loading