Emacs on WSLg: Copying to the Windows Clipboard

Emacs has been my daily driver for software development and various other tasks for quite some time. I usually use it on Linux, but at my current job, I am forced to run Windows as my main OS. Fortunately the Windows Subsystem for Linux (WSL) has become pretty usable, especially since MS added a bundled Wayland server that integrates into the Windows desktop (called WSLg).

However, one thing that kept annoying me: Copying text out of my Emacs (running in WSL/WSLg) into any Windows application did not work. I would expect that if I kill some text in Emacs (using e.g. kill-ring-save, bound by default to M-w), the text somehow makes its way to the Windows clipboard and can be pasted into any Windows application.

The Crucial Fix

If you are hit by this bug and just want to know how to fix it: It should probably be sufficient to just set select-active-regions to nil, i.e., add this to your init.el file:

1(setq select-active-regions nil)

It may also be necessary to make sure that select-enable_clipboard, select-enable-primary, and interprogram-cut-function are at their default settings:

1(setq select-enable-clipboard 't)
2(setq select-enable-primary nil)
3(setq interprogram-cut-function #'gui-select-text)

What’s Going On

The old X Window System knows about an arbitrary number of so-called selections. These can be used to pass data from one application to another, and Copy-and-Paste on X systems is implemented using these selections. Usually, only two of these selections are used, one named PRIMARY and one named CLIPBOARD. Usually, PRIMARY is used for (e.g.) text selected by the user without explicitly asking for it to be copied - for example when you just select some text using your mouse in some terminal. On the other hand, CLIPBOARD is used when the user explicitly asks for some contents to be copied.

On the MS Windows side, there is no PRIMARY (and there is no arbitrary-number-of-selections system either). There’s basically only CLIPBOARD. A Windows build of Emacs knows about this and never tries to copy any data to the PRIMARY selection. However, we’re running a Linux build (in WSL) which is connected to an Wayland server (in WSLg), so Emacs very much thinks that it has a PRIMARY selection available.1

Why is this a problem?

When you invoke kill-ring-save (or any other kill command), that’s an explicit copy operation that should go to the CLIPBOARD selection and everything should work out fine, right? This is true, and that’s basically what the default values select-enable-clipboard 't and select-enable-primary nil say: Copy text to CLIPBOARD, do not copy text to PRIMARY. More precisely: The kill commands call the function assigned to interprogram-cut-function, which is set to gui-select-text by default, which handles the copying.

However, immediately after the kill operation is finished, the mark (which is active at this point, since you marked a region to kill) is deactivated. This causes Emacs to copy the previously-marked region to PRIMARY in the deactivate-mark function. And that’s where (I assume) a WSLg bug kicks in: If Emacs requests to copy something to PRIMARY, the WSLg Weston server seems to clear the Windows clipboard.

Setting (setq select-active-regions nil) tells deactivate-mark that the previous selection should not be copied, and the problem goes away.

Digging Deeper

Actually, it does not seem quite that simple. If I create a simple GTK application which basically just runs:

1// … setup of a simple GTK application skipped …
2
3// Copy "hello world" to CLIPBOARD
4gtk_clipboard_set_text(gtk_clipboard_get(GDK_SELECTION_CLIPBOARD), "hello world", -1);
5// Copy "foobar" to PRIMARY
6gtk_clipboard_set_text(gtk_clipboard_get(GDK_SELECTION_PRIMARY), "foobar", -1);

… then after executing this in WSL(g), I can paste “hello world” in MS Windows, as expected. Even if I throw in a:

1// Clear the PRIMARY selection
2gtk_selection_clear_targets(gdk_get_default_root_window(), GDK_SELECTION_PRIMARY);

it still works.

Emacs’ pgtk backend does seem to do something significantly more involved - have a look at src/pgtkselect.c in the Emacs sources. That’s almost 2000 lines of GTK/GDK code which goes way beyond what I know about GTK or GDK, so I’ll just happily accept that I found a workaround and stop digging. I still assume that this is somehow a WSLg quirk, and Emacs does not seem to be alone in this: There are currently 36 open issues in the WSLg repository containing the word ‘clipboard’.


  1. Actually, Wayland does not have a PRIMARY selection either, at least without this extension. However, the GTK library that Emacs uses as its backend was written back in the days when X was the new and shiny stuff, so GTK assumes multiple selections exist. I do not know how this translates to the Wayland backend… ↩︎

Comments

You can use your Mastodon account to reply to this post.

Reply to tinloaf's post

With an account on the Fediverse or Mastodon, you can respond to this post. Since Mastodon is decentralized, you can use your existing account hosted by another Mastodon server or compatible platform if you don't have an account on this one.

Copy and paste this URL into the search field of your favourite Fediverse app or the web interface of your Mastodon server.