A lightweight, feature-rich dock for Linux written in Python with GTK 3 and Cairo. Inspired by Plank and Cairo-Dock, with an extensible applet system for custom widgets.
- Highlights
- Requirements
- Installation
- Running
- First Use
- Configuration
- Applets
- Theming
- Writing Custom Applets
- Translations
- Developer Workflow
- Additional Docs
- Contributing
- License
- Fast launcher workflow with running indicators, previews, app actions, and drag-and-drop organization.
- Native Linux desktop integration across X11 and Wayland, with support for GNOME, KDE Plasma, Niri, wlroots compositors, MATE, Xfce, Cinnamon, and reduced fallback mode.
- 63 built-in applets for launching apps and commands, monitoring system state, controlling media, managing notes, files, folders, screenshots, power, networking, weather, and more.
- Folder stacks and pinned files/folders, so directories and documents can live directly in the dock alongside applications.
- Flexible dock layout with multi-position, multi-monitor, auto-hide, separators, and scalable sizing.
- Deep customization through 13 built-in themes, transparency, icon sizing, per-item custom icons, menu behavior, and tooltip controls.
- Broad release packaging: AppImage, Debian package, RPM, Flatpak, Snap, Arch package, and Nix output.
- Desktop integration details such as Unity LauncherEntry badge/progress support, X11 background blur region export, and 74 locale catalogs plus English fallback.
- Extensible Python applet system for adding custom dock-resident tools without changing the core runtime.
- Linux desktop with X11 (full support) or Wayland (backend-specific support)
- Python 3.10+
- Wayland backends:
- GNOME / Mutter 45+ through the companion
docking-bridge@docking.orgextension - KDE Plasma 6 through the native KWin backend
- wlroots-style compositors through layer-shell and advertised Wayland protocols
- reduced mode when compositor integration is unavailable
- GNOME / Mutter 45+ through the companion
- System packages (Ubuntu/Debian):
sudo apt install \
python3-venv \
python3-gi python3-gi-cairo \
gir1.2-gtk-3.0 gir1.2-gdkpixbuf-2.0 gir1.2-wnck-3.0 gir1.2-pango-1.0 \
gir1.2-nm-1.0 gir1.2-gstreamer-1.0 \
libcairo2-dev libgirepository1.0-dev pkg-configNative Wayland layer-shell source installs also need the system
gtk-layer-shell GIR package:
# Debian / Ubuntu
sudo apt install gir1.2-gtklayershell-0.1
# Fedora
sudo dnf install gtk-layer-shell
# Arch
sudo pacman -S gtk-layer-shellRelease packages include or depend on this where native Wayland support is advertised. Source installs must install it separately.
Live Wayland protocol clients in source installs need the [wayland] extra:
# Debian / Ubuntu build dependencies for pywayland
sudo apt install libwayland-dev wayland-protocols
pip install -e ".[wayland]"The latest prebuilt packages are available on GitHub Releases and linked directly below.
AppImage: x64, arm64Debian .deb: x64, arm64RPM: x64, arm64Flatpak: x64, arm64Snap: x64, arm64Arch package: x64, arm64Nix: x64 store path, x64 output tarball, arm64 store path, arm64 output tarball
Typical local install/run commands after downloading a release asset:
# Choose the suffix matching the downloaded asset.
ARCH=x86_64 # Use aarch64 for ARM64.
# AppImage
chmod +x "docking-latest-linux-${ARCH}.AppImage"
./docking-latest-linux-${ARCH}.AppImage
# Debian / RPM / Arch
sudo apt install "./docking-latest-linux-${ARCH}.deb"
sudo dnf install "./docking-latest-linux-${ARCH}.rpm"
sudo pacman -U "./docking-latest-linux-${ARCH}.pkg.tar.zst"
# Flatpak / Snap
flatpak install --user "./docking-latest-linux-${ARCH}.flatpak"
sudo snap install --dangerous "./docking-latest-linux-${ARCH}.snap"
# Nix output tarball
mkdir docking-nix-output
tar -C docking-nix-output -xf "docking-latest-linux-${ARCH}-nix-output.tar.gz"
./docking-nix-output/bin/docking# Clone
git clone https://github.com/edumucelli/docking.git
cd docking
# Create venv with access to system GI bindings
python3 -m venv --system-site-packages .venv
source .venv/bin/activate
# Install development dependencies, then GTK 3 type stubs without replacing
# the distribution-provided PyGObject runtime
pip install -e ".[dev]"
PYGOBJECT_STUB_CONFIG=Gtk3,Gdk3 \
pip install --no-deps -r requirements-typing.txtOr with uv:
uv venv --python /usr/bin/python3 --system-site-packages .venv
source .venv/bin/activate
uv pip install -e ".[dev]"
PYGOBJECT_STUB_CONFIG=Gtk3,Gdk3 \
uv pip install --no-deps -r requirements-typing.txt# Via entry point
docking
# Or directly
python run.py
# With debug logging
DOCKING_LOG_LEVEL=DEBUG python run.pyDocking selects a backend from the current desktop session. You can also force
one with DOCKING_BACKEND.
| Backend | Compositor | Coverage |
|---|---|---|
| GNOME Shell bridge | GNOME / Mutter 45+ | Full: dock placement, window tracking, window actions (activate / minimize / close), window previews, workspace switching, Show Desktop, Alt+Tab hiding |
| KWin | KDE Plasma 6 Wayland | Dock placement (layer-shell), window tracking with titles via AT-SPI accessibility bus, workspace switching via KWin D-Bus. No window actions (KWin 6 does not expose a public activate/close/minimize protocol) |
| Hyprland | Hyprland Wayland | Dock placement (layer-shell), IPC-based window tracking, active state, window actions, geometry, workspace association, and optional previews |
| Niri | Niri Wayland | Dock placement (layer-shell), IPC-based window tracking, active state, window actions (focus, close), window previews, workspace association |
| Native layer-shell | wlroots-based (Sway, labwc, river, Wayfire) | Dock placement, window tracking, workspace switching (varies by compositor protocol support) |
| Reduced | Any Wayland | Dock visible but no window management (no running indicators, no previews, no workspace switching) |
On GNOME, Docking uses a companion GNOME Shell extension
(docking-bridge@docking.org) that provides window management, previews,
workspace switching, and Show Desktop over a private session D-Bus interface.
How to enable:
# Install and enable the extension (one-time)
tools/gnome_bridge.sh install
# Run the dock with the GNOME Shell bridge backend
DOCKING_BACKEND=gnome-shell dockingSystem packages include the extension. AppImage and Nix users should run
tools/gnome_bridge.sh install once, or copy
docking/platform/backends/gnome/extension/ into the GNOME Shell user
extensions directory.
Docking auto-detects KDE Plasma 6 and uses the KWin backend without extra
configuration. The support table above summarizes the capabilities that KWin's
public interfaces make available. You can also select it explicitly with
DOCKING_BACKEND=kwin.
Native layer-shell mode needs a compositor with zwlr_layer_shell_v1.
See Requirements for the gtk-layer-shell GIR and optional
live-protocol dependencies needed by source installs.
Check capabilities:
wayland-info | grep -E 'zwlr_layer_shell_v1|zwlr_foreign_toplevel_manager_v1|ext_workspace_manager_v1'To force a specific backend for testing:
DOCKING_BACKEND=gnome-shell docking # GNOME / Mutter 45+
DOCKING_BACKEND=kwin docking # KDE Plasma 6 Wayland
DOCKING_BACKEND=hyprland docking # Hyprland IPC + layer-shell
DOCKING_BACKEND=niri docking # Niri IPC + layer-shell
DOCKING_BACKEND=wayland-layer-shell docking # wlroots compositors
DOCKING_BACKEND=reduced docking # any Wayland (no WM integration)
DOCKING_BACKEND=x11 docking # X11 (full support)Start by opening the dock menu: right-click the shelf background between icons. If the dock is full or the background is hard to hit, hold Ctrl while right-clicking anywhere on the shelf to show the same dock menu.
The first things to explore are:
- Preferences: open right-click -> Preferences to choose position, monitor behavior, icon size, zoom, hiding, click actions, themes, tooltips, previews, and update checks.
- Add Applet: right-click the shelf background -> Add Applet to add launchers, system status, media, productivity, and utility applets.
- Add Separator: right-click the shelf background where the separator should appear -> Add Separator.
- Pin and remove items: right-click a running app -> Keep in Dock, right-click a pinned item -> Remove from Dock, or drag an unlocked item off the dock to remove it.
- Drag items in: drop applications,
.desktopfiles, files, folders, and AppImages onto the dock to pin them. - Customize icons: right-click a pinned app, file, or folder -> Icon -> Choose From File... to use an image from disk, or reset it back to the automatically detected icon.
- Folder stacks: pin a folder and open it from the dock for quick access to its contents.
- Diagnostics: open right-click -> Diagnostics when checking backend support or preparing a support report.
Open right-click -> Preferences to configure the dock's appearance, placement, behavior, applets, and update checks. Display moves the dock between monitors, while Diagnostics reports the capabilities available in the current desktop session.
Settings are saved automatically in ~/.config/docking/dock.json. See the
Configuration guide for every setting, hide-mode and
mouse-action behavior, pinned entry formats, per-applet preferences, backups,
and safe manual editing.
Docking includes thirteen built-in themes and supports custom JSON themes. A few examples:
| Default | Glass | Olive |
|---|---|---|
![]() |
![]() |
![]() |
See the Themes guide for the complete gallery, custom-theme instructions, and theme field reference.
Docking includes 63 built-in applets, ranging from application launchers and system controls to productivity tools, wellness reminders, and live information.
| Category | Examples |
|---|---|
| Launcher & Navigation | Applications, Run Application, Desktop, Workspaces |
| Time & Productivity | Clock, Calendar, Alarm, Pomodoro, Calculator, Quick Note |
| System & Power | Devices, Network, Bluetooth, Volume, Battery, System Tray |
| Wellness & Ambient | Hydration, Plant Care, Stretch Coach, Ambient, Pet |
| Information and Environment | Weather, Sunrise, Moon, News, Reddit, Hacker News |
Add one from right-click -> Add Applet, then choose a category. See the Applets guide for the complete catalog, interactions, preferences, update intervals, and integration requirements.
Applets are discovered from AppletMeta metadata and loaded lazily when
enabled. They inherit the common lifecycle and UI hooks from
docking/applets/base.py, including create_icon(), click, scroll, and menu
handling, plus optional start() and stop() methods. Keep package imports
cheap and separate GTK wiring from pure state and rendering helpers so most
logic remains testable without a live desktop session.
docking/applets/myapplet/
__init__.py # metadata only: AppletMeta declaration
applet.py # GTK wiring and lifecycle
state.py # pure state/logic helpers
render.py # icon rendering helpers
__init__.py:
from docking.applets.identity import AppletCategory, AppletMeta
meta = AppletMeta(
id="myapplet",
name="My Applet",
category=AppletCategory.PRODUCTIVITY,
)
__all__ = ["meta"]applet.py:
from docking.applets.base import Applet, load_theme_icon
class MyApplet(Applet):
def create_icon(self, size):
return load_theme_icon(name="my-icon", size=size)
def refresh_tooltip(self):
self.item.name = "My Applet"
self.item.tooltip_text = "Useful status"
def start(self, notify):
super().start(notify)
def stop(self):
super().stop()Use self.present() after state changes to refresh icon, tooltip, and dock UI.
Keep parsing/state logic in plain Python modules so tests do not need a display.
Docking now ships 74 locale catalogs via standard gettext (plus English fallback).
Core locales include:
| Language | Code |
|---|---|
| Brazilian Portuguese | pt_BR |
| Spanish | es |
| French | fr |
| Simplified Chinese | zh_CN |
| Hindi | hi |
| Arabic | ar |
| German | de |
| Japanese | ja |
| Korean | ko |
| Russian | ru |
Additional locales are available under docking/locale/*/LC_MESSAGES/docking.po.
The dock automatically uses your system locale. To test a specific language:
LANGUAGE=pt_BR python run.pyCreate a catalog from the template, edit it with a PO editor such as Poedit or
Lokalize, run the validation workflow below, and submit the .po file in a pull
request.
msginit --input=docking/locale/docking.pot \
--locale=XX \
--output=docking/locale/XX/LC_MESSAGES/docking.poAfter adding or modifying a user-visible _("...") string, regenerate the
template and run the same checks as CI:
./tools/i18n.sh --extract
./tools/i18n.sh --check-pot-sync
./tools/i18n.sh --check-catalogs --allow-incomplete
./tools/i18n.sh --compileRegular feature commits only update docking/locale/docking.pot; they do not
need to refresh every catalog or fill every new msgstr.
Translation-only updates merge the current template into every catalog and can apply the stricter completeness check:
./tools/i18n.sh --update-translations
./tools/i18n.sh --check-catalogs --require-complete# Run all tests
pytest tests/ -v
# Run specific module
pytest tests/applets/test_clock.py -v
# Coverage report
pytest tests/ -v --cov=docking --cov-report=term-missingFor the GUI/integration-oriented slice under a headless X11 session:
bash tools/test_gui_headless.shRequirements for that mode:
xvfb-rundbus-run-session
By default it runs the dock interaction/UI slice:
- pointer scenarios
- edges
- menu integration
- preview popup integration
- dock window integration
- interaction
- DnD integration
- renderer integration
You can also pass explicit pytest targets:
bash tools/test_gui_headless.sh tests/ui/test_pointer_scenarios.pyDocking exposes the org.docking.Docking.Items1 session-bus interface for item
inspection and control. See D-Bus Remote Control for the method
reference, examples, and expected responses.
Build dependencies, commands, output paths, and local installation steps for every package format live in the packaging guide.
- Fork the repository
- Create a feature branch
- Make your changes (tests required for new features)
- Run
ruff format docking/ tests/for formatting - Ensure
ruff check && ty check && pytest tests/passes - Submit a pull request
GPL-3.0-or-later




