Skip to content

Instantly share code, notes, and snippets.

@Simon-CR
Created October 5, 2026 05:29
Show Gist options
  • Select an option

  • Save Simon-CR/fddd4b7ea9cc557ab4a7b8ae37befb1a to your computer and use it in GitHub Desktop.

Select an option

Save Simon-CR/fddd4b7ea9cc557ab4a7b8ae37befb1a to your computer and use it in GitHub Desktop.
Universal Window Position & Dimension Persistence for Chromium / Chrome PWAs on KDE Plasma 6 (Wayland)

Universal Window Position & Dimension Persistence for Chromium / Chrome PWAs on KDE Plasma 6 (Wayland)

Executive Summary / The Problem

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.

Deep Technical Root Cause

The problem stems from a combination of Wayland protocol restrictions, Chromium's rendering pipeline, and KWin's window matching logic:

  1. Wayland xdg_shell Protocol 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.

  2. 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-size command-line flag. This results in the unpredictable dimensions observed on launch.

  3. 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.

  4. The Failure of Static KWin Rules: Attempting to solve this by creating static KWin Rules (kwinrulesrc) with regex matching for the chrome window 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 Universal Solution

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.

Step-by-Step Implementation Guide

Follow these steps to permanently fix PWA window geometry on Plasma 6 Wayland.

1. Install the KWin Script

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.js

2. Enable the Script in KWin Configuration

Add the script to your KWin plugins configuration.

# Open ~/.config/kwinrc in an editor
nano ~/.config/kwinrc

Ensure the following entry exists under the [Plugins] section:

[Plugins]
rememberwindowpositionsEnabled=true

3. Activate Live Without Logging Out

You 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.start

4. Verify Script Execution

Ensure 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: true

You 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.

5. Clear Conflicting Rigid Override Rules

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.reconfigure

6. Standard PWA .desktop Launcher Template

Ensure 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-Default

Note: 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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment