Linux XGetSelectionOwner()如何从选择所有者那里获取应用程序的主窗口?

时间:2014-12-15 04:05:55

标签: c linux x11

[编辑]我已经更改了我的程序,因此我不再需要使用XGetSelectionOwner(),所以我不再需要答案。我应该删除这篇文章吗? [END-EDIT]

我想获取具有当前选择的应用程序主窗口的ID以进行保存,因此在对选择进行某些操作后,我可以提升/激活/聚焦原始应用程序。

XGetSelectionOwner()返回了什么?

[编辑]如何从中获取程序主窗口ID?

[EDIT2]添加了带有输出的精简代码:

//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;
}

未选择任何内容的结果是:

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

选择:

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 $ 

该行:

r = 0x0000007d p = 0x0000007d c = 0

显示root,parent(和no children)窗口。 root和parent是相同的,如果我在其他程序中进行选择,则不会更改。

我希望有人可以从我糟糕的代码中理解。

0 个答案:

没有答案