【问题标题】:X11 Copy is returning only returning GDK_SELECTION, for CLIPBOARD SelectionX11 Copy 只返回 GDK_SELECTION,用于剪贴板选择
【发布时间】:2021-09-24 01:03:39
【问题描述】:

我正在编写一个组件,它必须监视 X11 窗口的剪贴板中的变化。

auto display = XOpenDisplay(NULL);
auto screen = DefaultScreen(mdisplay);
auto root_window = RootWindow(display, screen);
clipboard = XInternAtom(display, "CLIPBOARD", 0);
window = XCreateSimpleWindow(mdisplay, root_window, 0, 0, 1, 1, 0, 0, 0);
while(true) {
    XEvent event = {0};
    XNextEvent(display, &event);
    switch(event.type) {
        case SelectionNotify: {
            // do something
        }
        break;
        case SelectionRequest: { // triggered after performing copy
            auto target_name = XGetAtomName(display, event.xselectionrequest.target);
            auto selection_name = XGetAtomName(display, event.xselectionrequest.selection);
            auto property_name = XGetAtomName(display, event.xselectionrequest.property);
            Log("Event SelectionRequest: owner: %ld, requestor: %ld, selection: %s, target: %s(%d), property: %s",
                    event.xselectionrequest.owner, 
                    event.xselectionrequest.requestor,
                    selection_name,
                    target_name,
                    event.xselectionrequest.target,
                    property_name);

            if(x_event.xselectionrequest.selection != clipboard) {
                Log("%s: Warning: event selection not matching\n", __func__);
                break;
            }
        }
        break;
    }
}

问题是当我尝试检查事件 SelectionRequest 时,我看到的只是

Event SelectionRequest: owner: 33554433, requestor: 18874649, selection: CLIPBOARD, target: TARGETS(344), property: GDK_SELECTION

我正在执行的操作是从 Chrome 浏览器复制一些文本。谁能告诉我为什么我没有看到这个文本、unicode、字符串类型,而是GDK_SELECTION?

PS: 碰巧我只看到过一次这些格式(文本、unicode、字符串类型),但再也没有看到过。

【问题讨论】:

    标签: c++ linux x11 copy-paste pasteboard


    【解决方案1】:

    要读取剪贴板中的数据,您需要:

    • 以 TARGETS 作为目标原子调用 XConvertSelection
    • 等待 SelectionNotify 事件并使用 XGetWindowProperty 读取可用目标
    • 使用首选目标调用 XConvertSelection
    • 等待 SelectionNotify 事件并使用 XGetWindowProperty 读取可用数据

    更多信息请查看this answer

    发布听到幼稚的实现仅用于描述主要思想。

    // gcc -o xclipget xclipget.c -lX11
    #include <stdio.h>
    #include <limits.h>
    #include <X11/Xlib.h>
    
    Bool PrintSelection(Display *display, Window window, const char *bufname, const char *fmtname)
    {
      char *result;
      unsigned long ressize, restail;
      int resbits;
      Atom bufid = XInternAtom(display, bufname, False),
           fmtid = XInternAtom(display, fmtname, False),
           propid = XInternAtom(display, "XSEL_DATA", False),
           incrid = XInternAtom(display, "INCR", False);
      XEvent event;
    
      XConvertSelection(display, bufid, fmtid, propid, window, CurrentTime);
      do {
        XNextEvent(display, &event);
      } while (event.type != SelectionNotify || event.xselection.selection != bufid);
    
      if (event.xselection.property)
      {
        XGetWindowProperty(display, window, propid, 0, LONG_MAX/4, False, AnyPropertyType,
          &fmtid, &resbits, &ressize, &restail, (unsigned char**)&result);
    
        if (fmtid == incrid)
          printf("Buffer is too large and INCR reading is not implemented yet.\n");
        else
          printf("%.*s", (int)ressize, result);
    
        XFree(result);
        return True;
      }
      else // request failed, e.g. owner can't convert to the target format
        return False;
    }
    
    int main()
    {
      Display *display = XOpenDisplay(NULL);
      unsigned long color = BlackPixel(display, DefaultScreen(display));
      Window window = XCreateSimpleWindow(display, DefaultRootWindow(display), 0,0, 1,1, 0, color, color);
      Bool result = PrintSelection(display, window, "CLIPBOARD", "UTF8_STRING") ||
                    PrintSelection(display, window, "CLIPBOARD", "STRING");
      XDestroyWindow(display, window);
      XCloseDisplay(display);
      return !result;
    }
    

    【讨论】:

    • 虽然此链接可能会回答问题,但最好在此处包含答案的基本部分并提供链接以供参考。如果链接页面发生更改,仅链接答案可能会失效。 - From Review
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-18
    • 2012-02-04
    • 2010-11-02
    • 1970-01-01
    相关资源
    最近更新 更多