[hackers] [st] mouseshortcuts: fix custom modifier on release || Avi Halachmi (:avih)

From: <git_AT_suckless.org>
Date: Thu, 2 Apr 2020 14:41:48 +0200 (CEST)

commit 28ad28839985e965c9ca06a9a202523414c84ac4
Author: Avi Halachmi (:avih) <avihpit_AT_yahoo.com>
AuthorDate: Thu Apr 2 11:43:22 2020 +0300
Commit: Hiltjo Posthuma <hiltjo_AT_codemadness.org>
CommitDate: Thu Apr 2 14:41:03 2020 +0200

    mouseshortcuts: fix custom modifier on release
    
    This line didn't work at mshortcuts at config.h:
    
      /* mask button function arg release */
        { ShiftMask, Button2, selpaste, {.i = 0}, 1 },
    
    and now it does work.
    
    The issue was that XButtonEvent.state is "the logical state ... just prior
    to the event", which means that on release the state has the Button2Mask
    bit set because button2 was down just before it was released.
    
    The issue didn't manifest with the default shift + middle-click on release
    (to override mouse mode) because its specified modifier is XK_ANY_MOD, at
    which case match(...) ignores any specific bits and simply returns true.
    
    The issue also doesn't manifest on press, because prior to the event
    Button<N> was not down and its mask bit is not set.
    
    Fix by filtering out the mask of the button which we're currently matching.
    
    We could have said "well, that's how button events behave, you should
    use ShiftMask|Button2Mask for release", but this both not obvious to
    figure out, and specifically here always filtering does not prevent
    configuring any useful modifiers combination. So it's a win-win.

diff --git a/x.c b/x.c
index 48a6676..4cf6b21 100644
--- a/x.c
+++ b/x.c
_AT_@ -171,6 +171,7 @@ static void kpress(XEvent *);
 static void cmessage(XEvent *);
 static void resize(XEvent *);
 static void focus(XEvent *);
+static uint buttonmask(uint);
 static int mouseaction(XEvent *, uint);
 static void brelease(XEvent *);
 static void bpress(XEvent *);
_AT_@ -423,16 +424,30 @@ mousereport(XEvent *e)
         ttywrite(buf, len, 0);
 }
 
+uint
+buttonmask(uint button)
+{
+ return button == Button1 ? Button1Mask
+ : button == Button2 ? Button2Mask
+ : button == Button3 ? Button3Mask
+ : button == Button4 ? Button4Mask
+ : button == Button5 ? Button5Mask
+ : 0;
+}
+
 int
 mouseaction(XEvent *e, uint release)
 {
         MouseShortcut *ms;
 
+ /* ignore Button<N>mask for Button<N> - it's set on release */
+ uint state = e->xbutton.state & ~buttonmask(e->xbutton.button);
+
         for (ms = mshortcuts; ms < mshortcuts + LEN(mshortcuts); ms++) {
                 if (ms->release == release &&
                     ms->button == e->xbutton.button &&
- (match(ms->mod, e->xbutton.state) || /* exact or forced */
- match(ms->mod, e->xbutton.state & ~forcemousemod))) {
+ (match(ms->mod, state) || /* exact or forced */
+ match(ms->mod, state & ~forcemousemod))) {
                         ms->func(&(ms->arg));
                         return 1;
                 }
Received on Thu Apr 02 2020 - 14:41:48 CEST

This archive was generated by hypermail 2.3.0 : Thu Apr 02 2020 - 14:48:37 CEST