Linux有没有方法监控到剪贴板内容的变化?

开发基于GTK+或QT的应用程序
回复
fielding_st
帖子: 7
注册时间: 2014-02-22 22:13
送出感谢: 0
接收感谢: 0

Linux有没有方法监控到剪贴板内容的变化?

#1

帖子 fielding_st » 2016-03-24 15:05

软件环境:ubuntu14.04
硬件环境:PC x86

Linux里面有selection或clipboard,相当于Windows的剪贴板,当文字被选中或者按Ctrl+C时,内容会进入剪贴板。

我最近在做一个功能:当剪贴板内容发生变化时,检测剪贴板内的新内容是否合法。

我当前遇到的一个问题就是如何监控剪贴板内容的变化,不是内容,是内容的变化,内容何时发生了变化。
我研究了一下剪贴板监控工具xclip的源码,其调用X11系列的Xmu库API,从剪贴板获取内容,采用的方式是查询。
通过不断读取剪贴板的内容,和上次作比较,当然也可以知晓剪贴板何时发生了变化,但查询这种方式非常耗时,而且效率也很低。
请问有没有一种类似回调函数或事件通知的方法,可以监控到剪贴板内容的变化?

比如:
当前剪贴板内容是abc,当剪贴板内容变为def的时候,我就可以得到一个通知或剪贴板内容变化事件。

谢谢各位。
谢宝良
帖子: 1979
注册时间: 2010-05-01 21:23
送出感谢: 4 次
接收感谢: 21 次

Re: Linux有没有方法监控到剪贴板内容的变化?

#2

帖子 谢宝良 » 2016-03-24 16:33

我曾使用python监控剪贴板的图片文件,一旦剪贴板出现新图片就保存为文件到指定目录下。
脚本就在论坛上。

哦,不好意思,你是要高效率的方法。那就没辙了。
头像
millenniumdark
论坛版主
帖子: 4159
注册时间: 2005-07-02 14:41
系统: Ubuntu 14.04 (Kylin)
送出感谢: 42 次
接收感谢: 9 次
联系:

Re: Linux有没有方法监控到剪贴板内容的变化?

#3

帖子 millenniumdark » 2016-03-24 16:55

短答案:没有。

长答案:
有没有一种类似回调函数或事件通知的方法,可以监控到剪贴板内容的变化
为了避免两个程序同时写内容到剪贴板(拷贝)产生错乱,显然需要通知。
当剪切或粘贴发生时,程序 a 会用 XSetSelectionOwner() 通知 X11,
告知我要写入剪贴板。
然后当前拥有剪贴板的程序 b(假定 b 和 a 不是同一个程序)会收到 SelectionClear 事件,告知剪贴板控制器没了。

现在你的程序 c 要监听这个程序,除了
通过不断读取剪贴板的内容,和上次作比较
还有一种方法就是不断成为 b,(也就是不断 XSetSelectionOwner() ),以便将来能收到 SelectionClear。

这样不需要读取剪贴板内容,理论上应该快一点(特别是剪贴复制的内容较多的情况下),不过到底如何还是要 benchmark 一下看看。

更优雅的应该是到 X11 那里注册:「你要是收到 XSetSelectionOwner(),也通知我一下。」

遗憾的是 X11 没有提供这样的机制。

http://www.x.org/releases/X11R7.6/doc/f ... sproto.txt

上面是 X11 的一个补丁,提供了 SelectionNotify 事件,可以用来监视剪贴板改变。
fielding_st
帖子: 7
注册时间: 2014-02-22 22:13
送出感谢: 0
接收感谢: 0

Re: Linux有没有方法监控到剪贴板内容的变化?

#4

帖子 fielding_st » 2016-03-25 11:46

多谢楼上两位帮助,非常感谢:-)))。

@millenniumdark兄所提到的补丁是针对X11R7.6的,我找到了X11R7.5的Glib库帮助文档(见http://www.x.org/archive/X11R7.5/doc/libX11/libX11.html),
R7.5里也已经有SelectionNotify事件了,不知道这个补丁是补了什么,看了两遍硬是没看出来新SelectionNotify是干啥用的,惭愧,回头我再研究研究~

我还有下面两个疑惑的地方:

疑一:SelectionNotify事件如何产生的?
先说下我对此事件的理解,这是从对Xclip源码的阅读和调试中得到的部分见解,如有谬误请指正,哈。
关于剪贴板,除了@millenniumdark兄所提到的XSetSelectionOwner外,还有下面两个重要的:
XGetSelectionOwner和XConvertSelection
对于XConvertSelection,官方有如下的解释:
XConvertSelection requests that the specified selection be converted to the specified target type:
·If the specified selection has an owner, the X server sends a SelectionRequest event to that owner.
·If no owner for the specified selection exists, the X server generates a SelectionNotify event to the requestor with property None.
Xclip是这样使用XConvertSelection接口得到SelectionNotify事件的:
发送XConvertSelection请求,然后等待SelectionNotify事件,当得到这个事件后,读取剪贴板。
这和官方对XConvertSelection的解释对不上啊,剪贴板有内容时应该是有owner的,如果Xclip发送XConvertSelection请求,不应该会收到SelectionNotify事件的啊。
嗯,我觉得此事定有蹊跷,除非这里面有一个天大的秘密,元芳你凑上来看看:-)。

疑二:XSetSelectionOwner会不会导致剪贴板内容不可用?
举个栗子:
1.程序a目前拥有剪贴板,剪贴板里面有一段内容是aaa
2.调用XSetSelectionOwner接口,使b拥有剪贴板
此时剪贴板内容会发生变化吗,在其他编辑器内按ctrl+V,是否能得到预想的aaa?

以上,还望不吝指教,thx。
回复

回到 “GTK+和QT”