Linux中的剪贴板--X11和selection
简介
几乎所有的Linux发行版都使用X11
实现剪贴板功能
剪贴板的说法可能是从Windows
传入的, 在X11
中剪贴板就叫做selection
, 并且系统中可以有任意多个selection
如无特别说明, 下文的剪贴板和selection是相同的意思
复制和粘贴
从用户的直观感受来说, 基本的剪贴板操作有2个: 复制和粘贴
复制, 就是把数据放到剪贴板
粘贴, 就是把数据从剪贴板取出来
但是, 在X11
中的实现却不是这样
在X11
中复制
时, 数据并没有拷贝到剪贴板, 数据是在粘贴
时, 直接发送给粘贴的窗口
听起来有点抽象, 举个栗子
用户在窗口A选中了一段文字, 点击复制
然后在窗口B点击粘贴
X11剪贴板
X11
的实现流程是这的
- 窗口A所属的程序使用
XSetSelectionOwner()
获取剪贴板的所有权, 此时没有任何数据操作, 仅仅声明现在自己拥有剪贴板 - 窗口A所属的程序等待剪贴板的
粘贴
请求 - 用户在窗口B点击粘贴
- 窗口B所属的程序使用
XConvertSelection()
告诉XServer
说我要粘贴
, 请把数据发到我的窗口属性上 XServer
向窗口A发送粘贴
请求, 告诉A把数据设置到窗口B的属性上- 窗口A使用
XChangeProperty()
把数据设置到窗口B的属性上 - 窗口B收到剪贴板数据设置完成的通知, 使用
XGetWindowProperty()
把数据取出来
以上是大概的流程, 可以看到还是相当麻烦的
这是因为X协议是C/S架构
X客户端只能和XServer通信(可以把窗口A当做一个客户端, B当做另一个客户端)
窗口A要把剪贴板数据发给B只能通过XServer中转
以上流程使用libX11实现的关键代码如下
窗口A
sel = XInternAtom(dpy, "CLIPBOARD", False);
utf8 = XInternAtom(dpy, "UTF8_STRING", False);
// 窗口A拥有剪贴板
XSetSelectionOwner(dpy, sel, A, CurrentTime);
for (;;)
{
// 等待其他X客户端发出获取剪贴板数据的请求
XNextEvent(dpy, &ev);
switch (ev.type)
{case SelectionRequest:sev = (XSelectionRequestEvent*)&ev.xselectionrequest;// 把剪贴板数据设置到想要粘贴的x客户端窗口的属性上XChangeProperty(dpy, sev->requestor, sev->property, utf8, 8, PropModeReplace,(unsigned char *)now, strlen(now));// 发送SelectionNotify事件给请求剪贴板的x客户端XSendEvent(dpy, sev->requestor, True, NoEventMask, (XEvent *)&ssev);
}
窗口B
sel = XInternAtom(dpy, "CLIPBOARD", False);
utf8 = XInternAtom(dpy, "UTF8_STRING", False);
// 告诉窗口A, 把剪贴板数据转换成指定的格式,
// 并把数据放到窗口B的的属性上
// 此后窗口A会收到SelectionRequest事件
XConvertSelection(dpy, sel, utf8, property, B, CurrentTime);
// 等待窗口A把数据设置完成
XNextEvent(dpy, &ev);
switch (ev.type)
{// 剪贴板数据已经放到指定的窗口, 可以获取了case SelectionNotify:XGetWindowProperty();
}
数据类型
- 剪贴板的数据类型叫做target, 例如UTF8_STRING, TEXT等
- 有一个特殊的剪贴板类型叫做TARGETS, 通过它可以获取剪贴板数据支持转换成的格式
异常情况
理论上来讲
2个X客户端之间传输剪贴板数据, 只能通过XServer实现
XServer不保存剪贴板数据, 只转发selection事件
数据直接由2个X客户端通过设置窗口属性传递(当然这也要通过XServer中转)
那么就会出现一个问题
如果一个x客户端复制了一个内容, 然后这个x客户端关闭了
这时另一个程序想粘贴数据是不可能的
但是实际测试并不是这样
在Ubuntu上测试时发现, 复制内容的那个程序(窗口A)关闭了,
其他程序(窗口B)还是可以粘贴
难道以上的理论错了
当然不是
只是情况更加复杂了
因为又多了一个Clipboard manager
Clipboard manager的大概工作流程如下
- Clipboard manager获取剪贴板的所有权
- 如果其他程序要复制数据, 会获取剪贴板所有权, 这时Clipboard manager失去所有权, 它会这么做
- 获取当前剪贴板的数据
- 自己提供数据
- 再次获取剪贴板所有权
所以当A关闭后, B粘贴的数据实际上是Clipboard manager提供的
参考资料
X11: How does “the” clipboard work?
Linux中的剪贴板--X11和selection相关推荐
- linux vim 粘贴 没有保持原来的格式,linux中的剪贴板用法,实现vim中原格式粘贴...
不同于Windows,Linux系统里存在两个剪切板:一个叫做选择缓冲区(X11 selection buffer),另一个才是剪切板(clipboard). 选择缓冲区是实时的,当使用鼠标或键盘选择 ...
- macOS 使用 X11 运行远端 linux 中的 x11 client 图形程序
安装 brew install --cask xquartz 配置 打开 xquartz,新建一个终端,然后执行 xhost + 开放权限. linux 中 sshd 配置 /etc/ssh/sshd ...
- linux五文件类型,Linux中常见的文件类型
1>系统文件 文件扩展名 说明 .conf 一种配置文件.配置文件有时也使用 .cfg .lock 锁(lock)文件:用来判定程序或设备是否正在被使用 .rpm Re ...
- linux 找到安装的软件包,如何在 Linux 中列出可用的软件包组
原标题:如何在 Linux 中列出可用的软件包组 编译自: https://www.2daygeek.com/how-to-list-an-available-package-groups-in-li ...
- linux 中如何将文件粘贴到usr下的lib内,学会在Linux下GCC生成和使用静态库和动态库...
一.基本概念1.1什么是库 在windows平台和linux平台下都大量存在着库. 本质上来说库是一种可执行代码的二进制形式,可以被操作系统载入内存执行. 由于windows和linux的平台不同(主 ...
- Linux中的目录和文件管理
Linux中的目录和文件管理 1:Linux的命令分类:内部命令和外部命令 内部命令属于shell解释器的一部分 外部命令是独立于shell解释器之外的程序文件 2:Linux命令的通用格式 命令字 ...
- linux 图形界面 x x11 gnome xorg kde 之间的关系
LINUX初学者经常分不清楚linux和X之间,X和Xfree86之间,X和KDE,GNOME等之间是什么关系.常常混淆概念,本文以比较易于理解的方式来解释X,X11,XFREE,WM,KDE,GNO ...
- Linux中使用gcp拷贝报错:dbus.exceptions.DBusException: org.freedesktop.DBus.Error.NotSupported:
1 在linux中使用gcp拷贝的时候报错 Linux中使用gcp拷贝报错:dbus.exceptions.DBusException: org.freedesktop.DBus.Error.NotS ...
- Linux中关于useradd、chmod、chown、getfacl、setfact等权限设置
Linux中关于useradd.chmod.chown.getfacl.setfact等权限设置 文章目录: 一.Linux用户管理 1.用户(user).用户组(group).其他用户概念(othe ...
最新文章
- python字典练习题
- PowerShell因为在此系统中禁止执行脚本
- python set union_python – set.union()抱怨它在传入生成器时没有参数
- 【H264/AVC 句法和语义详解】(五):Exp-Golomb指数哥伦布编码(理论篇)
- OSS 上传出现异常
- oracle 审计结果表,oracle对某表进行审计,观察对这个表的增删改查等sql操作
- C++11多线程 unique_lock详解
- 济南大学Oj系统c语言,“浪潮杯”第十届山东省大学生ACM程序设计竞赛在济南大学举行...
- 利用python进行正球面的大圆航程与横向线航程计算
- 衰老,其实是一种疾病?
- EMV log 解析
- [ScyllaHide] 02 InjectorCLI源码分析
- wince模拟器上网_wince5.0模拟器下载
- git合并多次提交为一次提交
- C++ 之 for 循环 | C++11 for 循环 | 内存 Destory 示例
- P4043 [AHOI2014/JSOI2014]支线剧情(有源汇上下界最小费用可行流)
- 多个日期时间段进行合并计算时长,剔除重叠时间段
- 每股收益再创新高,增长速度趋于减缓:上市公司半年报业绩波澜不惊
- Android漂浮碰壁动画
- Vijos1234 口袋的天空 题解
热门文章
- 云表MES系统助力小型企业
- 群辉docker阿里云ipv6域名解析
- 对于电影《八佰》,知乎与豆瓣的评价相差巨大?分析下电影评论
- ​手机微信可以批量删除好友了!(文末送书)
- double类型问题(精度丢失和自动拆箱)
- 22届应届生入职华为OD一个半月,治好了我的精神内耗...
- C语言复习笔记——适合一些需要复习和进阶c语言的朋友,这只能说是个概要。当然,如果朋友你看到某个内容能联想到知识点,那你应该是掌握了的,你可以尝试找找其他的文章去深入理解下,如有错误和疑问可以直接指出
- ios 滤镜处理(详细滤镜介绍)及处理方法
- 达观AI+知识图谱技术在数字档案馆建设中的探索
- Python3基础,这篇就够了(总结版)