xsel이나 xclip을 통하지 않고 특정 X 버퍼를 직접 지웁니다.

xsel이나 xclip을 통하지 않고 특정 X 버퍼를 직접 지웁니다.

다음을 사용하여 버퍼에서 붙여넣기 위해 가운데 클릭을 완전히 비활성화하려고 합니다.라바리그의 솔루션.

그것을 넣어~/.xbindkeysrc

"echo -n | xsel -n -i; pkill xbindkeys; xdotool click 2; xbindkeys"
b:2 + Release

그러나 이 솔루션은 작업을 신속하게 수행하는 데 의존합니다 xsel(또는 이와 동일함 ).xclip

xsel최근에 메인 버퍼를 지우려고 할 때 몇 초의 지연이 발생하는 것을 발견했습니다 .xclip

xselxclipX가 특정 버퍼를 비우도록 강제하는 덜 "정중한" 방법이 있습니까?

xsel문제의 Linux 배포판은 Manjaro입니다... 이것은 Manjaro 또는 Arch 특정 버그일 수 있지만 다른 유사한 도구 없이 X11 서버와 상호 작용하는 방법에 대한 최종 사용자 대면 정보가 약간 부족한 것 같습니다 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있으며 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.

새 소유자(클라이언트 또는 없음)가 선택 항목의 현재 소유자와 다르고 현재 소유자가 없음이 아닌 경우 SelectionClear 이벤트가 현재 소유자에게 전송됩니다. 선택 항목의 소유자인 클라이언트가 나중에 종료되거나(예: 연결이 닫히는 경우) 요청에 지정된 소유자 창이 이후에 삭제되는 경우 선택 항목의 소유자는 자동으로 없음으로 되돌아갑니다. A - 변경 시간은 영향을 받지 않습니다. 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이전과 이후의 동일한 콘텐츠를 표시합니다.

답변1

  XSetSelectionOwner(display, XA_PRIMARY, None, CurrentTime);

이것은 작동하지 않습니다. 첫 번째 줄은 다음과 같이 DESCRIPTION말합니다 XSetSelectionOwner(3).

XSetSelectionOwner 함수는 지정된 선택 항목의 소유자와 마지막 변경 시간을 변경하며지정된 시간이 지정된 선택 항목의 현재 마지막 변경 시간보다 이전인 경우 아무런 효과가 없습니다.또는 현재 X 서버 시간보다 이후입니다.

XEvent서버에서 수신한 타임스탬프에서 얻을 수 있는 실제 타임스탬프를 전달해야 합니다 . 이것이 제가 직접 구현한 작업입니다 xsel.

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트릭을 시도하거나 문제를 일으키는 프로그램을 수정하는 것이 더 나을 것입니다 .

관련 정보