Universal Window Position & Dimension Persistence for Chromium / Chrome PWAs on KDE Plasma 6 (Wayland)
When running Chromium or Google Chrome Progressive Web Apps (PWAs) — such as Gmail, Messenger, Facebook, Slack, or YouTube — on KDE Plasma 6 under Wayland, users frequently encounter a severe window geometry issue. PWAs fail to remember their previous window dimensions and positions across sessions, often defaulting to arbitrary, maximized, or stretched sizes (e.g., spanning entire multi-monitor arrays or opening as a full vertical column).
This forces the user to manually resize and reposition web apps every time they are launched, severely degrading the desktop experience.
The problem stems from a combination of Wayland protocol restrictions, Chromium's rendering pipeline, and KWin's window matching logic:
-
Wayland
xdg_shellProtocol Restrictions: Unlike X11, the modern Wayland protocol prioritizes security and composition integrity by deliberately restricting client applications from setting their own absolute screen coordinates. The compositor (KWin) has final authority over where a window is placed. -
Chromium's Ozone Wayland Backend Behavior: When Chromium runs under native Wayland (
--ozone-platform=wayland), it ignores KWin's suggested configure size during the initial window mapping phase. Instead of conforming to the compositor's placement hints, Chromium commits its own internal default buffer size unless explicitly overridden with the--window-sizecommand-line flag. This results in the unpredictable dimensions observed on launch. -
The Mixed-DPI XWayland Dilemma: A common workaround is to force Chromium to run via XWayland (
--ozone-platform=x11), which successfully restores legacy window geometry memory. However, on modern hardware — specifically mixed-DPI dual monitor setups (e.g., a 4K display at 200% scaling alongside a 1440p display at 100%) — XWayland applications suffer from severe blurriness because Wayland scales the bitmap output rather than rendering native vectors. Therefore, native Wayland is required for crisp text rendering. -
The Failure of Static KWin Rules: Attempting to solve this by creating static KWin Rules (
kwinrulesrc) with regex matching for thechromewindow class often backfires. Chromium PWAs launched from the same binary often share identical properties during early initialization, causing KWin to map them to a single shared geometry entry. Consequently, opening Messenger might overwrite the saved position of Gmail, resulting in a chaotic "last app opened dictates the geometry for all" scenario.
The robust solution is to bypass static rules and employ native Wayland dynamic tracking using the KDE Plasma 6 KWin Script: Remember Window Positions (rememberwindowpositions).
Instead of relying on broad window classes, this script listens for window lifecycle events and accurately tracks client.resourceClass (which maps to the unique Chrome app ID, e.g., chrome-<hash>-Default). It independently serializes and restores geometries dynamically, ensuring every PWA remembers its exact coordinates and dimensions without interfering with others.
Follow these steps to permanently fix PWA window geometry on Plasma 6 Wayland.
Download the "Remember Window Positions" script repository and place it in the correct KDE directory.
Critical Pitfall: The directory name must exactly match the Plugin ID defined in the script's metadata.json (rememberwindowpositions). Do not name the directory RWP or nest the files inside a src/ folder.
mkdir -p ~/.local/share/kwin/scripts/rememberwindowpositions
# Extract or copy the contents of the script directly into this directory:
# ~/.local/share/kwin/scripts/rememberwindowpositions/
# ├── metadata.json
# └── contents/
# └── code/
# └── main.jsAdd the script to your KWin plugins configuration.
# Open ~/.config/kwinrc in an editor
nano ~/.config/kwinrcEnsure the following entry exists under the [Plugins] section:
[Plugins]
rememberwindowpositionsEnabled=trueYou do not need to log out to apply this change. Use DBus to reload KWin scripts on the fly:
# Reload the KWin Scripting engine
qdbus6 org.kde.KWin /Scripting org.kde.kwin.Scripting.unloadScripts
qdbus6 org.kde.KWin /Scripting org.kde.kwin.Scripting.startEnsure the script successfully loaded without syntax errors or missing metadata.
Check the DBus state to confirm it is loaded:
qdbus6 org.kde.KWin /Scripting org.kde.kwin.Scripting.isScriptLoaded rememberwindowpositions
# Should return: trueYou can also monitor the system journal for KWin Javascript logs:
journalctl -f --user-unit plasma-kwin_wayland.service
# Launch a PWA and move it; you should see "Remember Window Positions" logging the geometry updates.If you previously attempted to fix this using built-in Plasma window rules, they will conflict with the script.
Open System Settings -> Window Management -> Window Rules, and delete any rules matching "Chrome", "Chromium", or "Web Apps" that enforce Size, Position, or Screen.
Alternatively, manually edit ~/.config/kwinrulesrc and remove the offending [Rule_X] blocks, then run:
qdbus6 org.kde.KWin /KWin org.kde.KWin.reconfigureEnsure your PWA shortcut passes the correct Wayland ozone flags and exposes its WMClass cleanly so the script can hook into it.
Example ~/.local/share/applications/messenger.desktop:
[Desktop Entry]
Version=1.0
Terminal=false
Type=Application
Name=Messenger
Exec=/usr/bin/google-chrome-stable --profile-directory=Default --app-id=hnpfjngllnobngcgfapehpigfocgpmho --ozone-platform=wayland
Icon=chrome-hnpfjngllnobngcgfapehpigfocgpmho-Default
StartupWMClass=chrome-hnpfjngllnobngcgfapehpigfocgpmho-DefaultNote: You can find the correct app-id and StartupWMClass by inspecting the launcher Chrome automatically creates when you "Install App" from the browser menu.
With these steps applied, native Wayland PWAs will flawlessly remember their monitor placement, size, and maximize state across reboots and multi-monitor hotplugs.