在 X11 中使用 Xlib 复制粘贴选择:XA_TARGETS 原子数组

use*_*584 5 paste xlib selection gdk

我已经在 Xlib 程序中实现了文本字符串的复制粘贴。当我的程序拥有当前选择,并且我粘贴到 xterm、gimp 中的文本字段或 firefox 中时,它工作正常:我粘贴到的程序将 SelectionRequest 事件发送到我的程序,目标为 XA_UTF8_STRING ("UTF8_STRING "),我的程序会适当响应并粘贴字符串。

但是,当我的程序拥有当前选择,并且我尝试粘贴到 Thunderbird(版本 16.0.2)中的消息编写窗口或 SeaMonkey Web 浏览器(版本 2.20)中的文本字段中时,Thunderbird 和 SeaMonkey 会向我的程序发送一个 SelectionRequest 事件。使用目标 XA_TARGETS(“TARGETS”)进行程序,并且出现问题。我的理解是,我的程序应该响应它可以提供的一系列目标 - 我的程序的相关代码如下。(注意这是在64位机器上,Atom类型是64位)。Thunderbird / SeaMonkey 似乎对我的回复不满意,因为他们随后向我的程序发送了许多具有不同目标的后续 SelectionRequest 事件,就好像他们试图查看我将返回哪一个(他们尝试 application/x-moz-nativehtml, text/html、application/x-moz-file、image/png、image/jpeg、image/gif),然后最后尝试目标 UTF8_STRING,我的代码成功响应并粘贴了字符串。这一切可能需要 1 秒或更长时间,因此在粘贴字符串之前会有明显的延迟。

为了尝试调试,我修改了代码,以便当我粘贴到我的程序中时,另一个程序是所有者,我向它们发送一个带有目标 XA_TARGETS 的 SelectionRequest 事件,这样我就可以看到 Thunderbird 或 SeaMonkey 如何响应。我返回一个 SelectionNotify 事件,目标为 XA_TARGETS,并且该事件的属性设置为我请求的属性,当我在自己的窗口上读取该属性时,我发现它是一个类型为 XA_ATOM、格式为 32、长度为 0 的数组。因此,当我向 Thunderbird 或 SeaMonkey 询问时,我似乎没有从他们那里得到任何目标数组。

平台:Ubuntu 12.10 Linux x86_64

我使用的参考: http://svn.gna.org/svn/warzone/trunk/lib/betawidget/src/platform/sdl/clipboardX11.c

...
if ( event.type == SelectionRequest ) {
  Atom propertyOfRequestorToSet = event.xselectionrequest.property==None ? XA_PRIMARY : event.xselectionrequest.property;

  XSelectionEvent selEvent;
  selEvent.type = SelectionNotify;
  // selEvent.serial = event.xselectionrequest.serial; // I don't know if this is correct
  selEvent.send_event = True;
  selEvent.display = my_display;
  selEvent.requestor = event.xselectionrequest.requestor;
  selEvent.selection = event.xselectionrequest.selection;
  selEvent.target = event.xselectionrequest.target;
  selEvent.property = None;
  selEvent.time = event.xselectionrequest.time;

  if ( event.xselectionrequest.target == XA_TARGETS ) {

    Atom possibleTargets[] = { XA_UTF8_STRING, XA_STRING, XA_TEXT }; // [Note 2]

    // I checked, and this call returns 1
    XChangeProperty( my_display, event.xselectionrequest.requestor,
      propertyOfRequestorToSet,
      XA_ATOM,
      32, // 32 bits actually means long, according to what I've read // [Note 1]
      PropModeReplace,
      (unsigned char *) possibleTargets,
      sizeof(possibleTargets)/sizeof(possibleTargets[0])  // [Note 3]
    );

    selEvent.property = propertyOfRequestorToSet;
  }
  else ... {
  }

  if ( 0 == XSendEvent( my_display, selEvent.requestor, False, 0L, (XEvent*)&selEvent ) ) {
    printf("call to XSendEvent() failed\n");
  }
}
Run Code Online (Sandbox Code Playgroud)

注 1:如果我通过了 64,我会收到 BadValue X 错误。

注2:我尝试用 int possibleTargets[] = { (int)XA_STRING, (int)XA_UTF8_STRING, (int)XA_TEXT }; 替换这一行 这样数组将是 32 位字,并且行为是相同的。

注 3:我尝试过传递 1 个甚至 0 个元素的数组,并且行为是相同的。

在对 XChangeProperty() 的调用中,我还尝试传递格式为 8 且长度为 sizeof(possibleTargets),如(剪贴板选择传输不起作用)中的答案,但我仍然观察到相同的行为。