tmouseshortcuts: fix custom modifier on release - st - [fork] customized build … | |
git clone git://src.adamsgaard.dk/st | |
Log | |
Files | |
Refs | |
README | |
LICENSE | |
--- | |
commit 28ad28839985e965c9ca06a9a202523414c84ac4 | |
parent 51e19ea11dd42eefed1ca136ee3f6be975f618b1 | |
Author: Avi Halachmi (:avih) <[email protected]> | |
Date: Thu, 2 Apr 2020 11:43:22 +0300 | |
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 | |
tto 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. | |
Diffstat: | |
M x.c | 19 +++++++++++++++++-- | |
1 file changed, 17 insertions(+), 2 deletions(-) | |
--- | |
diff --git a/x.c b/x.c | |
t@@ -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 *); | |
t@@ -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; | |
} |