Applies the multikey patch
This allows me to have the same key do different things based on the number of times it is pushed. This is going to be useful on the pinephone so I can have double click or click and hold on the limited number of physical buttons
This commit is contained in:
parent
449d90b2e3
commit
c0a50b817c
3 changed files with 171 additions and 69 deletions
134
config.def.h
134
config.def.h
|
@ -37,7 +37,7 @@ static const Rule rules[] = {
|
||||||
{ "xterm-256color", NULL, NULL, 0, 0, 1, 1, 0, 0, -1 },
|
{ "xterm-256color", NULL, NULL, 0, 0, 1, 1, 0, 0, -1 },
|
||||||
{ "Thunderbird", NULL, NULL, 1 << 8 , 0, 0, 0, 0, 0, -1 },
|
{ "Thunderbird", NULL, NULL, 1 << 8 , 0, 0, 0, 0, 0, -1 },
|
||||||
{ NULL, NULL, "noswallow", 0, 0, 0, 1, 0, 0, -1 },
|
{ NULL, NULL, "noswallow", 0, 0, 0, 1, 0, 0, -1 },
|
||||||
{ "svkbd", NULL, NULL, 0, 1, 0, 1, 0, 1, -1 },
|
{ "svkbd", NULL, NULL, 0, 1, 0, 1, 0, 1, -1 },
|
||||||
{ "Onboard-settings", NULL, NULL, 0, 0, 0, 0, 0, 0, -1 }
|
{ "Onboard-settings", NULL, NULL, 0, 0, 0, 0, 0, 0, -1 }
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@ -63,10 +63,10 @@ static const Layout layouts[] = {
|
||||||
/* key definitions */
|
/* key definitions */
|
||||||
#define MODKEY Mod4Mask
|
#define MODKEY Mod4Mask
|
||||||
#define TAGKEYS(KEY,TAG) \
|
#define TAGKEYS(KEY,TAG) \
|
||||||
{ MODKEY, KEY, view, {.ui = 1 << TAG} }, \
|
{ MODKEY, KEY, 0, view, {.ui = 1 << TAG} }, \
|
||||||
{ MODKEY|ControlMask, KEY, toggleview, {.ui = 1 << TAG} }, \
|
{ MODKEY|ControlMask, KEY, 0, toggleview, {.ui = 1 << TAG} }, \
|
||||||
{ MODKEY|ShiftMask, KEY, tag, {.ui = 1 << TAG} }, \
|
{ MODKEY|ShiftMask, KEY, 0, tag, {.ui = 1 << TAG} }, \
|
||||||
{ MODKEY|ControlMask|ShiftMask, KEY, toggletag, {.ui = 1 << TAG} },
|
{ MODKEY|ControlMask|ShiftMask, KEY, 0, toggletag, {.ui = 1 << TAG} },
|
||||||
|
|
||||||
/* helper for spawning shell commands in the pre dwm-5.0 fashion */
|
/* helper for spawning shell commands in the pre dwm-5.0 fashion */
|
||||||
#define SHCMD(cmd) { .v = (const char*[]){ "/bin/sh", "-c", cmd, NULL } }
|
#define SHCMD(cmd) { .v = (const char*[]){ "/bin/sh", "-c", cmd, NULL } }
|
||||||
|
@ -125,69 +125,76 @@ static const char *backgroundDetails[] = { "background", "--only-notify", NULL }
|
||||||
static const char *powerMenu[] = { "rofi-shutdown", NULL };
|
static const char *powerMenu[] = { "rofi-shutdown", NULL };
|
||||||
|
|
||||||
#include "movestack.c"
|
#include "movestack.c"
|
||||||
|
|
||||||
|
#define MULTIKEY_THRESHOLD_MS_PRESS 200
|
||||||
|
#define MULTIKEY_THRESHOLD_MS_HOLD 700
|
||||||
|
|
||||||
|
|
||||||
static Key keys[] = {
|
static Key keys[] = {
|
||||||
/* modifier key function argument */
|
/* modifier key count function argument */
|
||||||
{ MODKEY, XK_p, spawn, {.v = dmenucmd } },
|
{ MODKEY, XK_p, 0, spawn, {.v = dmenucmd } },
|
||||||
{ MODKEY, XK_Return, spawn, {.v = termcmd } },
|
{ MODKEY, XK_Return, 0, spawn, {.v = termcmd } },
|
||||||
{ MODKEY|ControlMask, XK_Return, spawn, {.v = lfcmd } },
|
{ MODKEY|ControlMask, XK_Return, 0, spawn, {.v = lfcmd } },
|
||||||
{ MODKEY, XK_b, togglebar, {0} },
|
{ MODKEY, XK_b, 0, togglebar, {0} },
|
||||||
{ MODKEY, XK_j, focusstack, {.i = +1 } },
|
{ MODKEY, XK_j, 0, focusstack, {.i = +1 } },
|
||||||
{ MODKEY, XK_k, focusstack, {.i = -1 } },
|
{ MODKEY, XK_k, 0, focusstack, {.i = -1 } },
|
||||||
{ MODKEY|ShiftMask, XK_j, movestack, {.i = +1 } },
|
{ MODKEY|ShiftMask, XK_j, 0, movestack, {.i = +1 } },
|
||||||
{ MODKEY|ShiftMask, XK_k, movestack, {.i = -1 } },
|
{ MODKEY|ShiftMask, XK_k, 0, movestack, {.i = -1 } },
|
||||||
{ MODKEY, XK_i, incnmaster, {.i = +1 } },
|
{ MODKEY, XK_i, 0, incnmaster, {.i = +1 } },
|
||||||
{ MODKEY|ShiftMask, XK_i, incnmaster, {.i = -1 } },
|
{ MODKEY|ShiftMask, XK_i, 0, incnmaster, {.i = -1 } },
|
||||||
{ MODKEY, XK_h, setmfact, {.f = -0.05} },
|
{ MODKEY, XK_h, 0, setmfact, {.f = -0.05} },
|
||||||
{ MODKEY, XK_l, setmfact, {.f = +0.05} },
|
{ MODKEY, XK_l, 0, setmfact, {.f = +0.05} },
|
||||||
{ MODKEY|ShiftMask, XK_l, spawn, {.v = logout} },
|
{ MODKEY|ShiftMask, XK_l, 0, spawn, {.v = logout} },
|
||||||
{ MODKEY|ShiftMask, XK_Return, zoom, {0} },
|
{ MODKEY|ShiftMask, XK_Return, 0, zoom, {0} },
|
||||||
{ MODKEY, XK_Tab, toggleAttachBelow, {0} },
|
{ MODKEY, XK_Tab, 0, toggleAttachBelow, {0} },
|
||||||
{ MODKEY, XK_q, killclient, {0} },
|
{ MODKEY, XK_q, 0, killclient, {0} },
|
||||||
{ MODKEY, XK_t, setlayout, {.v = &layouts[0]} },
|
{ MODKEY, XK_t, 0, setlayout, {.v = &layouts[0]} },
|
||||||
{ MODKEY, XK_m, setlayout, {.v = &layouts[2]} },
|
{ MODKEY, XK_m, 0, setlayout, {.v = &layouts[2]} },
|
||||||
{ MODKEY|ShiftMask, XK_t, setlayout, {.v = &layouts[3]} },
|
{ MODKEY|ShiftMask, XK_t, 0, setlayout, {.v = &layouts[3]} },
|
||||||
{ MODKEY, XK_f, setlayout, {.v = &layouts[4]} },
|
{ MODKEY, XK_f, 0, setlayout, {.v = &layouts[4]} },
|
||||||
{ MODKEY|ShiftMask, XK_f, setlayout, {.v = &layouts[5]} },
|
{ MODKEY|ShiftMask, XK_f, 0, setlayout, {.v = &layouts[5]} },
|
||||||
{ MODKEY, XK_space, setlayout, {0} },
|
{ MODKEY, XK_space, 0, setlayout, {0} },
|
||||||
{ MODKEY|ShiftMask, XK_space, togglefloating, {0} },
|
{ MODKEY|ShiftMask, XK_space, 0, togglefloating, {0} },
|
||||||
{ MODKEY, XK_0, view, {.ui = ~0 } },
|
{ MODKEY, XK_0, 0, view, {.ui = ~0 } },
|
||||||
{ MODKEY|ShiftMask, XK_0, tag, {.ui = ~0 } },
|
{ MODKEY|ShiftMask, XK_0, 0, tag, {.ui = ~0 } },
|
||||||
{ MODKEY, XK_comma, focusmon, {.i = -1 } },
|
{ MODKEY, XK_comma, 0, focusmon, {.i = -1 } },
|
||||||
{ MODKEY, XK_period, focusmon, {.i = +1 } },
|
{ MODKEY, XK_period, 0, focusmon, {.i = +1 } },
|
||||||
{ MODKEY|ShiftMask, XK_comma, tagmon, {.i = -1 } },
|
{ MODKEY|ShiftMask, XK_comma, 0, tagmon, {.i = -1 } },
|
||||||
{ MODKEY|ShiftMask, XK_period, tagmon, {.i = +1 } },
|
{ MODKEY|ShiftMask, XK_period, 0, tagmon, {.i = +1 } },
|
||||||
{ 0, XK_Print, spawn, {.v = fullscreenshot } },
|
{ 0, XK_Print, 0, spawn, {.v = fullscreenshot } },
|
||||||
{ ControlMask, XK_Print, spawn, {.v = activescreenshot } },
|
{ ControlMask, XK_Print, 0, spawn, {.v = activescreenshot } },
|
||||||
{ ShiftMask, XK_Print, spawn, {.v = selectscreenshot } },
|
{ ShiftMask, XK_Print, 0, spawn, {.v = selectscreenshot } },
|
||||||
{ 0, XF86XK_AudioPlay, spawn, {.v = playpause } },
|
{ 0, XF86XK_AudioPlay, 0, spawn, {.v = playpause } },
|
||||||
{ MODKEY|ShiftMask, XK_d, spawn, {.v = date } },
|
{ MODKEY|ShiftMask, XK_d, 0, spawn, {.v = date } },
|
||||||
{ MODKEY|ShiftMask, XK_b, spawn, {.v = battery} },
|
{ MODKEY|ShiftMask, XK_b, 0, spawn, {.v = battery} },
|
||||||
{ MODKEY|ShiftMask, XK_Insert, spawn, {.v = greenclip } },
|
{ MODKEY|ShiftMask, XK_Insert, 0, spawn, {.v = greenclip } },
|
||||||
//Applications
|
//Applications
|
||||||
{ MODKEY|ShiftMask, XK_q, spawn, {.v = qutebrowser } },
|
{ MODKEY|ShiftMask, XK_q, 0, spawn, {.v = qutebrowser } },
|
||||||
{ MODKEY , XK_s, spawn, {.v = surf } },
|
{ MODKEY, XK_s, 0, spawn, {.v = surf } },
|
||||||
{ MODKEY, XK_c, spawn, {.v = firefox } },
|
{ MODKEY, XK_c, 0, spawn, {.v = firefox } },
|
||||||
{ MODKEY|ShiftMask, XK_c, spawn, {.v = chromium } },
|
{ MODKEY|ShiftMask, XK_c, 0, spawn, {.v = chromium } },
|
||||||
//Dmenu / Rofi
|
//Dmenu / Rofi
|
||||||
{ MODKEY, XK_u, spawn, {.v = unicode } },
|
{ MODKEY, XK_u, 0, spawn, {.v = unicode } },
|
||||||
{ MODKEY, XK_y, spawn, {.v = youtube } },
|
{ MODKEY, XK_y, 0, spawn, {.v = youtube } },
|
||||||
{ MODKEY, XK_a, spawn, {.v = offlineArchWiki } },
|
{ MODKEY, XK_a, 0, spawn, {.v = offlineArchWiki } },
|
||||||
{ MODKEY|ShiftMask, XK_a, spawn, {.v = screenlayout } },
|
{ MODKEY|ShiftMask, XK_a, 0, spawn, {.v = screenlayout } },
|
||||||
{ MODKEY|ShiftMask, XK_m, spawn, {.v = manPages } },
|
{ MODKEY|ShiftMask, XK_m, 0, spawn, {.v = manPages } },
|
||||||
{ MODKEY|ShiftMask, XK_p, spawn, {.v = ports } },
|
{ MODKEY|ShiftMask, XK_p, 0, spawn, {.v = ports } },
|
||||||
{ MODKEY, XK_w, spawn, {.v = whichproject } },
|
{ MODKEY, XK_w, 0, spawn, {.v = whichproject } },
|
||||||
{ MODKEY|ShiftMask, XK_w, spawn, {.v = project } },
|
{ MODKEY|ShiftMask, XK_w, 0, spawn, {.v = project } },
|
||||||
{ MODKEY, XK_d, spawn, {.v = pass } },
|
{ MODKEY, XK_d, 0, spawn, {.v = pass } },
|
||||||
//Background
|
//Background
|
||||||
{ MODKEY, XK_e, spawn, {.v = setBackgroundRandom } },
|
{ MODKEY, XK_e, 0, spawn, {.v = setBackgroundRandom } },
|
||||||
{ MODKEY|ControlMask, XK_e, spawn, {.v = backgroundDetails } },
|
{ MODKEY|ControlMask, XK_e, 0, spawn, {.v = backgroundDetails } },
|
||||||
//Special keys
|
//Special keys
|
||||||
{ 0, XF86XK_AudioRaiseVolume, spawn, {.v = volumeUp } },
|
{ 0, XF86XK_AudioRaiseVolume, 0, spawn, {.v = volumeUp } },
|
||||||
{ 0, XF86XK_AudioLowerVolume, spawn, {.v = volumeDown } },
|
{ 0, XF86XK_AudioLowerVolume, 0, spawn, {.v = volumeDown } },
|
||||||
{ 0, XF86XK_AudioMute, spawn, {.v = volumeToggle } },
|
{ 0, XF86XK_AudioMute, 0, spawn, {.v = volumeToggle } },
|
||||||
{ 0, XF86XK_MonBrightnessUp, spawn, {.v = brightnessUp } },
|
{ 0, XF86XK_MonBrightnessUp, 0, spawn, {.v = brightnessUp } },
|
||||||
{ 0, XF86XK_MonBrightnessDown, spawn, {.v = brightnessDown } },
|
{ 0, XF86XK_MonBrightnessDown, 0, spawn, {.v = brightnessDown } },
|
||||||
{ 0, XF86XK_PowerOff, spawn, {.v = powerMenu } },
|
{ 0, XF86XK_PowerOff, 0, spawn, {.v = powerMenu } },
|
||||||
|
{ MODKEY|ShiftMask, XK_r, 0, quit, {0} },
|
||||||
|
|
||||||
TAGKEYS( XK_1, 0)
|
TAGKEYS( XK_1, 0)
|
||||||
TAGKEYS( XK_2, 1)
|
TAGKEYS( XK_2, 1)
|
||||||
TAGKEYS( XK_3, 2)
|
TAGKEYS( XK_3, 2)
|
||||||
|
@ -197,7 +204,6 @@ static Key keys[] = {
|
||||||
TAGKEYS( XK_7, 6)
|
TAGKEYS( XK_7, 6)
|
||||||
TAGKEYS( XK_8, 7)
|
TAGKEYS( XK_8, 7)
|
||||||
TAGKEYS( XK_9, 8)
|
TAGKEYS( XK_9, 8)
|
||||||
{ MODKEY|ShiftMask, XK_r, quit, {0} },
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* button definitions */
|
/* button definitions */
|
||||||
|
|
|
@ -22,7 +22,7 @@ FREETYPEINC = /usr/include/freetype2
|
||||||
|
|
||||||
# includes and libs
|
# includes and libs
|
||||||
INCS = -I${X11INC} -I${FREETYPEINC}
|
INCS = -I${X11INC} -I${FREETYPEINC}
|
||||||
LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} ${FREETYPELIBS} -lX11-xcb -lxcb -lxcb-res
|
LIBS = -L${X11LIB} -lrt -lX11 ${XINERAMALIBS} ${FREETYPELIBS} -lX11-xcb -lxcb -lxcb-res
|
||||||
|
|
||||||
# flags
|
# flags
|
||||||
CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_POSIX_C_SOURCE=200809L -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS}
|
CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_POSIX_C_SOURCE=200809L -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS}
|
||||||
|
|
104
dwm.c
104
dwm.c
|
@ -30,6 +30,7 @@
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
|
#include <time.h>
|
||||||
#include <X11/cursorfont.h>
|
#include <X11/cursorfont.h>
|
||||||
#include <X11/keysym.h>
|
#include <X11/keysym.h>
|
||||||
#include <X11/Xatom.h>
|
#include <X11/Xatom.h>
|
||||||
|
@ -40,6 +41,7 @@
|
||||||
#include <X11/extensions/Xinerama.h>
|
#include <X11/extensions/Xinerama.h>
|
||||||
#endif /* XINERAMA */
|
#endif /* XINERAMA */
|
||||||
#include <X11/Xft/Xft.h>
|
#include <X11/Xft/Xft.h>
|
||||||
|
#include <X11/XKBlib.h>
|
||||||
#include <X11/Xlib-xcb.h>
|
#include <X11/Xlib-xcb.h>
|
||||||
#include <xcb/res.h>
|
#include <xcb/res.h>
|
||||||
|
|
||||||
|
@ -106,6 +108,7 @@ struct Client {
|
||||||
typedef struct {
|
typedef struct {
|
||||||
unsigned int mod;
|
unsigned int mod;
|
||||||
KeySym keysym;
|
KeySym keysym;
|
||||||
|
unsigned int npresses;
|
||||||
void (*func)(const Arg *);
|
void (*func)(const Arg *);
|
||||||
const Arg arg;
|
const Arg arg;
|
||||||
} Key;
|
} Key;
|
||||||
|
@ -187,6 +190,10 @@ static void grabbuttons(Client *c, int focused);
|
||||||
static void grabkeys(void);
|
static void grabkeys(void);
|
||||||
static void incnmaster(const Arg *arg);
|
static void incnmaster(const Arg *arg);
|
||||||
static void keypress(XEvent *e);
|
static void keypress(XEvent *e);
|
||||||
|
static void keypresstimerdispatch(int msduration, int data);
|
||||||
|
static void keypresstimerdone(union sigval timer_data);
|
||||||
|
static void keypresstimerdonesync(int idx);
|
||||||
|
static void keyrelease(XEvent *e);
|
||||||
static void killclient(const Arg *arg);
|
static void killclient(const Arg *arg);
|
||||||
static void manage(Window w, XWindowAttributes *wa);
|
static void manage(Window w, XWindowAttributes *wa);
|
||||||
static void mappingnotify(XEvent *e);
|
static void mappingnotify(XEvent *e);
|
||||||
|
@ -273,13 +280,14 @@ static void (*handler[LASTEvent]) (XEvent *) = {
|
||||||
[Expose] = expose,
|
[Expose] = expose,
|
||||||
[FocusIn] = focusin,
|
[FocusIn] = focusin,
|
||||||
[KeyPress] = keypress,
|
[KeyPress] = keypress,
|
||||||
|
[KeyRelease] = keyrelease,
|
||||||
[MappingNotify] = mappingnotify,
|
[MappingNotify] = mappingnotify,
|
||||||
[MapRequest] = maprequest,
|
[MapRequest] = maprequest,
|
||||||
[MotionNotify] = motionnotify,
|
[MotionNotify] = motionnotify,
|
||||||
[PropertyNotify] = propertynotify,
|
[PropertyNotify] = propertynotify,
|
||||||
[UnmapNotify] = unmapnotify
|
[UnmapNotify] = unmapnotify
|
||||||
};
|
};
|
||||||
static Atom wmatom[WMLast], netatom[NetLast];
|
static Atom timeratom, wmatom[WMLast], netatom[NetLast];
|
||||||
static int running = 1;
|
static int running = 1;
|
||||||
static Cur *cursor[CurLast];
|
static Cur *cursor[CurLast];
|
||||||
static Clr **scheme;
|
static Clr **scheme;
|
||||||
|
@ -290,6 +298,10 @@ static Window root, wmcheckwin;
|
||||||
|
|
||||||
static xcb_connection_t *xcon;
|
static xcb_connection_t *xcon;
|
||||||
|
|
||||||
|
static int multikeypendingindex = -1;
|
||||||
|
static timer_t multikeypendingtimer = NULL;
|
||||||
|
static int multikeyup = 1;
|
||||||
|
|
||||||
/* configuration, allows nested code to access above variables */
|
/* configuration, allows nested code to access above variables */
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
|
@ -604,6 +616,11 @@ clientmessage(XEvent *e)
|
||||||
XClientMessageEvent *cme = &e->xclient;
|
XClientMessageEvent *cme = &e->xclient;
|
||||||
Client *c = wintoclient(cme->window);
|
Client *c = wintoclient(cme->window);
|
||||||
|
|
||||||
|
if (cme->message_type == timeratom) {
|
||||||
|
keypresstimerdonesync(cme->data.s[0]);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (!c)
|
if (!c)
|
||||||
return;
|
return;
|
||||||
if (cme->message_type == netatom[NetWMState]) {
|
if (cme->message_type == netatom[NetWMState]) {
|
||||||
|
@ -1070,11 +1087,88 @@ keypress(XEvent *e) {
|
||||||
|
|
||||||
ev = &e->xkey;
|
ev = &e->xkey;
|
||||||
keysym = XKeycodeToKeysym(dpy, (KeyCode)ev->keycode, 0);
|
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
|
if (keysym == keys[i].keysym
|
||||||
&& CLEANMASK(keys[i].mod) == CLEANMASK(ev->state)
|
&& CLEANMASK(keys[i].mod) == CLEANMASK(ev->state)
|
||||||
&& keys[i].func)
|
&& keys[i].func){
|
||||||
keys[i].func(&(keys[i].arg));
|
// E.g. Normal functionality case - npresses 0 == keydown immediate fn
|
||||||
|
if (keys[i].npresses == 0) {
|
||||||
|
keys[i].func(&(keys[i].arg));
|
||||||
|
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(MULTIKEY_THRESHOLD_MS_PRESS, i);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
keypresstimerdispatch(int msduration, int data)
|
||||||
|
{
|
||||||
|
struct sigevent timer_signal_event;
|
||||||
|
struct itimerspec timer_period;
|
||||||
|
// Clear out the old timer if any set,and dispatch new timer
|
||||||
|
if (multikeypendingtimer != NULL) 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, &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(multikeypendingtimer, 0, &timer_period, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
keypresstimerdone(union sigval timer_data)
|
||||||
|
{
|
||||||
|
XEvent ev;
|
||||||
|
memset(&ev, 0, sizeof ev);
|
||||||
|
ev.xclient.type = ClientMessage;
|
||||||
|
ev.xclient.window = root;
|
||||||
|
ev.xclient.message_type = timeratom;
|
||||||
|
ev.xclient.format = 16;
|
||||||
|
ev.xclient.data.s[0] = ((short) timer_data.sival_int);
|
||||||
|
XSendEvent(dpy, root, False, SubstructureRedirectMask, &ev);
|
||||||
|
XSync(dpy, False);
|
||||||
|
}
|
||||||
|
|
||||||
|
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(
|
||||||
|
MULTIKEY_THRESHOLD_MS_HOLD - MULTIKEY_THRESHOLD_MS_PRESS,
|
||||||
|
maxidx
|
||||||
|
);
|
||||||
|
} else if (keys[idx].func) {
|
||||||
|
// Run the actual keys' fn
|
||||||
|
keys[idx].func(&(keys[idx].arg));
|
||||||
|
multikeypendingindex = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
keyrelease(XEvent *e)
|
||||||
|
{
|
||||||
|
multikeyup = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -2439,6 +2533,7 @@ zoom(const Arg *arg)
|
||||||
int
|
int
|
||||||
main(int argc, char *argv[])
|
main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
|
XInitThreads();
|
||||||
if (argc == 2 && !strcmp("-v", argv[1]))
|
if (argc == 2 && !strcmp("-v", argv[1]))
|
||||||
die("dwm-"VERSION);
|
die("dwm-"VERSION);
|
||||||
else if (argc != 1)
|
else if (argc != 1)
|
||||||
|
@ -2449,6 +2544,7 @@ main(int argc, char *argv[])
|
||||||
die("dwm: cannot open display");
|
die("dwm: cannot open display");
|
||||||
if (!(xcon = XGetXCBConnection(dpy)))
|
if (!(xcon = XGetXCBConnection(dpy)))
|
||||||
die("dwm: cannot get xcb connection\n");
|
die("dwm: cannot get xcb connection\n");
|
||||||
|
XkbSetDetectableAutoRepeat(dpy, True, NULL);
|
||||||
checkotherwm();
|
checkotherwm();
|
||||||
setup();
|
setup();
|
||||||
#ifdef __OpenBSD__
|
#ifdef __OpenBSD__
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue