https://github.com/fuddlesworth/plasmazones
FancyZones-style window tiling for KDE Plasma
https://github.com/fuddlesworth/plasmazones
fancyzones kde kde-plasma-6 kwin kwin-effect powertoys qt6 tiling tiling-window-manager zones
Last synced: 22 days ago
JSON representation
FancyZones-style window tiling for KDE Plasma
- Host: GitHub
- URL: https://github.com/fuddlesworth/plasmazones
- Owner: fuddlesworth
- License: gpl-3.0
- Created: 2026-01-15T01:50:21.000Z (5 months ago)
- Default Branch: main
- Last Pushed: 2026-04-02T01:03:16.000Z (2 months ago)
- Last Synced: 2026-04-02T02:43:38.479Z (2 months ago)
- Topics: fancyzones, kde, kde-plasma-6, kwin, kwin-effect, powertoys, qt6, tiling, tiling-window-manager, zones
- Language: C++
- Homepage:
- Size: 187 MB
- Stars: 205
- Watchers: 1
- Forks: 5
- Open Issues: 5
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- Contributing: CONTRIBUTING.md
- Funding: .github/FUNDING.yml
- License: LICENSE
Awesome Lists containing this project
README
# PlasmaZones

**Window zone management for Wayland compositors**
Define zones on your screen. Drag windows into them. Done.
[](https://github.com/fuddlesworth/PlasmaZones/actions/workflows/ci.yml)
[](https://github.com/fuddlesworth/PlasmaZones/releases/latest)
[](https://aur.archlinux.org/packages/plasmazones-bin)
[](https://copr.fedorainfracloud.org/coprs/fuddlesworth/PlasmaZones/package/plasmazones/)
[](LICENSE)
[](https://wayland.freedesktop.org/)
---
## Table of Contents
- [How It Works](#how-it-works)
- [Features](#features)
- [Window Snapping](#window-snapping)
- [Layout Editor](#layout-editor)
- [Autotiling](#autotiling)
- [Shader Effects](#shader-effects)
- [Snap Assist](#snap-assist)
- [Zone Selector](#zone-selector)
- [Layout Picker](#layout-picker)
- [Multi-Monitor & Virtual Desktops](#multi-monitor--virtual-desktops)
- [Settings App](#settings-app)
- [Installation](#installation)
- [Quick Start](#quick-start)
- [Keyboard Shortcuts](#keyboard-shortcuts)
- [Configuration](#configuration)
- [Troubleshooting](#troubleshooting)
- [D-Bus API](#d-bus-api)
- [Project Structure](#project-structure)
- [Contributing](#contributing)
- [Support](#support)
---
## How It Works
Hold **Alt** (or your configured modifier) while dragging a window. Zones light up. Drop the window into one and it resizes to fill that zone.
---
## Features
### Window Snapping
**Snapping**
- Drag with modifier key or mouse button to snap windows to zones
- Always-active mode: zones activate on every drag without a modifier
- Enable/disable snapping globally
- Snap all visible windows to zones at once
- Auto-assign windows to first empty zone per layout
- Snap to multiple zones at once
- App-to-zone rules: auto-snap apps to specific zones on launch
**Movement**
- Move windows between zones with keyboard shortcuts
- Swap windows between zones directionally
- Rotate windows clockwise/counterclockwise through zones
- Push window to first empty zone
- Restore original size on unsnap
- Per-window floating toggle
- Staggered animations with elastic and bounce easing curves
**Focus & Cycling**
- Focus adjacent zones without mouse
- Cycle through windows stacked in the same zone
### Layout Editor
- Visual canvas for drawing and resizing zones
- 26 built-in templates (columns, grids, fibonacci, master-stack, focus+stack, and more)
- Undo/redo, copy/paste, cut, duplicate
- Split zones horizontally or vertically
- Grid and edge snapping
- Fill available space / auto-expand
- Fullscreen editing mode
- Per-zone colors and styling
- Restrict layouts to specific screens, desktops, or activities
### Autotiling
24 built-in JavaScript tiling algorithms including master+stack, dwindle, BSP, spiral, grid, monocle, and more. All algorithms run in a sandboxed engine and support hot-reload. You can create your own custom algorithms — see the full list and authoring guide on the [Tiling Algorithms](https://github.com/fuddlesworth/PlasmaZones/wiki/Tiling-Algorithms) wiki page.
- Per-screen algorithm selection with independent settings
- Configurable master ratio and master count (separate settings for Centered Master vs Master+Stack)
- Inner and outer gaps with per-side control (top/bottom/left/right)
- Smart gaps — no gaps when only one window is tiled
- Max windows cap — overflow windows float automatically
- Hide title bars on tiled windows, with colored borders
- Window insertion position: end, after focused, or as master
- Focus follows mouse and focus new windows
- Minimized windows float, unminimized windows rejoin tiling
- Per-window floating toggle
- Staggered tiling animations
- Respect window minimum sizes (toggleable) — tiles expand to honor size hints reported by the application
> **Tip:** Some apps enforce a minimum size that prevents tiles from reaching their intended geometry. To fix this, create a KWin Window Rule:
> **System Settings → Window Management → Window Rules** → add a rule matching the window class, set **Minimum Size** to **Force** `0×0` under the **Size & Position** tab. This removes the constraint so PlasmaZones can tile the window at any size.
### Shader Effects
23 built-in GLSL shader effects for zone overlays, including audio-reactive visuals, distro-themed drifts, and procedural effects. Supports up to 4 custom image textures per shader plus desktop wallpaper sampling.
Custom shaders supported — see the full effect list and authoring guide in the [Shader Guide](https://github.com/fuddlesworth/PlasmaZones/wiki/Shaders) on the wiki.
### Snap Assist
After snapping a window, an overlay shows the remaining empty zones with thumbnails of other windows. Click a thumbnail to snap it into a zone.
### Zone Selector
Drag to screen edge to reveal a layout picker. Jump straight to any layout and zone.
### Layout Picker
Press `Meta+Alt+Space` to open a fullscreen layout picker. Click any layout to switch.
### Visual Layout OSD
See a preview of the layout when switching, not just text.
### Navigation OSD
Move, focus, swap, rotate, and push actions show a brief overlay with the affected zone numbers.
### Multi-Monitor & Virtual Desktops
- Per-monitor layouts (same or different)
- Per-virtual-desktop layouts
- Per-activity layouts (optional, requires PlasmaActivities)
- Per-monitor zone selector settings
- Per-screen shader selection
- Screen-targeted app-to-zone rules
### Settings App
Standalone settings app (`plasmazones-settings`) with sidebar navigation:
- **Overview** — Per-screen mode (snapping/tiling) with live context display
- **Layouts** — Create, duplicate, import/export zone layouts with 26 templates
- **Snapping** — Activation, zone appearance (colors, opacity, borders, blur, shaders), animations, zone selector, per-monitor/desktop/activity assignments
- **Tiling** — Per-screen algorithm selection, master ratio/count, gaps, title bar hiding, insertion order, focus behavior, per-monitor/desktop/activity assignments
- **App Rules** — Per-app zone assignment rules with interactive window picker
- **Exclusions** — Window class exclusion lists with interactive picker, minimum size thresholds
- **Editor** — Layout editor preferences and shortcut configuration
- **General** — OSD style, layout switch notifications, global behavior
- **About** — Version info, update checker, daemon status
On KDE Plasma, a System Settings entry provides version info and a launcher to the settings app.
---
## Installation
### Requirements
- Any Wayland compositor with layer-shell support
- Qt 6.6+
- qt6-wayland / Wayland::Client
- CMake 3.16+
- C++20 compiler
- wayland-scanner (build-time only)
Optional (for full KDE integration):
- KDE Frameworks 6.6+ (KWin effect, System Settings, KGlobalAccel shortcuts)
- PlasmaActivities (activity-based layouts)
### Arch Linux (AUR)
```bash
# Binary package (prebuilt)
yay -S plasmazones-bin
# Source package (builds locally)
yay -S plasmazones
```
### Fedora (COPR)
```bash
sudo dnf copr enable fuddlesworth/PlasmaZones
sudo dnf install plasmazones
```
### openSUSE Tumbleweed (OBS)
Community-maintained package by [ilFrance](https://build.opensuse.org/package/show/home:ilFrance/plasmazones):
```bash
sudo zypper addrepo https://download.opensuse.org/repositories/home:ilFrance/openSUSE_Tumbleweed/home:ilFrance.repo
sudo zypper refresh
sudo zypper install plasmazones
```
> **Note:** Do not use the Fedora RPM on openSUSE — it has incompatible Qt private API dependencies.
### Nix
```bash
nix profile install github:fuddlesworth/PlasmaZones
```
Or add to your flake inputs. A `flake.nix` is included in the repository.
### Building from Source
```bash
git clone https://github.com/fuddlesworth/PlasmaZones.git
cd PlasmaZones
cmake -B build -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr
cmake --build build -j$(nproc)
sudo cmake --install build
```
**Portable build (no KDE dependencies):**
```bash
cmake -B build -DUSE_KDE_FRAMEWORKS=OFF \
-DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr
cmake --build build -j$(nproc)
sudo cmake --install build
```
This builds only the daemon and editor — no KWin effect or KCM.
See [Compositor Integration](https://github.com/fuddlesworth/PlasmaZones/wiki/Compositor-Integration) for
shortcut and config setup on non-KDE compositors.
After installation, enable the daemon:
```bash
systemctl --user enable --now plasmazones.service
```
On KDE Plasma, also refresh the service cache for KCM:
```bash
kbuildsycoca6 --noincremental
```
Open the settings app:
```bash
plasmazones-settings
```
On KDE Plasma, PlasmaZones also appears in **System Settings → Window Management → PlasmaZones** with a launcher to the settings app.
Local install (no root)
```bash
cmake .. -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$HOME/.local
cmake --build . -j$(nproc)
cmake --install .
```
Add these to your `~/.bashrc` or `~/.zshrc`:
```bash
export QT_PLUGIN_PATH=$HOME/.local/lib/qt6/plugins:$QT_PLUGIN_PATH
export QML2_IMPORT_PATH=$HOME/.local/lib/qt6/qml:$QML2_IMPORT_PATH
export XDG_DATA_DIRS=$HOME/.local/share:$XDG_DATA_DIRS
```
Then reload your shell and refresh the cache:
```bash
source ~/.bashrc # or ~/.zshrc
kbuildsycoca6 --noincremental
systemctl --user enable --now plasmazones.service
```
RPM-based distros (Fedora/openSUSE)
An RPM spec is included in `packaging/rpm/plasmazones.spec` for building packages on Fedora, openSUSE, and other RPM-based distributions.
Universal Linux / Fedora Atomic (Portable Tarball)
For distributions where installing system packages is difficult (Fedora Atomic/Silverblue) or if you lack root privileges:
1. Download `plasmazones-linux-x86_64.tar.gz` from the [Latest Release](https://github.com/fuddlesworth/PlasmaZones/releases/latest).
2. Extract the archive.
3. Run the installer script:
```bash
tar xzf plasmazones-linux-x86_64.tar.gz
cd plasmazones-linux-x86_64
./install.sh
```
The script installs PlasmaZones to `~/.local` and sets up your environment variables.
**Or use the one-liner:**
```bash
bash <(curl -s https://raw.githubusercontent.com/fuddlesworth/PlasmaZones/main/packaging/local-install/web-install.sh)
```
**Upgrading:**
Run the installer again with a newer tarball. It will detect the existing installation and upgrade in place.
**Uninstalling:**
```bash
~/.local/share/plasmazones/uninstall.sh
```
---
## Quick Start
1. Enable the daemon: `systemctl --user enable --now plasmazones.service`
2. Open settings: `plasmazones-settings` (or **System Settings → PlasmaZones** on KDE)
3. Click **Open Editor** to create a layout
4. Draw zones or pick a template
5. Save with **Ctrl+S**
6. **Drag any window while holding Alt** — zones appear, drop to snap
> **Tip:** The settings app works on any compositor. On KDE, it also appears in System Settings.
---
## Keyboard Shortcuts
### Global Shortcuts
All configurable in **System Settings → Shortcuts → PlasmaZones** (KDE) or in the PlasmaZones settings app.
Layout switching
| Action | Default Shortcut |
|--------|------------------|
| Previous layout | `Meta+Alt+[` |
| Next layout | `Meta+Alt+]` |
| Quick layout 1–9 | `Meta+Alt+1` through `Meta+Alt+9` |
| Open layout picker | `Meta+Alt+Space` |
| Resnap windows to new layout | `Meta+Ctrl+Z` |
Window movement & snapping
| Action | Default Shortcut |
|--------|------------------|
| Snap to zone 1–9 | `Meta+Ctrl+1` through `Meta+Ctrl+9` |
| Move window left/right/up/down | `Meta+Alt+Shift+Arrow` |
| Swap window left/right/up/down | `Meta+Ctrl+Alt+Arrow` |
| Push to empty zone | `Meta+Alt+Return` |
| Snap all windows to zones | `Meta+Ctrl+S` |
| Restore window size | `Meta+Alt+Escape` |
| Toggle float | `Meta+F` |
Focus & cycling
| Action | Default Shortcut |
|--------|------------------|
| Focus zone left/right/up/down | `Alt+Shift+Arrow` |
| Cycle window forward | `Meta+Alt+.` |
| Cycle window backward | `Meta+Alt+,` |
| Rotate windows clockwise | `Meta+Ctrl+]` |
| Rotate windows counterclockwise | `Meta+Ctrl+[` |
Autotiling
| Action | Default Shortcut |
|--------|------------------|
| Toggle autotile | `Meta+Shift+T` |
| Toggle float | `Meta+F` |
| Focus master window | `Meta+Shift+M` |
| Swap with master | `Meta+Shift+Return` |
| Increase master ratio | `Meta+Shift+L` |
| Decrease master ratio | `Meta+Shift+H` |
| Increase master count | `Meta+Shift+]` |
| Decrease master count | `Meta+Shift+[` |
| Retile windows | `Meta+Shift+R` |
Other
| Action | Default Shortcut |
|--------|------------------|
| Open editor | `Meta+Shift+E` |
| Open settings | `Meta+Shift+P` |
| Toggle layout lock | `Meta+Ctrl+L` |
**Shortcut pattern** (avoids conflicts with KDE defaults):
- `Meta+Alt+{key}` — Layout operations and actions
- `Meta+Alt+Shift+Arrow` — Zone movement (avoids KDE's `Meta+Shift+Arrow` screen movement)
- `Meta+Ctrl+Alt+Arrow` — Swap windows (avoids KDE's `Meta+Ctrl+Arrow` desktop switching)
- `Alt+Shift+Arrow` — Focus navigation (avoids KDE's `Meta+Arrow` quick tile)
### Editor Shortcuts
| Action | Shortcut |
|--------|----------|
| Save | `Ctrl+S` |
| Undo / Redo | `Ctrl+Z` / `Ctrl+Shift+Z` |
| Select all | `Ctrl+A` |
| Copy / Cut / Paste | `Ctrl+C` / `Ctrl+X` / `Ctrl+V` |
| Paste with offset | `Ctrl+Shift+V` |
| Delete zone | `Delete` |
| Duplicate zone | `Ctrl+D` |
| Split horizontal | `Ctrl+Shift+H` |
| Split vertical | `Ctrl+Alt+V` |
| Fill available space | `Ctrl+Shift+F` |
| Toggle fullscreen | `F11` |
| Move zone | `Arrow keys` |
| Resize zone | `Shift+Arrow keys` |
| Next / previous zone | `Ctrl+Tab` / `Ctrl+Shift+Tab` |
---
## Configuration
Open the settings app:
```bash
plasmazones-settings # opens on overview page
plasmazones-settings -p layouts # opens directly to layouts page
plasmazones-settings --page tiling-behavior # opens to tiling behavior page
```
The app is single-instance — launching it again while running raises the existing window and switches to the requested page.
Settings stored in `~/.config/plasmazones/config.json`. Layouts stored as JSON in `~/.local/share/plasmazones/layouts/`.
---
## Troubleshooting
### PlasmaZones not appearing in System Settings (KDE only)
Refresh the KDE service cache after installing from source:
```bash
kbuildsycoca6 --noincremental
```
Or log out and back in. The standalone settings app is always available:
```bash
plasmazones-settings
```
### Daemon not starting
```bash
# Check status
systemctl --user status plasmazones.service
# View logs
journalctl --user -u plasmazones.service -f
# Restart
systemctl --user restart plasmazones.service
```
### Zones not appearing when dragging
1. Ensure daemon is running: `systemctl --user status plasmazones.service`
2. Check drag modifier in settings (default: Alt)
3. Verify you have at least one layout with zones
4. Check if the application is excluded in settings
### Generating a support report
When filing a bug report, attach a support report archive. It collects your config, layouts, screen topology, and recent daemon logs with home paths redacted:
```bash
plasmazones-report
```
The archive is saved to `/tmp` by default. Options:
```bash
plasmazones-report --since 60 # Last 60 minutes of logs (default: 30, max: 120)
plasmazones-report --output ~/Desktop # Save to a specific directory
```
You can also call the D-Bus method directly:
```bash
qdbus6 org.plasmazones /PlasmaZones org.plasmazones.Control.generateSupportReport 0
```
---
## D-Bus API
PlasmaZones exposes 10 D-Bus interfaces on `org.plasmazones` for scripting and integration — Autotile, Control, LayoutManager, Overlay, Screen, Settings, Shader, and more.
```bash
# Quick examples
qdbus6 org.plasmazones /PlasmaZones org.plasmazones.LayoutManager.getLayoutList
qdbus6 org.plasmazones /PlasmaZones org.plasmazones.Overlay.showOverlay
```
Full API reference, scripting examples, and per-interface documentation: [D-Bus API](https://github.com/fuddlesworth/PlasmaZones/wiki/D-Bus-API) on the wiki.
---
## Project Structure
See the full directory tree and data locations on the [Project Structure](https://github.com/fuddlesworth/PlasmaZones/wiki/Project-Structure) wiki page.
---
## Contributing
See [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines on code style, license headers, testing, and translations.
---
## Support
If PlasmaZones is useful to you, consider supporting development:
- [Ko-fi](https://ko-fi.com/fuddlesworth)
- [GitHub Sponsors](https://github.com/sponsors/fuddlesworth)
Bug reports and feature requests: [GitHub Issues](https://github.com/fuddlesworth/PlasmaZones/issues)
---
## License
GPL-3.0-or-later
---
Inspired by [FancyZones](https://learn.microsoft.com/en-us/windows/powertoys/fancyzones) from PowerToys.
**Works on KDE Plasma, Hyprland, Sway, GNOME, and any Wayland compositor with layer-shell support.**