【问题标题】:X11 Wait for and Get Clipboard TextX11 等待并获取剪贴板文本
【发布时间】:2012-02-04 01:01:50
【问题描述】:

我必须监控 X11 剪贴板。

目前,我每 5 秒请求一次剪贴板选择,然后对从剪贴板返回的文本进行哈希处理,并将其与上次检查的哈希计算进行比较。如果hash不一样,我会分析文本内容并做一些事情......

我不喜欢我的方法。我是windows的,winapi是内核在剪贴板发生变化时通知你的程序,效率更高!

我只是想知道当剪贴板发生变化时,X11 是否可以将您的程序通知为 winapi?使用 X11 检查剪贴板修改的更有效方法是什么?

【问题讨论】:

    标签: c x11


    【解决方案1】:

    这是一个很好的参考:http://www.jwz.org/doc/x-cut-and-paste.html

    【讨论】:

    • 这不能回答问题。
    【解决方案2】:
    1. 使用GetSelectionOwner(主要和剪贴板)查找带有选择的窗口
    2. 通过发送 SelectionRequest 获取选择副本,通知您的应用程序
    3. 关注SelectionClear 事件
    4. 使用来自SelectionClear 事件的 id 选择更新窗口,转到第 2 步

    【讨论】:

    • 选择所有者关闭后怎么办?
    【解决方案3】:

    使用 Xfixes 扩展中的XFixesSelectSelectionInput() 并等待XFixesSelectionNotify 事件。

    示例:

    // gcc -o xclipwatch xclipwatch.c -lX11 -lXfixes
    ...
    #include <X11/extensions/Xfixes.h>
    ...
    void WatchSelection(Display *display, Window window, const char *bufname)
    {
      int event_base, error_base;
      XEvent event;
      Atom bufid = XInternAtom(display, bufname, False);
    
      assert( XFixesQueryExtension(display, &event_base, &error_base) );
      XFixesSelectSelectionInput(display, DefaultRootWindow(display), bufid, XFixesSetSelectionOwnerNotifyMask);
    
      while (True)
      {
        XNextEvent(display, &event);
    
        if (event.type == event_base + XFixesSelectionNotify &&
            ((XFixesSelectionNotifyEvent*)&event)->selection == bufid)
        {
          if (!PrintSelection(display, window, bufname, "UTF8_STRING"))
            PrintSelection(display, window, bufname, "STRING");
    
          fflush(stdout);
        }
      }
    }
    ...
    

    这适用于bufname == "CLIPBOARD"bufname == "PRIMARY" 选择。

    另见PrintSelection()函数in this answer

    【讨论】:

    • 请不要将强制命令放入assert()because assert() leaves the impression that it can be left away(参见NDEBUG)。更好:int xfixinstalled = XFixesQueryExtension(display, &amp;event_base, &amp;error_base); assert(xfixinstalled);
    • 我的 Ubuntu 20.04 中似乎缺少 X11/extensions/xfixes.h - 知道在哪里可以找到它吗?它是必须安装的东西吗?我只看到 xfixesproto.h
    【解决方案4】:

    x11user 接受的答案是一个很好的答案。但是你可能想要一个非阻塞的 while 循环,为此你可以接受这个答案,并像这样调整它。

    // get the internal X11 event file descriptor
    int x11fd = ConnectionNumber(display);
    
    while(!shutdown)
    {
      if(!XPending(display)) {
        // wait on the file descriptor
        // you can use poll, epoll, select, eventfd, etc.
      }
    
      XNextEvent(display, &event);
      // process the event
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-07-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-01-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多