我正在尝试设置一些鼠标按钮和弦,灵感来自 Acme 文本编辑器:http://acme.cat-v.org/mouse
在 Windows 和 Mac 上,我能够分别使用 AutoHotKey 和 Hammerspoon 进行以下设置:
Left+Middle = Cut (Ctrl+x)
Left+Right = Paste (Ctrl+v)
Middle+Left = Return
Middle+Right = Space
Right+Left = Undo (Ctrl+z)
Right+Middle = Redo (Ctrl+Y / Ctrl+Shift+z)
Middle+Scroll = Switch window
我的主计算机从 Windows 迁移到 Linux 后,我尝试在 Linux 上进行相同的设置。我正在使用 X11 和 XFCE 运行 OpenSUSE Tumbleweed。
Left+Middle = Ctrl+x
为简单起见,我将在以下代码示例中仅关注 cut ( )。
使用xev
我发现当鼠标左键按下时,state
变量设置为0x100
。
所以 cut 的一个简单配置是:
"xdotool key ctrl+x"
m:0x100 + b:2
这不起作用,我收到了臭名昭著的冲突程序警告:
*** Warning ***
Please verify that there is not another program running
which captures one of the keys captured by xbindkeys.
It seems that there is a conflict, and xbindkeys can't
grab all the keys defined in its configuration file.
m:0x4 + b:2
确实有效(0x4 是 Ctrl),所以我不确定问题是什么。
有办法让它发挥作用吗?
四处搜索,我发现了一些鼠标和弦的设置,我能够适应我的需要。不过,这些需要 xbindkeys 中的 guile 支持。
.xbindkeysrc.scm
(define actionperformed 0)
(define (first-binding)
"First binding"
(xbindkey-function '("b:1") b1-second-binding) ;; Left Mouse Button
)
(define (reset-first-binding)
"Reset first binding"
(ungrab-all-keys)
(remove-all-keys)
(set! actionperformed 0)
(first-binding)
(grab-all-keys)
)
(define (b1-second-binding)
"Left Mouse Button"
(remove-all-keys)
(ungrab-all-keys)
(run-command "xdotool mousedown 1 &") ;; <--- THIS DOES NOT WORK!
;; Left+Middle
(xbindkey-function '("b:2")
(lambda ()
;; Copy
(run-command "xdotool key ctrl+x&")
(run-command "xdotool mouseup 1&")
(set! actionperformed 1)
)
)
;; Release left
(xbindkey-function '(release "b:1")
(lambda ()
(unless actionperformed (begin
(run-command "xdotool mouseup 1&")))
(reset-first-binding)
)
)
(grab-all-keys)
)
(first-binding)
这确实使 Left+Middle 执行剪切操作。
问题是左键单击被覆盖,因此我无法进行简单的左键单击或文本选择。
我添加了xdotool mousedown 1
修复这个问题,但它不起作用。
xdotool
当同一鼠标事件处于活动状态时,似乎无法触发鼠标事件。
有什么办法可以防止 xbindkeys 覆盖按钮的正常操作吗?
我还有另一个带有按钮 9 的鼠标,使用它我至少可以设置一些东西。
由于所有按钮和弦必须以同一个按钮开始,所以我只能真正获得 3 个和弦(+ 滚动),这只是我想要的一半。
按下按钮也很尴尬,我不能认为这是一个永久的解决方案:
(define (first-binding)
(xbindkey-function '("b:9") second-binding)
)
(define (second-binding)
(remove-all-keys)
(ungrab-all-keys)
(xbindkey-function '("b:2") (lambda () (run-command "xdotool key ctrl+x")))
(xbindkey-function '(Release "b:9") reset-first-binding)
)
(define (reset-first-binding)
(ungrab-all-keys)
(remove-all-keys)
(first-binding)
(grab-all-keys)
)
(first-binding)
关于解决这个问题的方法有什么想法吗?
我终于解决了它,但解决方法有点复杂(无论如何与Windows和Mac版本相比)。
这个想法是用来
xinput
重新映射 USB 鼠标的鼠标按钮,导致按钮不起作用,但保留鼠标移动。然后监听鼠标按钮事件并
evtest
触发检测到的按钮组合的鼠标和弦命令,或者在未检测到组合时触发正常的按钮事件。xinput
并evtest
evtest
并记下你的 USB 鼠标(类似/dev/input/event3
)xinput -list
并记下设备 IDxinput set-button-map {id} 0 0 0 0 0 0 0 0 0 0
(10 个零)evtest /dev/input/event3 | ./mouse-chording.pl
内容
mouse-chording.pl
:该解决方案与 github 上的 Windows 和 Mac 版本一起维护: https: //github.com/levigutt/mouse-chording/
欢迎 PR!:)