首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >直接清除特定的X缓冲区,而无需通过xsel或xclip

直接清除特定的X缓冲区,而无需通过xsel或xclip
EN

Unix & Linux用户
提问于 2018-10-16 21:46:16
回答 1查看 524关注 0票数 3

我试图完全禁用使用拉达维氏溶液从缓冲区中粘贴的中间单击。

将其放置在~/.xbindkeysrc中"echo -n \ xsel -n -i;pkill xbindkey;xdotool单击2;xbindkey“b:2 +发布中。

然而,这个解决方案依赖于xsel (或相当于xclip)快速完成它的工作。

最近,我注意到xselxclip在试图清除主缓冲区时延迟了几秒钟。

有没有比xselxclip强制X清空特定缓冲区的任何“礼貌”方式?

Linux的发行版是Manjaro ..。这可能是一个Manjaro或Arch特有的错误,但关于如何在没有xselxclip或其他类似工具的情况下与D10服务器进行交互的面向最终用户的信息似乎有点缺乏。

代码语言:javascript
复制
~  > xclip -selection primary -verbose -in  xclip -selection primary -verbose -in  xclip -selection primary -verbose -in 

我将gdb附加到一个挂起的xclips上,它似乎被困在等待X服务器的响应。

代码语言:javascript
复制
(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 ?? ()

我试图直接使用X编写一个精简的程序,它基于xsel源代码的一部分,特别是:https://github.com/kfish/xsel/blob/master/xsel.c#L1003-L1018

为了清除缓冲区,xsel似乎依赖于XSetSelectionOwner的以下属性:

如果新所有者(无论是客户端还是无)与选择的当前所有者不相同,且当前所有者不是None,则向当前所有者发送SelectionClear事件。如果选择的所有者客户端后来终止(即连接关闭),或者如果请求中指定的所有者窗口后来被销毁,则选择的所有者将自动恢复为无,但最后的更改时间不会受到影响。选择原子未被X服务器解释。XGetSelectionOwner()返回所有者窗口,这是在SelectionRequest和SelectionClear事件中报告的。选择对于X服务器是全局的。

下面是我试图将xsel简化为我所需要的功能的尝试。

我假设XA_PRIMARY缓冲区的所有者通常不是None。我正在将它设置为C程序正文中的None,然后希望它能工作。

代码语言:javascript
复制
// clear.c
#include 
#include 
#include 
#include 

// 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;
}

这个程序运行并打印。

代码语言:javascript
复制
100
300
400
500
200

如预期的那样。

但是,它未能清除主缓冲区。

xclip -selection -primary out在前后显示了相同的内容。

EN

回答 1

Unix & Linux用户

回答已采纳

发布于 2018-10-16 22:32:54

XSetSelectionOwner(显示,XA_PRIMARY,None,CurrentTime);

这不管用。正如DESCRIPTION of XSetSelectionOwner(3)的第一行所说:

XSetSelectionOwner函数更改指定选择的所有者和最后更改时间,如果指定的时间早于指定选择的当前最后更改时间或比当前X服务器时间晚,则具有<#>no效果。

您必须传递一个真正的时间戳,您可以从从服务器接收到的XEvent中获得这个时间戳。这就是我在自己的xsel实现中所做的工作:

代码语言:javascript
复制
Time getctime(void){
        XSelectInput(dpy, w, PropertyChangeMask);
        XStoreName(dpy, w, "xsel");
        for(;;){
                XEvent e;
                XNextEvent(dpy, &e);
                if(e.type == PropertyNotify && e.xproperty.window == w)
                        return e.xproperty.time;
        }
}

我在窗口上设置了一个属性,等待PropertyNotify事件,然后从XPropertyEvent结构中获得时间戳。这个窗口可以是一个InputOnly窗口。这在xlib编程手册或一些X11手册中也有描述。

不幸的是,这也意味着你的小程序也不够快,因为它必须等待那个事件;-)

我不认为链接问题的答案是令人满意的。您最好探索使用一些LD_PRELOAD黑客,或者修改那些给您带来麻烦的程序。

票数 2
EN
页面原文内容由Unix & Linux提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://unix.stackexchange.com/questions/475906

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档