commit 9cd20ae3a19a6e1b3e010c6156a564f55f3f27ad
parent a4ebfc9c59465a6ffa986751b6105e3e02de6389
Author: Miles Alan <m@milesalan.com>
Date: Sat, 18 Apr 2020 18:56:23 -0500
Multikey fixes
Diffstat:
| M | dwm.c | | | 97 | +++++++++++++++++++++++++++++++++---------------------------------------------- |
1 file changed, 41 insertions(+), 56 deletions(-)
diff --git a/dwm.c b/dwm.c
@@ -296,9 +296,9 @@ static Window root, wmcheckwin;
#define KEYPRESS_MS_THRESHOLD 200
#define KEYHOLD_MS_THRESHOLD 700
-static KeySym lastkeysym = NULL;
-static unsigned int lastkeypresses = 0;
-static unsigned int lastkeyreleased = 0;
+static int multikeypendingindex = -1;
+timer_t multikeypendingtimer;
+static int multikeyup = 1;
static xcb_connection_t *xcon;
@@ -1105,37 +1105,20 @@ isuniquegeom(XineramaScreenInfo *unique, size_t n, XineramaScreenInfo *info)
#endif /* XINERAMA */
-void keypresstimerdonesync(int keyindex) {
- int i;
- Key * maxkeypresskey = NULL;
-
- if (
- keyindex < 0 &&
- keys[-1 * keyindex].keysym == lastkeysym &&
- keys[-1 * keyindex].npresses == lastkeypresses
- ) {
- // Key hold - find keybinding w/ max npresses and run that fn
- for (i = 0; i < LENGTH(keys); i++) {
- if (
- keys[-1 * keyindex].keysym == keys[i].keysym &&
- (maxkeypresskey == NULL || keys[i].npresses > maxkeypresskey->npresses)
- ) {
- maxkeypresskey = &keys[i];
- }
- }
- lastkeysym = NULL;
- if (maxkeypresskey && maxkeypresskey->func) maxkeypresskey->func(&(maxkeypresskey->arg));
- } else if (
- // Key press
- keys[keyindex].keysym == lastkeysym &&
- keys[keyindex].npresses == lastkeypresses
- ) {
- if (lastkeyreleased) {
- lastkeysym = NULL;
- if (keys[keyindex].func) keys[keyindex].func(&(keys[keyindex].arg));
- } else {
- keypresstimerdispatch(KEYHOLD_MS_THRESHOLD - KEYPRESS_MS_THRESHOLD, -1 * keyindex);
- }
+void keypresstimerdonesync(int idx) {
+ int i, maxidx;
+
+ if (keys[idx].npresses == 1 && !multikeyup) {
+ // Dispatch hold key
+ maxidx = -1;
+ for (i = 0; i < LENGTH(keys); i++)
+ if (keys[i].keysym == keys[idx].keysym) maxidx = i;
+ if (maxidx != -1)
+ keypresstimerdispatch(KEYHOLD_MS_THRESHOLD - KEYPRESS_MS_THRESHOLD, maxidx);
+ } else if (keys[idx].func) {
+ // Run the actual keys' fn
+ keys[idx].func(&(keys[idx].arg));
+ multikeypendingindex = -1;
}
}
@@ -1155,57 +1138,58 @@ void keypresstimerdone(union sigval timer_data)
void keypresstimerdispatch(int msduration, int data)
{
struct sigevent timer_signal_event;
- timer_t timer;
struct itimerspec timer_period;
+ // Clear out the old timer if any set,and dispatch new timer
+ timer_delete(multikeypendingtimer);
timer_signal_event.sigev_notify = SIGEV_THREAD;
timer_signal_event.sigev_notify_function = keypresstimerdone;
timer_signal_event.sigev_value.sival_int = data;
timer_signal_event.sigev_notify_attributes = NULL;
- timer_create(CLOCK_MONOTONIC, &timer_signal_event, &timer);
+ timer_create(CLOCK_MONOTONIC, &timer_signal_event, &multikeypendingtimer);
timer_period.it_value.tv_sec = 0;
timer_period.it_value.tv_nsec = msduration * 1000000;
timer_period.it_interval.tv_sec = 0;
timer_period.it_interval.tv_nsec = 0;
- timer_settime(timer, 0, &timer_period, NULL);
+ timer_settime(multikeypendingtimer, 0, &timer_period, NULL);
}
void
keypress(XEvent *e)
{
- unsigned int i;
+ unsigned int i, j;
KeySym keysym;
XKeyEvent *ev;
ev = &e->xkey;
keysym = XKeycodeToKeysym(dpy, (KeyCode)ev->keycode, 0);
- for (i = 0; i < LENGTH(keys); i++)
+ for (i = 0; i < LENGTH(keys); i++) {
if (keysym == keys[i].keysym
&& CLEANMASK(keys[i].mod) == CLEANMASK(ev->state)
&& keys[i].func) {
- // E.g. normal functionality case - npresses 0
- if (keys[i].npresses == 0) { keys[i].func(&(keys[i].arg)); continue; }
-
- if (lastkeysym != keys[i].keysym) {
- lastkeysym = keys[i].keysym;
- lastkeypresses = 0;
+ // E.g. Normal functionality case - npresses 0
+ if (keys[i].npresses == 0) {
+ keys[i].func(&(keys[i].arg));
+ break;
}
- if (lastkeypresses + 1 == keys[i].npresses) {
- lastkeypresses++;
- lastkeyreleased = 0;
- keypresstimerdispatch(KEYPRESS_MS_THRESHOLD, i);
- break;
- }
+
+ // Multikey functionality - find index of key, set global, & dispatch
+ if (
+ (multikeypendingindex == -1 && multikeyup && keys[i].npresses == 1) ||
+ (multikeypendingindex != -1 && keys[multikeypendingindex].npresses + 1 == keys[i].npresses)
+ ) {
+ multikeyup = 0;
+ multikeypendingindex = i;
+ keypresstimerdispatch(KEYPRESS_MS_THRESHOLD, i);
+ break;
+ }
}
+ }
}
void
keyrelease(XEvent *e)
{
- KeySym keysym;
- XKeyEvent *ev;
- ev = &e->xkey;
- keysym = XKeycodeToKeysym(dpy, (KeyCode)ev->keycode, 0);
- if (lastkeysym == keysym) { lastkeyreleased = 1; }
+ multikeyup = 1;
}
void
@@ -2527,6 +2511,7 @@ main(int argc, char *argv[])
fputs("warning: no locale support\n", stderr);
if (!(dpy = XOpenDisplay(NULL)))
die("dwm: cannot open display");
+ XkbSetDetectableAutoRepeat(dpy, True, NULL);
if (!(xcon = XGetXCBConnection(dpy)))
die("dwm: cannot get xcb connection\n");
checkotherwm();