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
。
したがって、カットの簡単な構成は次のとおりです。
"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でチートサポートが必要です。
.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)
この問題を解決する方法についてのアイデアはありますか?
答え1
ついに解決しましたが、回避策は少し複雑です(とにかくWindowsとMacのバージョンと比較して)。
アイデアは、xinput
USBマウスのマウスボタンを再マップしてボタンを無効にしますが、マウスの動きは維持することです。
その後、マウスボタンイベントを受け取り、evtest
検出されたボタンの組み合わせに対してマウスコードコマンドをトリガーするか、組み合わせが検出されない場合は通常のボタンイベントをトリガーします。
- 設置
xinput
とevtest
evtest
USBマウスを起動して記録してみてください(類似/dev/input/event3
)- 実行し
xinput -list
てデバイスIDを書き留めます。 - 実行
xinput set-button-map {id} 0 0 0 0 0 0 0 0 0 0
(0 10個) - 走る
evtest /dev/input/event3 | ./mouse-chording.pl
コンテンツmouse-chording.pl
:
#!/usr/bin/perl -wlnF/\s|,/
BEGIN
{
our %btns = (272 => 0, 273 => 0, 274 => 0);
our $active_chord = 0;
# mouse button codes
our $left_code = 272;
our $right_code = 273;
our $middle_code = 274;
our $scroll_code = 8;
}
# only handle events
next unless 0 == index $_, 'Event';
next unless -1 == index $_, 'SYN';
# extract event values
my ($time, $type, $code, $value) = @F[2, 5, 9, 13];
# skip mouse movements and hi-res scroll
next if $code == 11;
next if $type == 2 && $code != 8;
# keep track of pressed buttons
$btns{$code} = $value;
# emulate button presses
if ( ($code == $left_code && !($btns{$right_code} || $btns{$middle_code}))
|| ($code == $right_code && !($btns{$left_code} || $btns{$middle_code}))
|| ($code == $middle_code && !($btns{$left_code} || $btns{$right_code})) )
{
if ($code == $left_code)
{
# left button can be held for selecting text
system $value ? "xdotool mousedown 1&" : "xdotool mouseup 1&";
}
elsif($value == 0 && not $active_chord)
{
# middle and right will only trigger click - cannot be held
system "xdotool click " . ($code == $middle_code ? 2 : 3) . "&";
}
$active_chord = 0;
next;
}
# emulate scroll wheel
elsif ($code == 8)
{
system( sprintf("xdotool click %d&", $value > 0 ? 4 : 5) );
}
# only do chords when button is pressed (not released)
next unless $value;
# Left + Middle = Cut
if ($btns{$left_code} && $code == $middle_code)
{
system "xdotool mouseup 1&"; # prevent accidental selection after snarf
system "xdotool key ctrl+c key ctrl+x&";
$active_chord = 1;
next;
}
# Left + Right = Paste
if ($btns{$left_code} && $code == $right_code)
{
system "xdotool key ctrl+v&";
$active_chord = 1;
next;
}
END
{
# release buttons to prevent getting stuck when closing
system "xdotool mouseup $_&" for (1..3);
}
このソリューションは、githubのWindowsとMacのバージョンで維持されています。https://github.com/levigutt/mouse-chording/
PRを歓迎します! :)