Xorg에 KeyHold 이벤트가 있습니까?

Xorg에 KeyHold 이벤트가 있습니까?

나는 새로운 Macbook Pro를 가지고 있고 거기에 Arch Linux를 설치했습니다. 내가 하고 싶은 한 가지는 미디어 키를 사용하여 mpd에서 트랙을 검색하고 다음 또는 이전 트랙으로 이동하는 것입니다. 이것은 iTunes가 있는 OSX에서 가능하므로 불가능한 일은 아니라고 생각합니다. xev키 누르기 및 키 놓기 이벤트만 표시 하려면 사용합니다 . 열쇠를 쥐고 있으면 두 이벤트가 빠르게 순환되는 것 같습니다.

그래서 제가 하고 싶은 일은 다음과 같습니다.

  • XF86AudioNext 키를 누르면 다음 mpd 트랙으로 이동합니다.
  • XF86AudioNext 키를 누른 상태에서 현재 mpd 트랙 찾기

물론 XF86AudioPrev 키도 마찬가지입니다(그러나 반대 방향).

이것은 일부 고급 스크립팅을 통해서만 달성할 수 있는 것 같습니다. 여러분 중 한 분이 저에게 올바른 방향을 알려 주실 수 있기를 바랍니다.

편집: 흥미롭게도 showkey키를 누르고 있어도 누르기와 놓기가 순환되지 않습니다. 대신, 키를 누르고 있는 동안 발생하는 일련의 누르기 이벤트와 키를 마지막으로 놓을 때의 최종 릴리스 이벤트만 표시합니다.

xset방금 알아낸 또 다른 흥미로운 점은 then을 사용하여 자동 반복을 비활성화하면 xev키를 얼마나 오랫동안 누르고 있어도 단일 키 누르기 이벤트만 표시되고 키를 놓을 때 단일 키 놓기 이벤트가 표시된다는 것입니다. 반면에 출력은 showkey변경되지 않습니다. 일련의 주요 이벤트와 출시 시 최종 키 릴리스를 보여줍니다.

아마도 이것을 사용하여 내가 하고 싶은 일을 스크립트로 작성하는 방법이 있을 것입니다. 그러나 sxhkd제가 사용하고 있는 단축키 도구는 이 xev접근 방식을 따르는 것 같습니다. 마찬가지이다 Xbindkeys.

답변1

아니요, KeyHold 이벤트는 없으며 KeyPress 및 KeyRelease만 있습니다. KeyPress는 키를 누를 때 전송되고 일정 시간이 지나면 다시 전송됩니다. 시간은 다음과 같이 구성할 수 있습니다.xset r(첫 번째 반복 시간과 후속 반복 시간의 두 가지 시간이 있습니다.) KeyRelease 이벤트는 키를 실제로 놓을 때 전송됩니다(키를 누르고 있는 동안에는 전송되지 않습니다).

응용 프로그램이 누른 키에 반응하려는 경우 초기 키 누름을 기록한 다음 설정된 시간 후 또는 새 KeyPress 이벤트 후에 반응해야 합니다(그 동안 KeyRelease를 수신하지 않는다고 가정). Unix GUI 세계에서는 누른 키에 반응하는 것이 매우 드물기 때문에 이를 수행하지 않는 응용 프로그램의 자체 영속 루프가 존재하며 프로그래밍 프레임워크도 이를 수행하는 쉬운 방법을 제공하지 않습니다.

XKB를 사용하면 특정 키 입력을 반복 불가능하도록 구성할 수 있습니다. 이러한 키 입력은 초기 KeyPress 및 최종 KeyRelease만 생성합니다. 구성에서 이 작업이 어디서 수행되는지 모르겠습니다. 이러한 키의 경우 KeyPress+timeout 정책만 유효하고 두 번째 KeyPress 정책은 유효하지 않습니다.

xbindkeys나 sxhkd 모두 이것을 쉽게 만들지 못합니다. 키 릴리스 이벤트에 대한 바인딩 작업을 허용하지만 키 누름과 키 릴리스의 상관 관계를 쉽게 연관시키지 못하므로 "키를 누른 후 X 밀리초 후에 이 작업을 수행하지만 키를 누른 경우에만 아직 릴리스되지 않았습니다"라는 논리를 프로그래밍하기가 어렵습니다. + "키를 놓을 때 이 작업을 수행하십시오. 단, 보류 이벤트가 아직 트리거되지 않은 경우에만"입니다. 나는 이것을 쉽게 만들어주는 다른 유사한 프레임워크를 모릅니다.

답변2

X11에는 간단한 해결책이 없지만 "keyhold" 이벤트를 사용하여 커널에서 장치 출력을 읽는 것이 가능합니다. *kernel.org의 추가 정보*

이것은 /dev/input/event#에 대한 샘플 출력입니다(#은 장치에 따라 다름).

Event: time 1677080541.072921, type 4 (EV_MSC), code 4 (MSC_SCAN), value 9d
Event: time 1677080541.072921, type 1 (EV_KEY), code 97 (KEY_RIGHTCTRL), value 1
Event: time 1677080541.072921, -------------- SYN_REPORT ------------
Event: time 1677080541.319094, type 4 (EV_MSC), code 4 (MSC_SCAN), value 9d
Event: time 1677080541.319094, type 1 (EV_KEY), code 97 (KEY_RIGHTCTRL), value 2
Event: time 1677080541.319094, -------------- SYN_REPORT ------------
Event: time 1677080541.348759, type 4 (EV_MSC), code 4 (MSC_SCAN), value 9d
Event: time 1677080541.348759, type 1 (EV_KEY), code 97 (KEY_RIGHTCTRL), value 2
Event: time 1677080541.348759, -------------- SYN_REPORT ------------
Event: time 1677080541.379604, type 4 (EV_MSC), code 4 (MSC_SCAN), value 9d
Event: time 1677080541.379604, type 1 (EV_KEY), code 97 (KEY_RIGHTCTRL), value 0

출력은 1(키 누름), 2(키 유지), 0(키 놓음)으로 진행됩니다.

/dev/input/event#의 출력을 모니터링함으로써 제가 만든 간단한 스크립트로 명령을 실행하여 검색 및 다음 동작을 시뮬레이션할 수 있습니다("playerctl position 5+" 및 "playerctl next" 사용). 여기있어깃허브 브랜치.

관련 정보