This fork of Touchpad Gesture Customization adds:
- App Exposé on a downward Overview swipe.
- Optional Mission Control-style grouping by application in Overview.
- A
flake.nixfor Nix and NixOS packaging.
This repository (7mind/touchpad-gesture-customization-app-expose) is a downstream fork of HieuTNg/touchpad-gesture-customization. It exists primarily to add a macOS-style App Exposé behavior to the overview gesture: when configured, swiping down with 3/4 fingers spreads only the windows of the currently focused application, while swiping up keeps the standard GNOME overview / app grid navigation. See the App overview on down mode under Overview navigation states in the extension preferences. Changes from this fork may or may not be upstreamed.
The fork also provides an optional Mission Control-style Grouping by Application in Overview. When enabled, the normal window picker lays out applications as primary regions and stacks each application's windows in an overlapping clockwise spiral. Grouped Overview appearance selects an application icon/name header above each stack (default) or one application icon beneath it; neither mode shows per-window icons. Front thumbnails shrink when necessary to leave every window partly exposed. Hover and keyboard focus highlight previews without raising or enlarging them over their neighbors. The same grouped geometry is used for touchpad swipe-up, Super, the hot corner, keyboard shortcuts, and programmatic Overview entry. Swipe-down App Exposé keeps the current application's windows spread out without overlap; group decorations are hidden there, in search, and in the app grid. Show app icons in App overview independently enables per-window icons in that view and is off by default, including when grouping is disabled.
Open the extension preferences and enable Group Overview by application, or run:
gsettings set org.gnome.shell.extensions.touchpad-gesture-customization group-overview-by-application true
This setting is independent of Overview navigation states. Combine it with App overview on down for the paired behavior:
swipe up -> all applications grouped by application
swipe down -> current application's windows only
The grouped layout is off by default and targets GNOME Shell 50 or later. It checks the required private Shell interfaces at runtime; an unsupported Shell build keeps the stock Overview instead. On GNOME 48–49, the preference switch is insensitive and shown off. The stored setting is ignored even if it was enabled previously or changed with gsettings, so the extension retains its existing behavior on those versions.
In gnome-extensions-app settings,
Overview navigation states should be set to App overview on down:
At least one vertical swipe gesture should be set to Application overview:
Then swipe up will show default overview and swipe down will show an overview of current application's windows only.
This extension modifies and extends existing touchpad gestures on GNOME using Wayland. This project is a fork of gnome-gesture-improvements. Since the original project seems to be no longer maintained, I setup this project with the aim of taking over the development and maintenance of this wonderful extension that I relied on for daily use.
Note:
mainbranch contains latest changes which may not work on older version of GNOME, please choose the correct branch if install from source.- To view the extension's settings window, user need to install
extensionsapp. - I have removed the support for X11 since I only use Wayland, but this can be added again in the future if needed and if someone is willing to support this.
- There is a bug in GNOME 49 which break the extension, you have to upgrade to GNOME 49.3 or compile it from source for the extension to work again.
This repository is a flake. It exposes the built extension as
packages.<system>.default (also named
packages.<system>.gnome-shell-extension-touchpad-gesture-customization-app-expose).
The package's passthru.extensionUuid carries the extension UUID, so you never
have to hard-code it.
Add the flake as an input and install the package on a vanilla NixOS configuration:
{
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
touchpad-gesture-customization-app-expose.url =
"github:7mind/touchpad-gesture-customization-app-expose";
};
outputs = { nixpkgs, touchpad-gesture-customization-app-expose, ... }: {
nixosConfigurations.myhost = nixpkgs.lib.nixosSystem {
system = "x86_64-linux";
modules = [
({ pkgs, ... }: {
environment.systemPackages = [
touchpad-gesture-customization-app-expose.packages.${pkgs.system}.default
];
})
];
};
};
}Then rebuild (sudo nixos-rebuild switch --flake .#myhost), log out and log
back in, and enable the extension like any other — via the Extensions app or:
gnome-extensions enable touchpad-gesture-customization@coooolapps.com
The package targets the GNOME Shell versions listed in metadata.json; on a
newer Shell you may need to append the major version to shell-version via an
overrideAttrs patch.
Run the extension in a nested GNOME 48, 49, or 50 Wayland session without logging out of the host session:
nix run '.?dir=nix/testing#gnome-48'
nix run '.?dir=nix/testing#gnome-49'
nix run '.?dir=nix/testing#gnome-50'The test apps live in a separate flake so downstream package consumers do not resolve the three test-only Nixpkgs inputs. Run the commands above from the repository root. Check all three launchers with:
nix flake check '.?dir=nix/testing'Each command uses its pinned Nixpkgs release and installs this checkout into a
temporary profile. GNOME 48 opens the legacy nested compositor; GNOME 49–50 use
Mutter Development Kit. The launcher opens two terminals, Calculator, and the
extension preferences in the nested session. Close the nested window or press
Ctrl-C in the launching terminal to stop it.
The isolated profile selects App overview on down. Focus one of the two
terminal windows, then use two-finger vertical scrolling over the nested
display as the swipe proxy. Scroll up to enter App Overview, or reverse
downward before the proxy gesture ends to restore the normal Overview. With
natural scrolling, “scroll up” means moving two fingers downward. This
exercises the extension's interactive SwipeTracker path, but not libinput
finger-count or hold-gesture recognition.
These launchers provide configuration isolation, not a security boundary. They use a temporary HOME and XDG directories, a private D-Bus session and keyfile-backed GSettings state, and, for GNOME 49–50, a private PipeWire/WirePlumber media graph. Only the host display connection used by the nested compositor is shared; test applications and extension preferences receive only the nested Wayland display. The host system bus is used when available. Normal exit deletes the temporary profile, and no host logout or Shell restart is required. The first invocation may download a multi-gigabyte GNOME closure; later runs use the Nix store cache.
The grouped Overview setting also starts as true inside the temporary
profile. On GNOME 48–49 the preference must still appear insensitive and off,
and stock Overview behavior must remain active. GNOME 50 should expose the
enabled grouped behavior. See the manual QA checklist
for the complete matrix.
Most users enable extensions imperatively as above. If you instead want the
extension enabled (and configured) declaratively for every user session, drop
the programs.dconf block below into the same module. It reads the UUID from
the package rather than repeating the string:
({ pkgs, ... }:
let
ext = touchpad-gesture-customization-app-expose.packages.${pkgs.system}.default;
in {
environment.systemPackages = [ ext ];
programs.dconf = {
enable = true;
profiles.user.databases = [{
settings = {
"org/gnome/shell" = {
disable-user-extensions = false;
enabled-extensions = [ ext.extensionUuid ];
};
# The point of this fork: turn on the app-expose (application overview)
# gesture. `overview-navigation-states` opens the app overview on a
# downward swipe; exactly one vertical swipe must be set to
# `OVERVIEW_NAVIGATION` — pick 3- or 4-finger (4-finger shown here).
"org/gnome/shell/extensions/touchpad-gesture-customization" = {
overview-navigation-states = "APPLICATION_OVERVIEW_ON_DOWN";
vertical-swipe-4-fingers-gesture = "OVERVIEW_NAVIGATION";
group-overview-by-application = true;
}
# (Optional) free the 3-finger gestures (e.g. for 3-finger drag) by
# moving GNOME's defaults off them. Append this `// { … }` or drop it.
# If you keep it, leave the OVERVIEW_NAVIGATION swipe above on 4-finger.
// {
vertical-swipe-3-fingers-gesture = "NONE";
horizontal-swipe-3-fingers-gesture = "NONE";
pinch-3-finger-gesture = "NONE";
};
};
}];
};
})- Install extension
git clone https://github.com/7mind/touchpad-gesture-customization-app-expose.git
cd touchpad-gesture-customization-app-expose
npm install
npm run update
This runs the full build→pack→install chain in order: npm run update chains npm run pack && make update, and npm run pack chains npm run build && make pack. Direct invocation of make pack or make update is protected by Makefile guards that fail loudly if prerequisites are missing (no transpiled extension.js for pack, or missing/invalid zip for update).
- Log out and log in
- Enable extension via extensions app or via command line
gnome-extensions enable touchpad-gesture-customization@coooolapps.com
If you're updating the extension, make sure the old version is fully uninstalled. Run:
gnome-extensions uninstall touchpad-gesture-customization@coooolapps.com
And log out and log in again.
| Swipe Gesture | Modes | Fingers | Direction |
|---|---|---|---|
| Show current application windows (**) | Desktop | 3/4/both | Vertical down |
| Desktop/Overview/AppGrid navigation | Any | 3/4/both | Vertical/Horizontal |
| Switch workspaces | Overview | 2/3/4 | Horizontal |
| Switch workspaces | Any | 3/4/both | Vertical/Horizontal |
| Switch app pages | AppGrid | 2/3 | Horizontal |
| Switch windows | Desktop | 3/4/both | Vertical/Horizontal |
| Unmaximize/maximize/fullscreen a window | Desktop | 3/4/both | Vertical |
| Minimize a window | Desktop | 3/4/both | Vertical |
| Snap/half-tile a window | Desktop | 3/4/both | Vertical (*) |
| Volume Control | Desktop | 3/4/both | Vertical/Horizontal |
| Brightness Control | Desktop | 3/4/both | Vertical/Horizontal |
| Media Control | Desktop | 3/4/both | Vertical/Horizontal |
| Pinch Gesture Actions | Description | Fingers |
|---|---|---|
| Show Desktop (*) | Hide all application (i.e. windows), pinch out | 3/4 |
| Open/Close Window | Open/Close an application, like clicking on "x" | 3/4 |
| Open/Close Tab/Document | Open/Close a tab in application that uses tabs | 3/4 |
| Show Notification List | Show GNOME notification | 3/4 |
| Volume Control | Increase/decrease system volume | 3/4 |
| Keyboard Backlight Control | Increase/decrease keyboard backlight | 3/4 |
| Application Gestures Actions (*) | Description |
|---|---|
| Forward/Backward | Go back or forward in browser tab |
| Page up/down | Scroll up/down 1 page |
| Right/Left | Switch to next or previous image in image viewer |
| Audio Next/Prev | Switch to next or previous audio |
| Tab Next/Prev | Change tabs (e.g. in browser or file manager) |
- Do a 3/4-fingers vertical swipe downward gesture on an unmaximized window but don't release the gesture
- Wait a few milliseconds
- Do a 3/4-fingers horizontal swipe gesture to tile a window to either side of the screen
- Activate a 3/4-fingers hold gesture on touchpad by pressing your fingers on touchpad but don't release the gesture
- Wait a few milliseconds
- Do a 3/4-fingers vertical/horizontal swipe gesture to activate the application gesture (an arrow animation circle will appear)
- For horizontal gestures, application gesture only works if 3/4-fingers horizontal swipe is set to Window Switching
- Application gesture also supports vertical swipe but is still experimental and requires users to turn off other actions for 3/4-fingers vertical swipe (i.e. set the action to None).
- In addition to swiping, resting 3/4 fingers on the touchpad (a hold gesture) toggles play/pause. The action fires as soon as the hold is registered, so you get immediate feedback that the gesture was recognised. Note that libinput only reports a hold once the fingers have been still for a short moment, so a quick tap does not trigger it.
- Media Control sends the standard media keys (
XF86AudioNext/XF86AudioPrev/XF86AudioPlay), so it applies to whichever player GNOME currently considers active, exactly as pressing the media keys on a keyboard would. It is not tied to any specific application. - How far you need to swipe before a track changes scales with the Touchpad swipe speed setting: raising it makes media swipes trigger with a shorter movement.
- This will only work if you have a Keyboard Backlight tile in Gnome quick settings.
- Enabling minimizing window gesture for Window Manipulation will disable snapping/tiling gesture.
- If you are using an older version of GNOME, there might be a bug which prevent the extension from detecting hold and swipe gesture and pinch gesture. If you face this problem, the gesture can only work if the mouse pointer is pointed at the desktop or top panel.
- (**) App Exposé / current application windows is exposed as a sub-mode of the existing Overview gesture rather than a standalone gesture. Set Overview navigation states to App overview on down in the extension preferences (see Customization below). With this mode active, swiping up still opens the regular overview / app grid; swiping down past a small threshold filters the overview to windows of the currently focused application (similar to macOS App Exposé). Reversing direction within the same swipe restores the regular overview. The mode falls back to the standard overview when no app is focused or when no app windows are eligible for spreading.
- Grouped Overview is a persistent normal-window-picker policy, not a gesture mode. It leaves workspace thumbnails and individual
WindowPreviewinteractions under GNOME Shell's control.
- To switch to windows from all workspaces using 3-fingers swipes, run
gsettings set org.gnome.shell.window-switcher current-workspace-only false
Massive thanks to the original author and everyone who has contributed to the original project to bring us this wonderful GNOME extension.
gnome-gesture-improvements - Original GNOME Gesture Improvement
Screen Brightness Governor - brightness control code.
Volume Scroller - volume control code.

