aboutsummaryrefslogtreecommitdiff
path: root/x.c
diff options
context:
space:
mode:
authorAvi Halachmi (:avih) <avihpit@yahoo.com>2020-04-02 11:43:22 +0300
committerHiltjo Posthuma <hiltjo@codemadness.org>2020-04-02 14:41:03 +0200
commit28ad28839985e965c9ca06a9a202523414c84ac4 (patch)
treeb5e83f2b48c180743f34296251fbe1a863575382 /x.c
parent51e19ea11dd42eefed1ca136ee3f6be975f618b1 (diff)
downloadst-patched-28ad28839985e965c9ca06a9a202523414c84ac4.tar.bz2
st-patched-28ad28839985e965c9ca06a9a202523414c84ac4.tar.xz
st-patched-28ad28839985e965c9ca06a9a202523414c84ac4.zip
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.
Diffstat (limited to 'x.c')
-rw-r--r--x.c19
1 files changed, 17 insertions, 2 deletions
diff --git a/x.c b/x.c
index 48a6676..4cf6b21 100644
--- a/x.c
+++ b/x.c
@@ -171,6 +171,7 @@ static void kpress(XEvent *);
171static void cmessage(XEvent *); 171static void cmessage(XEvent *);
172static void resize(XEvent *); 172static void resize(XEvent *);
173static void focus(XEvent *); 173static void focus(XEvent *);
174static uint buttonmask(uint);
174static int mouseaction(XEvent *, uint); 175static int mouseaction(XEvent *, uint);
175static void brelease(XEvent *); 176static void brelease(XEvent *);
176static void bpress(XEvent *); 177static void bpress(XEvent *);
@@ -423,16 +424,30 @@ mousereport(XEvent *e)
423 ttywrite(buf, len, 0); 424 ttywrite(buf, len, 0);
424} 425}
425 426
427uint
428buttonmask(uint button)
429{
430 return button == Button1 ? Button1Mask
431 : button == Button2 ? Button2Mask
432 : button == Button3 ? Button3Mask
433 : button == Button4 ? Button4Mask
434 : button == Button5 ? Button5Mask
435 : 0;
436}
437
426int 438int
427mouseaction(XEvent *e, uint release) 439mouseaction(XEvent *e, uint release)
428{ 440{
429 MouseShortcut *ms; 441 MouseShortcut *ms;
430 442
443 /* ignore Button<N>mask for Button<N> - it's set on release */
444 uint state = e->xbutton.state & ~buttonmask(e->xbutton.button);
445
431 for (ms = mshortcuts; ms < mshortcuts + LEN(mshortcuts); ms++) { 446 for (ms = mshortcuts; ms < mshortcuts + LEN(mshortcuts); ms++) {
432 if (ms->release == release && 447 if (ms->release == release &&
433 ms->button == e->xbutton.button && 448 ms->button == e->xbutton.button &&
434 (match(ms->mod, e->xbutton.state) || /* exact or forced */ 449 (match(ms->mod, state) || /* exact or forced */
435 match(ms->mod, e->xbutton.state & ~forcemousemod))) { 450 match(ms->mod, state & ~forcemousemod))) {
436 ms->func(&(ms->arg)); 451 ms->func(&(ms->arg));
437 return 1; 452 return 1;
438 } 453 }