Skip to main content
SZCZ

Pinning Emacs in the KDE Launcher

KDE Top Bar and Emacs

Here's an annoying problem I ran into. I have a few apps pinned to my KDE taskbar: Firefox, Emacs, Teams, and others. The order matters because I switch between them with keyboard shortcuts: Meta+1, Meta+2, etc.

The problem: KDE couldn't figure out whether to launch emacs or emacsclient. Sometimes clicking Meta+2 would:

Basically, (I think) KDE got confused about whether the daemon and client were the same app. Every time I wanted to reset things, I'd have to quit Emacs entirely and start over.

To reset things back I'd have to quit my Emacs instance and restart things.

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:

Now Meta+2 behaves consistently: it either focuses the existing Emacs or starts a new one in the right spot.

Maybe I caused the issue myself and fixed it in a roundabout way. Who knows.

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
[...]