我正在尝试使用Radivarig 的解决方案完全禁用从缓冲区粘贴的中键。
把这个放在
~/.xbindkeysrc
"echo -n | xsel -n -i; pkill xbindkeys; xdotool click 2; xbindkeys" b:2 + Release
但是,此解决方案取决于xsel
(或等效xclip
地)快速完成其工作。
最近我注意到尝试清除主缓冲区时xsel
延迟了几秒钟。xclip
是否有比强制 X 清空特定缓冲区的任何方式xsel
或正在采取的方式更不“礼貌”的方式?xclip
有问题的 Linux 发行版是 Manjaro ......这可能是 Manjaro 或 Arch 特定的错误,但关于如何在没有或其他类似工具的情况下与 X11 服务器交互的面向最终用户的信息xsel
似乎xclip
有些缺乏。
~ > xclip -selection primary -verbose -in </dev/null
Connected to X server.
Using selection: XA_PRIMARY
Using UTF8_STRING.
Waiting for selection requests, Control-C to quit
Waiting for selection request number 1
Waiting for selection request number 2
Time: 13s
~ > xclip -selection primary -verbose -in </dev/null
...
Time: 11s
~ > xclip -selection primary -verbose -in </dev/null
...
Time: 23s
我连接gdb
到一个挂起xclip
的 s 上,它似乎一直在等待来自 X 服务器的响应。
(gdb) where
#0 0x00007f905e1f1b78 in poll () from /usr/lib/libc.so.6
#1 0x00007f905dc68630 in ?? () from /usr/lib/libxcb.so.1
#2 0x00007f905dc6a2db in xcb_wait_for_event () from /usr/lib/libxcb.so.1
#3 0x00007f905e306009 in _XReadEvents () from /usr/lib/libX11.so.6
#4 0x00007f905e2f4ee1 in XNextEvent () from /usr/lib/libX11.so.6
#5 0x0000563eb8eaea70 in ?? ()
#6 0x00007f905e125223 in __libc_start_main () from /usr/lib/libc.so.6
#7 0x0000563eb8eaf53e in ?? ()
我尝试根据部分xsel
源代码直接使用 X API 编写精简程序,特别是:https ://github.com/kfish/xsel/blob/master/xsel.c#L1003-L1018 。
为了清除缓冲区,xsel 似乎依赖于以下属性XSetSelectionOwner
:
如果新所有者(无论是客户端还是 None )与选择的当前所有者不同并且当前所有者不是 None ,则向当前所有者发送 SelectionClear 事件。如果作为选择所有者的客户端稍后终止(即其连接关闭),或者如果它在请求中指定的所有者窗口后来被销毁,则选择的所有者自动恢复为 None ,但最后一个-更改时间不受影响。X 服务器不解释选择原子。XGetSelectionOwner() 返回所有者窗口,在 SelectionRequest 和 SelectionClear 事件中报告。选择对于 X 服务器来说是全局的。
这是我尝试精简xsel
到我需要的功能。
我假设XA_PRIMARY
缓冲区的所有者通常不是None
. 我将它设置None
在我的 C 程序的主体内,然后希望它能够工作。
// clear.c
#include <stdio.h>
#include <X11/Xlib.h>
#include <X11/Xatom.h>
#include <assert.h>
// always debug
#undef NDEBUG
static Display * display = NULL;
static char * display_name = NULL;
static void clear_selection(void)
{
printf("%d\n", 300);
display = XOpenDisplay(display_name);
assert(display != NULL);
printf("%d\n", 200);
XSetSelectionOwner(display, XA_PRIMARY, None, CurrentTime);
printf("%d\n, 500);
XSync(display, False);
return;
}
int main(void)
{
printf("%d\n", 100);
clear_selection();
printf("%d\n", 200);
return 0;
}
该程序运行并打印
100
300
400
500
200
正如预期的那样。
但是,它未能清除主缓冲区。
xclip -selection -primary out
前后显示相同的东西。
这行不通。
DESCRIPTION
正如of中的第一行XSetSelectionOwner(3)
所说:您必须向它传递一个真正的时间戳,您可以
XEvent
从服务器接收到的时间戳中获取该时间戳。这是我在自己的实现中所做的xsel
:我在窗口上设置了一个属性,等待
PropertyNotify
事件,然后从XPropertyEvent
结构中获取时间戳。窗口可以是InputOnly
一个。xlib 编程手册或某些 X11 联机帮助页中也对此进行了描述。不幸的是,这也意味着你的小程序也不够快,因为它必须等待那个事件;-)
我认为链接问题的答案并不令人满意。您最好探索使用一些
LD_PRELOAD
技巧,或修改给您带来麻烦的程序。