I've noticed that sometimes clipboard contents become unavailable if the source application (where the content was copied from) is closed.

This leads me to wonder if it's possible to know what the source application is (e.g. perhaps by PID).

Why? If the source application is a terminal, I'd like to find the working directory of the terminal, in case the copied contents is a relative path, to construct a full path to a file.

FYI, I'm currently using xclip to determine the clipboard contents, e.g.

xclip -selection primary -t STRING -o 2> /dev/null
  • 2
    XGetSelectionOwner(3) gets you the window id of the owner of the selection. From which you can walk up the window tree to try and find a window with a _NET_WM_PID property for instance with xprop (assuming that window comes from a local client that sets that property). xwininfo -root -tree | less +/0x<that-id> may be enough to identify the application. Jun 22, 2015 at 21:46
  • 2
    What @StéphaneChazelas said. But be aware that you are unlikely to get a reliable PID of the other client out of X11. Remembering that X clients connect to X servers through generic network connections (UNIX socket or TCP socket), a PID might be meaningless since the application might not be local. It might be connected over TCP (not common anymore these days) or an SSH-forwarded X11 connection (more common).
    – Celada
    Jun 23, 2015 at 2:10
  • Thanks for the notes -- I assume I'll need to write some C code to access XGetSelectionOwner then? I can probably do that - I'll post back when I get to a solution.
    – Jeff Ward
    Jun 23, 2015 at 17:42

1 Answer 1


I wrote a tool which returns the plain application name (e.g. 'Terminal', 'gedit' or 'SmartGit' which are the ones I tested). Most code is shamelessly stolen from @Harvey here.

// gcc clipboard-owner.c -lX11 -o clipboard-owner

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <X11/Xlib.h>
#include <X11/Xatom.h>


typedef unsigned long ulong;

static char *get_property(Display *, Window, Atom , const char *, ulong *);

int main(void) {
    // Open the Display
    Display *display = XOpenDisplay(NULL);

    // Get the selection window
    Window selection_owner = XGetSelectionOwner(display, XA_PRIMARY);
    if(!selection_owner) {
    } else {
          char *window_name = get_property(display, selection_owner, XA_STRING, "WM_NAME", NULL);
          printf("%s\n", window_name);


static char *get_property (Display *disp, Window win,
        Atom xa_prop_type, const char *prop_name, ulong *size) {
    Atom xa_prop_name;
    Atom xa_ret_type;
    int ret_format;
    ulong ret_nitems;
    ulong ret_bytes_after;
    ulong tmp_size;
    unsigned char *ret_prop;
    char *ret;

    xa_prop_name = XInternAtom(disp, prop_name, False);

    if (XGetWindowProperty(disp, win, xa_prop_name, 0,
            MAX_PROPERTY_VALUE_LEN / 4, False,
            xa_prop_type, &xa_ret_type, &ret_format,     
            &ret_nitems, &ret_bytes_after, &ret_prop) != Success) {
        printf("Cannot get %s property.\n", prop_name);
        return NULL;

    if (xa_ret_type != xa_prop_type) {
        printf("Invalid type of %s property.\n", prop_name);
        return NULL;

    /* null terminate the result to make string handling easier */
    tmp_size = (ret_format / 8) * ret_nitems;
    /* Correct 64 Architecture implementation of 32 bit data */
    if(ret_format==32) tmp_size *= sizeof(long)/4;
    ret = (char *)malloc(tmp_size + 1);
    memcpy(ret, ret_prop, tmp_size);
    ret[tmp_size] = '\0';

    if (size) {
        *size = tmp_size;

    return ret;
  • A great start, thanks! Hmm, it works with terminal, firefox, and chrome, but throws "Cannot get WM_NAME property" for others like emacs and robomongo, etc. I wonder if that's the "walk the tree" part Stéphane was referring to.
    – Jeff Ward
    Jun 29, 2015 at 16:37
  • I tried adding a "try parent until WM_NAME property is found" -- and that made emacs work, though not robomongo. Interesting. This answer also has some relevant info for finding the PID: unix.stackexchange.com/questions/5478/… Interestingly this PID (being cardinal?) is the same for all "Terminal" windows. This doesn't bode well for my specific use case, since each terminal may be in a separate current working directory.
    – Jeff Ward
    Jun 29, 2015 at 17:06
  • Yes. I had no luck with the "_NET_WM_PID" property to get the PID but I hoped you could use the name as a starting point.
    – jnodorp
    Jun 29, 2015 at 17:22
  • 1
    @JeffWard some modern terminal programs like gnome-terminal start only once instance of the application per session instead of one instance per terminal window like venerable xterm. Maybe that's why you are seeing the same PID in all of them? For gnome-terminal you used to be able to disable that misfeature with --disable-factory (odd name for an option) but apparently that might no longer be possible. Anyway, sounds like you need the pwd of one of the processes running inside the terminal, not of itself.
    – Celada
    Jun 29, 2015 at 23:53
  • @Celada - right, and it makes sense -- the X window system knows about windows, not necessarily what each program chooses to do with them. It also appears that Chrome has a separate window (or process?) dedicated to the clipboard. Apparently there are many schemata, and my idea may not pan out.
    – Jeff Ward
    Jun 30, 2015 at 14:22

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .