Sample Header Ad - 728x90

prevent xbindkeys from overriding mouse click when used for mouse button chording

1 vote
1 answer
391 views
I am trying to set up some mouse button chording, inspired by the Acme text editor: http://acme.cat-v.org/mouse On Windows and Mac, I was able to set up the following using AutoHotKey and Hammerspoon respectively:
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
Having moved from Windows to Linux for my main computer, I'm trying to set up the same on Linux. I am running OpenSUSE Tumbleweed with X11 and XFCE. For simplicity, I'll focus only on cut (Left+Middle = Ctrl+x) for the following code examples. --- Using xev I've found that while the left mouse button is down, the state variable is set to 0x100. So a simple configuration for cut would be:
"xdotool key ctrl+x"
    m:0x100 + b:2
This does not work, and I get the infamous warning of conflicting program:
*** 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 does work (0x4 being Ctrl), so I'm not sure what the problem is. **Is there a way to get this to work?** --- Searching around I've found some setups for mouse chording, which I was able to adapt to my needs. These requires guile-support in xbindkeys though. .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)
This does make Left+Middle perform a cut operation. The problem is that the Left click is overridden, and I can therefore not make a simple left click or a text selection. I added xdotool mousedown 1 to fix this, but it doesn't work. xdotool seems to not be able to trigger a mouse-event while the same mouse event is active. **Is there any way to prevent xbindkeys from overriding the normal action of buttons?** --- I have another mouse with a button 9, using this I can at least set up something. Since all the button chords must start with the same button I can only really get 3 chords (+ scrolling), which is half of what I want. Pressing the buttons is also very awkward, and I can't consider this a permanent solution:
(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)
**Any ideas on ways to solve this?**
Asked by Levi (61 rep)
Jul 18, 2023, 01:40 PM
Last activity: Aug 10, 2023, 09:38 PM