Skip to main content
SZCZ

Pinning Emacs in the KDE Launcher

KDE Top Bar and Emacs

I ran into a mildly annoying issue with KDE’s taskbar. I keep a few apps pinned - Firefox, Emacs, Teams, and others - and the order matters because I switch between them using keyboard shortcuts like Meta+1, Meta+2, etc.

KDE couldn’t reliably decide whether it should treat emacs and emacsclient as the same application. As a result, pressing Meta+2 might:

In other words, the taskbar kept losing track of which Emacs window belonged where. The only reliable reset was to close Emacs completely and start again.

I assume KDE was getting confused about window classes between the daemon and the client.

Solution

I ended up writing this .desktop file

[Desktop Entry]
Name=Emacs
Comment=GNU Emacs
Exec=emacsclient -c -a ""
Icon=emacs
Type=Application
Terminal=false
Categories=Development;TextEditor;
StartupWMClass=Emacs
StartupNotify=true

I saved this to ~/.local/share/applications/emacs-custom.desktop, then pinned that to my taskbar instead of the default Emacs launcher.

The key parts:

After this, Meta+2 behaves consistently: it either focuses the existing Emacs window or opens a new one in the correct taskbar slot.

Possibly I created this problem myself in the first place and solved it in a roundabout way - but at least it works.

Plasma 6

June 2025 I was just setting up KDE (with Plasma 6) on another PC (NixOS this time around). I followed the steps above and found that... it doesn't work.

I did get it working by adapting the above slightly: instead of putting emacsclient -c -a "" in the Exec part I call out to a custom script:

# Check if the Emacs daemon is running
# Use 'emacsclient -e "(daemonp)"' to check.
# The '>/dev/null 2>&1' suppresses output and errors.
if emacsclient -e '(daemonp)' >/dev/null 2>&1; then
    # Daemon is running, launch Emacs client
    # -c: Create a new frame
    # "$@": Pass all arguments (like filenames) to emacsclient
    exec emacsclient -c "$@"
else
    # Daemon is not running, launch full Emacs GUI
    # "$@": Pass all arguments (like filenames) to emacs
    exec emacs "$@"
fi

Important note: make sure to put %F at the end of the Exec and chmod +x the script:

[...]
Exec=/path/to/script.sh %F
[...]