No description
  • Python 62.9%
  • Shell 37.1%
Find a file
nocci 84a4f9b6d3 Translate README and all comments to English
- 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
2026-07-21 14:18:10 +02:00
applications Initial release: save & restore KDE/KWin window layouts on Wayland 2026-07-21 14:14:35 +02:00
autostart Initial release: save & restore KDE/KWin window layouts on Wayland 2026-07-21 14:14:35 +02:00
.gitignore Initial release: save & restore KDE/KWin window layouts on Wayland 2026-07-21 14:14:35 +02:00
install.sh Translate README and all comments to English 2026-07-21 14:18:10 +02:00
LICENSE Initial release: save & restore KDE/KWin window layouts on Wayland 2026-07-21 14:14:35 +02:00
README.md Translate README and all comments to English 2026-07-21 14:18:10 +02:00
uninstall.sh Translate README and all comments to English 2026-07-21 14:18:10 +02:00
winlayout Translate README and all comments to English 2026-07-21 14:18:10 +02:00
winlayout-autostart Translate README and all comments to English 2026-07-21 14:18:10 +02:00
winlayout-click Translate README and all comments to English 2026-07-21 14:18:10 +02:00

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 windows
  • winlayout restore [name] restore an arrangement exactly
  • winlayout list list saved layouts
  • winlayout rm <name> delete a layout
  • winlayout 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: in qt6-tools)
  • notify-send (Arch: in libnotify)

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:

  1. Open the application menu (Kickoff) and search for “Window Layout”.
  2. 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 via callDBus to 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.