sites

public wiki contents of suckless.org
git clone git://git.suckless.org/sites
Log | Files | Refs

keysequence-20250606-0d6af14.diff (4102B)


      1 From 0d6af14efa1250631b081ad9d1f3aa0263221fd8 Mon Sep 17 00:00:00 2001
      2 From: TUVIMEN <hexderm@gmail.com>
      3 Date: Fri, 6 Jun 2025 09:08:40 +0200
      4 Subject: [PATCH] [PATCH] 6.5 keysequence patch
      5 
      6 ---
      7  config.def.h |  1 +
      8  dwm.c        | 86 +++++++++++++++++++++++++++++++++++++++++++++++-----
      9  2 files changed, 80 insertions(+), 7 deletions(-)
     10 
     11 diff --git a/config.def.h b/config.def.h
     12 index 9efa774..6104343 100644
     13 --- a/config.def.h
     14 +++ b/config.def.h
     15 @@ -95,6 +95,7 @@ static const Key keys[] = {
     16  	TAGKEYS(                        XK_8,                      7)
     17  	TAGKEYS(                        XK_9,                      8)
     18  	{ MODKEY|ShiftMask,             XK_q,      quit,           {0} },
     19 +	{0}
     20  };
     21  
     22  /* button definitions */
     23 diff --git a/dwm.c b/dwm.c
     24 index f1d86b2..89a4bc5 100644
     25 --- a/dwm.c
     26 +++ b/dwm.c
     27 @@ -28,6 +28,7 @@
     28  #include <stdlib.h>
     29  #include <string.h>
     30  #include <unistd.h>
     31 +#include <time.h>
     32  #include <sys/types.h>
     33  #include <sys/wait.h>
     34  #include <X11/cursorfont.h>
     35 @@ -177,6 +178,7 @@ static void grabbuttons(Client *c, int focused);
     36  static void grabkeys(void);
     37  static void incnmaster(const Arg *arg);
     38  static void keypress(XEvent *e);
     39 +static void keypress_other(const Arg *arg);
     40  static void killclient(const Arg *arg);
     41  static void manage(Window w, XWindowAttributes *wa);
     42  static void mappingnotify(XEvent *e);
     43 @@ -949,6 +951,13 @@ grabbuttons(Client *c, int focused)
     44  	}
     45  }
     46  
     47 +static char
     48 +key_not_empty(const Key *key)
     49 +{
     50 +    static const Key empty = {0};
     51 +    return memcmp(key, &empty, sizeof(Key)) != 0;
     52 +}
     53 +
     54  void
     55  grabkeys(void)
     56  {
     57 @@ -965,7 +974,7 @@ grabkeys(void)
     58  		if (!syms)
     59  			return;
     60  		for (k = start; k <= end; k++)
     61 -			for (i = 0; i < LENGTH(keys); i++)
     62 +			for (i = 0; key_not_empty(keys+i); i++)
     63  				/* skip modifier codes, we do that ourselves */
     64  				if (keys[i].keysym == syms[(k - start) * skip])
     65  					for (j = 0; j < LENGTH(modifiers); j++)
     66 @@ -996,8 +1005,8 @@ isuniquegeom(XineramaScreenInfo *unique, size_t n, XineramaScreenInfo *info)
     67  }
     68  #endif /* XINERAMA */
     69  
     70 -void
     71 -keypress(XEvent *e)
     72 +static void
     73 +keypress_r(XEvent *e, const Key *keys)
     74  {
     75  	unsigned int i;
     76  	KeySym keysym;
     77 @@ -1005,11 +1014,74 @@ keypress(XEvent *e)
     78  
     79  	ev = &e->xkey;
     80  	keysym = XKeycodeToKeysym(dpy, (KeyCode)ev->keycode, 0);
     81 -	for (i = 0; i < LENGTH(keys); i++)
     82 +	for (i = 0; key_not_empty(keys+i); i++)
     83  		if (keysym == keys[i].keysym
     84 -		&& CLEANMASK(keys[i].mod) == CLEANMASK(ev->state)
     85 -		&& keys[i].func)
     86 -			keys[i].func(&(keys[i].arg));
     87 +            && CLEANMASK(keys[i].mod) == CLEANMASK(ev->state)
     88 +            && keys[i].func)
     89 +            keys[i].func(&(keys[i].arg));
     90 +}
     91 +
     92 +static char
     93 +grabkeyboard(void) //taken from dmenu
     94 +{
     95 +	struct timespec ts = { .tv_sec = 0, .tv_nsec = 1000000  };
     96 +
     97 +	/* try to grab keyboard, we may have to wait for another process to ungrab */
     98 +	for (int i = 0; i < 1000; i++) {
     99 +		if (XGrabKeyboard(dpy, DefaultRootWindow(dpy), True, GrabModeAsync,
    100 +		    GrabModeAsync, CurrentTime) == GrabSuccess)
    101 +			return 0;
    102 +		nanosleep(&ts, NULL);
    103 +	}
    104 +    return 1; //failed
    105 +}
    106 +
    107 +static char
    108 +keysym_is_modifier(KeySym s)
    109 +{
    110 +	return (s == XK_Shift_L ||
    111 +        s == XK_Shift_R ||
    112 +        s == XK_Control_L ||
    113 +        s == XK_Control_R ||
    114 +        s == XK_Caps_Lock ||
    115 +        s == XK_Shift_Lock ||
    116 +        s == XK_Meta_L ||
    117 +        s == XK_Meta_R ||
    118 +        s == XK_Alt_L ||
    119 +        s == XK_Alt_R ||
    120 +        s == XK_Super_L ||
    121 +        s == XK_Super_R ||
    122 +        s == XK_Hyper_L ||
    123 +        s == XK_Hyper_R);
    124 +}
    125 +
    126 +void
    127 +keypress_other(const Arg *arg)
    128 +{
    129 +    if (grabkeyboard())
    130 +        return;
    131 +
    132 +    XEvent ev;
    133 +    while (!XNextEvent(dpy, &ev)) {
    134 +        if (ev.type == ButtonPress)
    135 +            break;
    136 +        if (ev.type == KeyPress) {
    137 +            KeySym keysym = XKeycodeToKeysym(dpy, (KeyCode)ev.xkey.keycode, 0);
    138 +            if (keysym_is_modifier(keysym))
    139 +                continue;
    140 +            keypress_r(&ev, (Key*)arg->v);
    141 +            break;
    142 +        }
    143 +    }
    144 +
    145 +    XUngrabKeyboard(dpy, CurrentTime);
    146 +    grabkeys();
    147 +}
    148 +
    149 +void
    150 +keypress(XEvent *e)
    151 +{
    152 +    keypress_r(e,keys);
    153  }
    154  
    155  void
    156 -- 
    157 2.49.0
    158