A lightweight GTK 4/labwc panel with:
- a Python-native
org.kde.StatusNotifierWatcher - tray icons and DBusMenu drop-downs
- a simple labwc/wlroots tasklist using
wlrctl - GTK4 Layer Shell anchoring
- optional user-level systemd support
This panel is intended to replace an external Ayatana/KDE tray watcher. Do not run another StatusNotifier watcher at the same time.
python3 lab.pyChoose a style at startup:
LABTRAY_STYLE=Default python3 lab.py
LABTRAY_STYLE=Alternative1 python3 lab.pyDebug tray registration/icons/menus:
LABTRAY_DEBUG=1 python3 lab.pyIf a tray applet was already running before the panel started, restart that applet after the panel is running. Some StatusNotifier clients register only once.
sudo apt update
sudo apt install \
python3 \
python3-gi \
gir1.2-gtk-4.0 \
gir1.2-gdkpixbuf-2.0 \
python3-pydbus \
dbus-user-session \
gir1.2-gtk4layershell-1.0 \
libgtk4-layer-shell0 \
wlrctl \
wtype \
pkg-configNotes:
gir1.2-gtk4layershell-1.0must provide theGtk4LayerShellGI namespace. The older GTK3 packagegir1.2-gtklayershell-0.1is not enough for this code.wlrctlandwtypeare used by the tasklist. The tray still starts without them, but the tasklist is hidden or limited.- Some Ubuntu releases may not ship
gir1.2-gtk4layershell-1.0orwlrctlin the default repositories. Use a backport/PPA, build the missing component, or run on a distro release that packages them.
Build dependencies if you need to build gtk4-layer-shell yourself:
sudo apt install \
git \
build-essential \
meson \
ninja-build \
pkg-config \
gobject-introspection \
libgtk-4-dev \
libwayland-devsudo pacman -S \
python \
python-gobject \
gtk4 \
gtk4-layer-shell \
python-pydbus \
dbus \
wtype \
pkgconfInstall wlrctl from AUR if you want the tasklist:
yay -S wlrctlInstall the files into ~/.local/share/lab-panel and install user units into ~/.config/systemd/user:
Notice: ./script folder might cause permission denied. Either:
bash chmod +x ./scripts/install-user-service.sh OR add bash in front of the command - Like I added to the below.
bash ./scripts/install-user-service.shInstall and start immediately:
Notice: ./script folder might cause permission denied. Either:
bash chmod +x ./scripts/install-user-service.sh OR add bash in front of the command - Like I added to the below.
bash ./scripts/install-user-service.sh --enableManual service commands:
systemctl --user daemon-reload
systemctl --user enable --now lab-panel.service
systemctl --user status lab-panel.service
journalctl --user -u lab-panel.service -fIf your compositor does not import Wayland session variables into the user manager, run this once from inside the graphical session before starting the service:
systemctl --user import-environment WAYLAND_DISPLAY DISPLAY XDG_CURRENT_DESKTOP XDG_SESSION_TYPE DBUS_SESSION_BUS_ADDRESS XDG_RUNTIME_DIRThe service reads ~/.config/lab-panel/env through EnvironmentFile=. Use the style oneshot units to change the style and restart the panel with a single systemctl command:
systemctl --user start lab-panel-style@Default.service
systemctl --user start lab-panel-style@Alternative1.serviceThe command updates ~/.config/lab-panel/env and then runs:
systemctl --user try-restart lab-panel.serviceYou can also edit the file manually:
mkdir -p ~/.config/lab-panel
printf 'LABTRAY_STYLE=Default\n' > ~/.config/lab-panel/env
systemctl --user restart lab-panel.serviceSupported styles:
DefaultAlternative1
Uninstall the user service files:
Notice: ./script folder might cause permission denied. Either:
bash chmod +x ./scripts/uninstall-user-service.sh OR add bash in front of the command - Like I added to the below.
bash ./scripts/uninstall-user-service.shlab.py small launcher; bootstraps runtime before GTK imports
style.py compatibility shim for older imports
lab_panel/runtime.py environment setup and gtk4-layer-shell LD_PRELOAD re-exec
lab_panel/config.py constants, supported styles, env flags, debug logger
lab_panel/dbus_helpers.py session bus and StatusNotifier item canonicalization
lab_panel/native_watcher.py Python org.kde.StatusNotifierWatcher implementation
lab_panel/tray.py tray UI, icons, clicks, and DBusMenu rendering
lab_panel/tasklist.py labwc tasklist backed by wlrctl/wtype
lab_panel/window.py layer-shell panel window layout
lab_panel/app.py GTK application and signal handling
lab_panel/style.py GTK CSS themes
lab_panel/style_command.py systemd helper for changing LABTRAY_STYLE
systemd/user/*.service user-level systemd units
scripts/*.sh install/uninstall helpers
Stop any external watcher before starting this panel:
pkill -f ayatana-indicator || trueIf tray icon colors are wrong, try one of the pixmap conversion overrides:
LABTRAY_PIXMAP_FORMAT=bgra python3 lab.py
LABTRAY_PIXMAP_FORMAT=argb python3 lab.py
LABTRAY_PIXMAP_FORMAT=rgba python3 lab.pyFor the systemd service, add the variable to ~/.config/lab-panel/env and restart:
printf 'LABTRAY_STYLE=Alternative1\nLABTRAY_DEBUG=1\n' > ~/.config/lab-panel/env
systemctl --user restart lab-panel.service
journalctl --user -u lab-panel.service -f