Linux XGetSelectionOwner() How to get the App's main window from selection owner?

1

[EDIT] I have changed my program so I no longer need to use XGetSelectionOwner(), so I no longer need an answer. Should I delete this post? [END-EDIT]

I want to get the ID of the App's main window that has the current selection, to save, so after doing something with the selection I can then raise/activate/focus the original App.

What is returned by XGetSelectionOwner()?

[EDIT] How do I get the program main window ID from this?

[EDIT2] Added stripped down code with its output:

//Filter and Read Selected Text with ReadPlease
// g++ RP.c -lX11 -o RPo

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

#define MAX_PROPERTY_VALUE_LEN 4096

typedef unsigned long ulong;

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

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

  // Show the client window list with ids and names
  Get_CL(dsp);

  // Get the selection window
  Window swn = XGetSelectionOwner(dsp, XA_PRIMARY);
  printf("s = 0x%08lx\n", swn);
  if(!swn) {
    exit(0);
  }

  Window parent_win; // ID of the parent window of our window
  Window root_win; // root window of the screen our window is mapped on
  Window* child_windows; // array of IDs of the child windows
  uint num_child_windows;

  /* finally, make the query for the above values. */
  XQueryTree(dsp, swn,
         &root_win,
         &parent_win,
         &child_windows, &num_child_windows);
  printf("r = 0x%08lx p = 0x%08lx c = %d\n",
          root_win, parent_win, num_child_windows);

  // Get the selection
  // <snip>

  if(swn) {
    // What window do I need here?
    XSetInputFocus(dsp, swn, RevertToParent, CurrentTime);
    printf("s = 0x%08lx\n", swn);
  }

  XCloseDisplay(dsp);
}

static void Get_CL(Display *dsp)
{
  // Get client list
  ulong client_list_size;
  static Window *cl = get_client_list (dsp, &client_list_size);
  int cls = client_list_size / sizeof(Window);
  for (int i = 0; i < cls; i++) {
    char *wm_name = get_property(dsp, cl[i], XA_STRING, "WM_NAME", NULL);
    printf("w = 0x%08lx N = %s\n", cl[i], wm_name);
    XFree(wm_name);
  }
  XFree(cl);
}

static Window *get_client_list(Display *disp, ulong *size) {
  Window *client_list;
  if ((client_list = (Window *)get_property(disp, DefaultRootWindow(disp),
         XA_WINDOW, "_NET_CLIENT_LIST", size)) == NULL) {
    return NULL;
  }
  return client_list;
}

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);
        XFree(ret_prop);
        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;
    }

    XFree(ret_prop);
    return ret;
}

The results with nothing selected are:

owner@OP755 ~/dev/KBSim $ ./RPs
w = 0x00e00003 N = Bottom Expanded Edge Panel
w = 0x0220001c N = x-caja-desktop
w = 0x03e0008e N = meld - What are "synchronzation points"? - Stack Overflow - Mozilla Firefox
w = 0x03600082 N = RP_snip.c (~/dev/KBSim) - pluma
w = 0x04200003 N = Terminal
w = 0x03602154 N = Find
w = 0x02353596 N = owner
w = 0x03c00002 N = ReadPlease Plus 2003
w = 0x03c00004 N = ReadPlease Plus 2003: .\Help\rpInstructions.txt
s = 0x00000000

And with a selection:

owner@OP755 ~/dev/KBSim $ ./RPs
w = 0x00e00003 N = Bottom Expanded Edge Panel
w = 0x0220001c N = x-caja-desktop
w = 0x03e0008e N = meld - What are "synchronzation points"? - Stack Overflow - Mozilla Firefox
w = 0x03600082 N = RP_snip.c (~/dev/KBSim) - pluma
w = 0x04200003 N = Terminal
w = 0x03602154 N = Find
w = 0x02353596 N = owner
w = 0x03c00002 N = ReadPlease Plus 2003
w = 0x03c00004 N = ReadPlease Plus 2003: .\Help\rpInstructions.txt
s = 0x03e034c2
r = 0x0000007d p = 0x0000007d c = 0
s = 0x03e034c2
X Error of failed request:  BadMatch (invalid parameter attributes)
  Major opcode of failed request:  42 (X_SetInputFocus)
  Serial number of failed request:  21
  Current serial number in output stream:  23
owner@OP755 ~/dev/KBSim $ 

The line:

r = 0x0000007d p = 0x0000007d c = 0

shows the root, parent (and no children) windows. The root and parent are the same, and do not change if I make a selection in a different program.

I hope someone can make sense out of my poor code.

c
linux
x11
asked on Stack Overflow Dec 15, 2014 by Harvey • edited Dec 30, 2014 by Harvey

0 Answers

Nobody has answered this question yet.


User contributions licensed under CC BY-SA 3.0