Hello everyone!
If you use GNOME on Wayland and install your browsers (like Brave or Microsoft Edge) via Flatpak, you’ve probably noticed a very annoying issue: when you install a PWA (like Microsoft Teams, YouTube, etc.), the icon doesn’t separate from the main browser in the dash/dock.
I was trying to fix this on Fedora, but this applies to any distro using GNOME Wayland.
The Root Cause: The issue happens because the StartupWMClass in the generated .desktop file doesn’t match the actual wmclass the browser window reports to Wayland. Using GNOME’s Looking Glass (Alt+F2, type lg, go to Windows), I noticed that Flatpak browsers export very specific and sometimes weird IDs. For example, Edge exports something like msedge-_[APP-ID]-Default (notice the weird dash and underscore together). GNOME can’t match it, so it groups it with the main browser.
The Solution: I wrote a bash script that automatically finds all your Flatpak PWA .desktop files, extracts the exact app-id and profile, and dynamically injects the correct StartupWMClass based on the browser’s behavior.
How to use it:
-
Create a file named
fix_pwa_icons.sh. -
Paste the following code:
Bash
#!/bin/bash
APP_DIR="$HOME/.local/share/applications"
echo "--- Starting PWA fix (GNOME Wayland / Flatpak) ---"
find "$APP_DIR" -name "*.desktop" -type f | while read -r file; do
# Check if it's a PWA by looking for the app-id flag
if grep -q -- "--app-id=" "$file"; then
echo "Processing: $(basename "$file")"
# Extract App ID and Profile from the Exec= line, cleaning up quotes
APP_ID=$(grep -o -- '--app-id=[^ ]*' "$file" | head -n 1 | cut -d= -f2 | tr -d "'" | tr -d '"')
PROFILE=$(grep -o -- '--profile-directory=[^ ]*' "$file" | head -n 1 | cut -d= -f2 | tr -d "'" | tr -d '"')
if [ -n "$APP_ID" ] && [ -n "$PROFILE" ]; then
# Build the WM_CLASS depending on the browser
if [[ "$file" == *"msedge"* ]]; then
# Edge specific format found via Looking Glass: msedge-_APPID-Profile
WM_CLASS="msedge-_${APP_ID}-${PROFILE}"
echo " -> Edge PWA detected. Applying msedge-_ format."
elif [[ "$file" == *"brave"* ]]; then
# Standard format for Brave
WM_CLASS="brave-${APP_ID}-${PROFILE}"
echo " -> Brave PWA detected."
else
# Fallback
WM_CLASS="${APP_ID}-${PROFILE}"
fi
# Replace or append StartupWMClass
if grep -q "^StartupWMClass=" "$file"; then
sed -i "s|^StartupWMClass=.*|StartupWMClass=$WM_CLASS|" "$file"
echo " -> Updated to: $WM_CLASS"
else
sed -i "/^\[Desktop Entry\]/a StartupWMClass=$WM_CLASS" "$file"
echo " -> Added: $WM_CLASS"
fi
else
echo " -> Error: Could not extract APP_ID or Profile."
fi
fi
done
echo "--- Refreshing desktop database... ---"
update-desktop-database "$APP_DIR"
echo "--- Process completed successfully ---"
-
Make the script executable:
chmod +x fix_pwa_icons.sh -
Run the script:
./fix_pwa_icons.sh -
Fully close your browser and any running PWAs. When you open your PWA again, it will finally have its own separate icon in the GNOME dock!
Note: You might need to run this script again whenever you install a new PWA. I hope this saves someone the headache I went through!