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),如(剪贴板选择传输不起作用)中的答案,但我仍然观察到相同的行为。