- Python 62.9%
- Shell 37.1%
- README.md rewritten in English - docstrings and code comments translated - user-facing output strings translated for consistency - winlayout-autostart grep patterns updated to match new output |
||
|---|---|---|
| applications | ||
| autostart | ||
| .gitignore | ||
| install.sh | ||
| LICENSE | ||
| README.md | ||
| uninstall.sh | ||
| winlayout | ||
| winlayout-autostart | ||
| winlayout-click | ||
kde-window-restore
Save window arrangements under KDE Plasma 6 / KWin (Wayland) and restore them pixel-perfectly — including position, size, virtual desktop and the minimized / maximized state.
The key idea: it uses KWin's own scripting (workspace.windowList /
frameGeometry). Since KWin itself is the Wayland compositor, it is allowed to
move its own windows — exactly where wmctrl and xdotool fail on Wayland. No
third-party packages are required.
Tested with Plasma 6.7 / KWin on Wayland (CachyOS / Arch).
Features
winlayout save [name]– save the current arrangement of all application windowswinlayout restore [name]– restore an arrangement exactlywinlayout list– list saved layoutswinlayout rm <name>– delete a layoutwinlayout path [name]– print the path of a layout file- Auto-restore after login (waits until the app windows are open)
- Panel buttons with a desktop notification as feedback
Per window it stores: application (resourceClass), window title,
frameGeometry (x/y/width/height), minimized, maximize mode and
"on all desktops".
Panels, the desktop background, docks and notifications are intentionally skipped.
Requirements
- KDE Plasma 6 with KWin (Wayland or X11)
- Python 3
dbus-python(Arch:python-dbus)PyGObject(Arch:python-gobject)qdbus(Arch: inqt6-tools)notify-send(Arch: inlibnotify)
All at once on Arch / CachyOS:
sudo pacman -S python-dbus python-gobject qt6-tools libnotify
Installation
git clone ssh://git@devnoc.de:2022/nocci/kde-window-restore.git
cd kde-window-restore
./install.sh
The installer copies the scripts to ~/.local/bin/, generates the .desktop
entries in ~/.local/share/applications/ and enables auto-restore under
~/.config/autostart/. Afterwards the desktop caches are refreshed.
To use a different prefix:
PREFIX=~/.local ./install.sh
Uninstall:
./uninstall.sh
Saved layouts under ~/.config/winlayout/ are kept during uninstall.
Usage
Command line
winlayout save # saves under the name "default"
winlayout save workstation # saves under "workstation"
winlayout restore # restores "default"
winlayout restore workstation
winlayout list
Panel buttons (optional)
After installation:
- Open the application menu (Kickoff) and search for “Window Layout”.
- Right-click “Save Window Layout” and “Restore Window Layout” and choose “Add to Taskbar” (or drag them onto the taskbar).
A click runs the command and shows a desktop notification with the result.
Automatically after login
install.sh sets up an autostart entry that restores layout “default” at
several intervals after login — until all saved windows are matched (apps often
open with a delay after login).
Use a different layout for autostart:
# adjust the argument in ~/.config/autostart/winlayout-autostart.desktop:
Exec=.../winlayout-autostart workstation
Or via the environment variable WINLAYOUT_AUTOSTART_NAME.
How it works (brief)
winlayout generates small KWin JavaScript snippets and loads them at runtime
via the D-Bus path org.kde.KWin /Scripting (loadScript + start).
- Save: the script runs inside KWin, reads
workspace.windowList()and sends the geometry back viacallDBusto a short-lived Python D-Bus receiver that writes it as JSON. (KWin scripts cannot write files themselves — hence the small detour via D-Bus.) - Restore: the saved JSON is embedded into a KWin script that matches the
current windows by application + window title and repositions them via
w.frameGeometry = {x, y, width, height}.
Layouts are stored in ~/.config/winlayout/<name>.json.
Notes & limitations
- Restore requires open windows. Matching is done by application
(
resourceClass) and window title. For multiple windows of the same app the title is matched as well. Apps that are not running yet are skipped. - The coordinates are logical/scaled screen coordinates. With an unchanged monitor setup this restores pixel-perfectly. With a changed monitor layout windows may end up off-screen.
- Fullscreen (
fullScreen) is recorded but not re-applied on restore (there is no reliable per-window setter in the scripting API). - Specific virtual desktops (desktop 2, 3, …) are currently only covered via “on all desktops”, not assigned per desktop.
Files
winlayout main tool (Python 3)
winlayout-click wrapper with notification for panel clicks
winlayout-autostart autostart helper (retries until all windows are present)
applications/*.desktop.in templates for the application-menu entries
autostart/*.desktop.in template for the KDE autostart
install.sh / uninstall.sh installation / uninstallation
License
MIT — see LICENSE.