Aplay keychord patch 🥰
This commit is contained in:
		
							parent
							
								
									f8de713afe
								
							
						
					
					
						commit
						869135c594
					
				
					 6 changed files with 359 additions and 2835 deletions
				
			
		| 
						 | 
				
			
			@ -1,130 +0,0 @@
 | 
			
		|||
/* See LICENSE file for copyright and license details. */
 | 
			
		||||
 | 
			
		||||
/* appearance */
 | 
			
		||||
static const unsigned int borderpx  = 1;        /* border pixel of windows */
 | 
			
		||||
static const unsigned int snap      = 32;       /* snap pixel */
 | 
			
		||||
static const unsigned int systraypinning = 0;   /* 0: sloppy systray follows selected monitor, >0: pin systray to monitor X */
 | 
			
		||||
static const unsigned int systrayonleft = 0;   	/* 0: systray in the right corner, >0: systray on left of status text */
 | 
			
		||||
static const unsigned int systrayspacing = 2;   /* systray spacing */
 | 
			
		||||
static const int systraypinningfailfirst = 1;   /* 1: if pinning fails, display systray on the first monitor, False: display systray on the last monitor*/
 | 
			
		||||
static const int showsystray        = 1;     /* 0 means no systray */
 | 
			
		||||
static const int showbar            = 1;     /* 0 means no bar */
 | 
			
		||||
static const int topbar             = 1;     /* 0 means bottom bar */
 | 
			
		||||
static const char *fonts[]          = { "monospace:size=10" };
 | 
			
		||||
static const char dmenufont[]       = "monospace:size=10";
 | 
			
		||||
static const char col_gray1[]       = "#222222";
 | 
			
		||||
static const char col_gray2[]       = "#444444";
 | 
			
		||||
static const char col_gray3[]       = "#bbbbbb";
 | 
			
		||||
static const char col_gray4[]       = "#eeeeee";
 | 
			
		||||
static const char col_cyan[]        = "#005577";
 | 
			
		||||
static const char *colors[][3]      = {
 | 
			
		||||
	/*               fg         bg         border   */
 | 
			
		||||
	[SchemeNorm] = { col_gray3, col_gray1, col_gray2 },
 | 
			
		||||
	[SchemeSel]  = { col_gray4, col_cyan,  col_cyan  },
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static const char *const autostart[] = {
 | 
			
		||||
	"st", NULL,
 | 
			
		||||
	NULL /* terminate */
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* tagging */
 | 
			
		||||
static const char *tags[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" };
 | 
			
		||||
 | 
			
		||||
static const Rule rules[] = {
 | 
			
		||||
	/* xprop(1):
 | 
			
		||||
	 *	WM_CLASS(STRING) = instance, class
 | 
			
		||||
	 *	WM_NAME(STRING) = title
 | 
			
		||||
	 */
 | 
			
		||||
	/* class      instance    title       tags mask     isfloating   monitor */
 | 
			
		||||
	{ "Gimp",     NULL,       NULL,       0,            1,           -1 },
 | 
			
		||||
	{ "Firefox",  NULL,       NULL,       1 << 8,       0,           -1 },
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* layout(s) */
 | 
			
		||||
static const float mfact     = 0.55; /* factor of master area size [0.05..0.95] */
 | 
			
		||||
static const int nmaster     = 1;    /* number of clients in master area */
 | 
			
		||||
static const int resizehints = 1;    /* 1 means respect size hints in tiled resizals */
 | 
			
		||||
static const int lockfullscreen = 1; /* 1 will force focus on the fullscreen window */
 | 
			
		||||
 | 
			
		||||
static const Layout layouts[] = {
 | 
			
		||||
	/* symbol     arrange function */
 | 
			
		||||
	{ "[]=",      tile },    /* first entry is default */
 | 
			
		||||
	{ "><>",      NULL },    /* no layout function means floating behavior */
 | 
			
		||||
	{ "[M]",      monocle },
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* key definitions */
 | 
			
		||||
#define MODKEY Mod1Mask
 | 
			
		||||
#define TAGKEYS(KEY,TAG) \
 | 
			
		||||
	{ MODKEY,                       KEY,      view,           {.ui = 1 << TAG} }, \
 | 
			
		||||
	{ MODKEY|ControlMask,           KEY,      toggleview,     {.ui = 1 << TAG} }, \
 | 
			
		||||
	{ MODKEY|ShiftMask,             KEY,      tag,            {.ui = 1 << TAG} }, \
 | 
			
		||||
	{ MODKEY|ControlMask|ShiftMask, KEY,      toggletag,      {.ui = 1 << TAG} },
 | 
			
		||||
 | 
			
		||||
/* helper for spawning shell commands in the pre dwm-5.0 fashion */
 | 
			
		||||
#define SHCMD(cmd) { .v = (const char*[]){ "/bin/sh", "-c", cmd, NULL } }
 | 
			
		||||
 | 
			
		||||
/* commands */
 | 
			
		||||
static char dmenumon[2] = "0"; /* component of dmenucmd, manipulated in spawn() */
 | 
			
		||||
static const char *dmenucmd[] = { "dmenu_run", "-m", dmenumon, "-fn", dmenufont, "-nb", col_gray1, "-nf", col_gray3, "-sb", col_cyan, "-sf", col_gray4, NULL };
 | 
			
		||||
static const char *termcmd[]  = { "st", NULL };
 | 
			
		||||
 | 
			
		||||
#include "movestack.c"
 | 
			
		||||
static Key keys[] = {
 | 
			
		||||
	/* modifier                     key        function        argument */
 | 
			
		||||
	{ MODKEY,                       XK_p,      spawn,          {.v = dmenucmd } },
 | 
			
		||||
	{ MODKEY|ShiftMask,             XK_Return, spawn,          {.v = termcmd } },
 | 
			
		||||
	{ MODKEY,                       XK_b,      togglebar,      {0} },
 | 
			
		||||
	{ MODKEY,                       XK_j,      focusstack,     {.i = +1 } },
 | 
			
		||||
	{ MODKEY,                       XK_k,      focusstack,     {.i = -1 } },
 | 
			
		||||
	{ MODKEY,                       XK_i,      incnmaster,     {.i = +1 } },
 | 
			
		||||
	{ MODKEY,                       XK_d,      incnmaster,     {.i = -1 } },
 | 
			
		||||
	{ MODKEY,                       XK_h,      setmfact,       {.f = -0.05} },
 | 
			
		||||
	{ MODKEY,                       XK_l,      setmfact,       {.f = +0.05} },
 | 
			
		||||
	{ MODKEY|ShiftMask,             XK_j,      movestack,      {.i = +1 } },
 | 
			
		||||
	{ MODKEY|ShiftMask,             XK_k,      movestack,      {.i = -1 } },
 | 
			
		||||
	{ MODKEY,                       XK_Return, zoom,           {0} },
 | 
			
		||||
	{ MODKEY,                       XK_Tab,    view,           {0} },
 | 
			
		||||
	{ MODKEY|ShiftMask,             XK_c,      killclient,     {0} },
 | 
			
		||||
	{ MODKEY,                       XK_t,      setlayout,      {.v = &layouts[0]} },
 | 
			
		||||
	{ MODKEY,                       XK_f,      setlayout,      {.v = &layouts[1]} },
 | 
			
		||||
	{ MODKEY,                       XK_m,      setlayout,      {.v = &layouts[2]} },
 | 
			
		||||
	{ MODKEY|ShiftMask,             XK_f,      fullscreen,     {0} },
 | 
			
		||||
	{ MODKEY,                       XK_space,  setlayout,      {0} },
 | 
			
		||||
	{ MODKEY|ShiftMask,             XK_space,  togglefloating, {0} },
 | 
			
		||||
	{ MODKEY,                       XK_0,      view,           {.ui = ~0 } },
 | 
			
		||||
	{ MODKEY|ShiftMask,             XK_0,      tag,            {.ui = ~0 } },
 | 
			
		||||
	{ MODKEY,                       XK_comma,  focusmon,       {.i = -1 } },
 | 
			
		||||
	{ MODKEY,                       XK_period, focusmon,       {.i = +1 } },
 | 
			
		||||
	{ MODKEY|ShiftMask,             XK_comma,  tagmon,         {.i = -1 } },
 | 
			
		||||
	{ MODKEY|ShiftMask,             XK_period, tagmon,         {.i = +1 } },
 | 
			
		||||
	TAGKEYS(                        XK_1,                      0)
 | 
			
		||||
	TAGKEYS(                        XK_2,                      1)
 | 
			
		||||
	TAGKEYS(                        XK_3,                      2)
 | 
			
		||||
	TAGKEYS(                        XK_4,                      3)
 | 
			
		||||
	TAGKEYS(                        XK_5,                      4)
 | 
			
		||||
	TAGKEYS(                        XK_6,                      5)
 | 
			
		||||
	TAGKEYS(                        XK_7,                      6)
 | 
			
		||||
	TAGKEYS(                        XK_8,                      7)
 | 
			
		||||
	TAGKEYS(                        XK_9,                      8)
 | 
			
		||||
	{ MODKEY|ShiftMask,             XK_q,      quit,           {0} },
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* button definitions */
 | 
			
		||||
/* click can be ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle, ClkClientWin, or ClkRootWin */
 | 
			
		||||
static Button buttons[] = {
 | 
			
		||||
	/* click                event mask      button          function        argument */
 | 
			
		||||
	{ ClkTagBar,            MODKEY,         Button1,        tag,            {0} },
 | 
			
		||||
	{ ClkTagBar,            MODKEY,         Button3,        toggletag,      {0} },
 | 
			
		||||
	{ ClkWinTitle,          0,              Button2,        zoom,           {0} },
 | 
			
		||||
	{ ClkStatusText,        0,              Button2,        spawn,          {.v = termcmd } },
 | 
			
		||||
	{ ClkClientWin,         MODKEY,         Button1,        movemouse,      {0} },
 | 
			
		||||
	{ ClkClientWin,         MODKEY,         Button2,        togglefloating, {0} },
 | 
			
		||||
	{ ClkClientWin,         MODKEY,         Button3,        resizemouse,    {0} },
 | 
			
		||||
	{ ClkTagBar,            0,              Button1,        view,           {0} },
 | 
			
		||||
	{ ClkTagBar,            0,              Button3,        toggleview,     {0} },
 | 
			
		||||
	{ ClkTagBar,            MODKEY,         Button1,        tag,            {0} },
 | 
			
		||||
	{ ClkTagBar,            MODKEY,         Button3,        toggletag,      {0} },
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1,10 +0,0 @@
 | 
			
		|||
--- config.def.h
 | 
			
		||||
+++ config.def.h
 | 
			
		||||
@@ -78,6 +80,7 @@ static Key keys[] = {
 | 
			
		||||
 	{ MODKEY,                       XK_t,      setlayout,      {.v = &layouts[0]} },
 | 
			
		||||
 	{ MODKEY,                       XK_f,      setlayout,      {.v = &layouts[1]} },
 | 
			
		||||
 	{ MODKEY,                       XK_m,      setlayout,      {.v = &layouts[2]} },
 | 
			
		||||
+	{ MODKEY,                       XK_g,      setlayout,      {.v = &layouts[3]} },
 | 
			
		||||
 	{ MODKEY,                       XK_space,  setlayout,      {0} },
 | 
			
		||||
 	{ MODKEY|ShiftMask,             XK_space,  togglefloating, {0} },
 | 
			
		||||
 	{ MODKEY,                       XK_0,      view,           {.ui = ~0 } },
 | 
			
		||||
							
								
								
									
										161
									
								
								config.h
									
										
									
									
									
								
							
							
						
						
									
										161
									
								
								config.h
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -1,10 +1,10 @@
 | 
			
		|||
/* See LICENSE file for copyright and license details. */
 | 
			
		||||
 | 
			
		||||
/* def */
 | 
			
		||||
#define WEBBROWSER		 "google-chrome-stable"
 | 
			
		||||
#define TERMINAL		 "alacritty"
 | 
			
		||||
#define SCREENSHOT		 "spectacle"
 | 
			
		||||
#define GUI_FILEMANAGER	 "dolphin"
 | 
			
		||||
#define WEBBROWSER		"google-chrome-stable"
 | 
			
		||||
#define TERMINAL		"alacritty"
 | 
			
		||||
#define SCREENSHOT		"spectacle"
 | 
			
		||||
#define GUI_FILEMANAGER	        "dolphin"
 | 
			
		||||
 | 
			
		||||
/* appearance */
 | 
			
		||||
static const unsigned int borderpx  = 1;        /* border pixel of windows */
 | 
			
		||||
| 
						 | 
				
			
			@ -73,10 +73,10 @@ static const Layout layouts[] = {
 | 
			
		|||
#define MODKEY Mod4Mask // win/super key
 | 
			
		||||
 | 
			
		||||
#define TAGKEYS(KEY,TAG) \
 | 
			
		||||
	{ MODKEY,                       KEY,      view,           {.ui = 1 << TAG} }, \
 | 
			
		||||
	{ MODKEY|ControlMask,           KEY,      toggleview,     {.ui = 1 << TAG} }, \
 | 
			
		||||
	{ MODKEY|ShiftMask,             KEY,      tag,            {.ui = 1 << TAG} }, \
 | 
			
		||||
	{ MODKEY|ControlMask|ShiftMask, KEY,      toggletag,      {.ui = 1 << TAG} },
 | 
			
		||||
	{1, {{MODKEY,                        KEY}},      view,           {.ui = 1 << TAG} }, \
 | 
			
		||||
	{1, {{MODKEY|ControlMask,            KEY}},      toggleview,     {.ui = 1 << TAG} }, \
 | 
			
		||||
	{1, {{MODKEY|ShiftMask,              KEY}},      tag,            {.ui = 1 << TAG} }, \
 | 
			
		||||
	{1, {{MODKEY|ControlMask|ShiftMask,  KEY}},      toggletag,      {.ui = 1 << TAG} },
 | 
			
		||||
 | 
			
		||||
/* helper for spawning shell commands in the pre dwm-5.0 fashion */
 | 
			
		||||
#define SHCMD(cmd) { .v = (const char*[]){ "/bin/sh", "-c", cmd, NULL } }
 | 
			
		||||
| 
						 | 
				
			
			@ -89,99 +89,118 @@ static const char *termcmd[]  = { TERMINAL, NULL };
 | 
			
		|||
#include "movestack.c"
 | 
			
		||||
// X11 keysym definitions
 | 
			
		||||
#include <X11/XF86keysym.h> // req (libxinerama1 and libxinerama-dev)
 | 
			
		||||
static Key keys[] = {
 | 
			
		||||
static Keychord keychords[] = {
 | 
			
		||||
	/* modifier                     key        function        argument */
 | 
			
		||||
	/* ---------------------------------- Apps Keys ---------------------------------- */
 | 
			
		||||
	// Dmenu (launcher)
 | 
			
		||||
	{ MODKEY|ShiftMask,             XK_d,      spawn,                  {.v = dmenucmd } },
 | 
			
		||||
	{1, {{MODKEY|ShiftMask,             XK_d}},      spawn,                  {.v = dmenucmd } },
 | 
			
		||||
	// Rofi launcher (small)
 | 
			
		||||
	{ MODKEY|ShiftMask|ControlMask, XK_d,      spawn,                  SHCMD("rofi -show drun") }, 
 | 
			
		||||
	{1, {{MODKEY|ShiftMask|ControlMask, XK_d}},      spawn,                  SHCMD("rofi -show drun") }, 
 | 
			
		||||
	// Start the terminal
 | 
			
		||||
	{ MODKEY,                       XK_Return, spawn,                  {.v = termcmd } },
 | 
			
		||||
	{1, {{MODKEY,                       XK_Return}}, spawn,                  {.v = termcmd } },
 | 
			
		||||
	// Start the terminal with tmux
 | 
			
		||||
	{ MODKEY|ShiftMask,             XK_Return, spawn,           SHCMD(TERMINAL " -e tmux")  },
 | 
			
		||||
	{2, {{MODKEY, XK_t},                {0, XK_1}},      spawn,           SHCMD(TERMINAL " -e tmux")  },
 | 
			
		||||
	// File browsers
 | 
			
		||||
	{ MODKEY|ShiftMask,             XK_f,      spawn,           SHCMD(GUI_FILEMANAGER) },
 | 
			
		||||
	{2, {{MODKEY|ShiftMask, XK_f},      {0, XK_g}},     spawn,           SHCMD(GUI_FILEMANAGER) },
 | 
			
		||||
	// Rofi file browser (small)
 | 
			
		||||
        { MODKEY|ShiftMask|ControlMask, XK_f,      spawn,           SHCMD("rofi -show filebrowser") },
 | 
			
		||||
	// Start the web brower
 | 
			
		||||
	{ MODKEY,                       XK_w,      spawn,           SHCMD(WEBBROWSER) },
 | 
			
		||||
        {2, {{MODKEY|ShiftMask, XK_f},      {0, XK_r}},     spawn,           SHCMD("rofi -show filebrowser") },
 | 
			
		||||
	/************************************* Start the web browers *************************************/
 | 
			
		||||
        // Google chrome stable
 | 
			
		||||
	{2, {{MODKEY, XK_w},                {0, XK_g}},     spawn,           SHCMD(WEBBROWSER) },
 | 
			
		||||
        // Tor brower
 | 
			
		||||
	{2, {{MODKEY, XK_w},                {0, XK_t}},     spawn,           SHCMD("tor-browser") },
 | 
			
		||||
	/************************************* Start the caht/email apps *************************************/
 | 
			
		||||
	// Discord
 | 
			
		||||
	{ MODKEY|ShiftMask,             XK_b,        spawn,         SHCMD("discord") },
 | 
			
		||||
	{2, {{MODKEY, XK_c},                {0, XK_d}},      spawn,           SHCMD("discord") },
 | 
			
		||||
	/************************************* Start the dev apps *************************************/
 | 
			
		||||
	// Jetbrains toolbox
 | 
			
		||||
	{ MODKEY|ShiftMask,             XK_t,        spawn,         SHCMD("jetbrains-toolbox") },
 | 
			
		||||
	{2, {{MODKEY, XK_a},                {0, XK_j}},     spawn,         SHCMD("jetbrains-toolbox") },
 | 
			
		||||
        // NeoVim
 | 
			
		||||
	{2, {{MODKEY, XK_a},                {0, XK_n}},     spawn,         SHCMD(TERMINAL "-e nvim") },
 | 
			
		||||
        // Vim
 | 
			
		||||
	{2, {{MODKEY, XK_d},                {0, XK_v}},     spawn,         SHCMD(TERMINAL "-e vim") },
 | 
			
		||||
	/************************************* Start the emoji piker apps *************************************/
 | 
			
		||||
	// Emoji selector (rofi)
 | 
			
		||||
	{ Mod4Mask,                    XK_period,   spawn,          SHCMD("rofi -show emoji") },
 | 
			
		||||
	/* ---------------------------------- dwm Keys ---------------------------------- */
 | 
			
		||||
	{1, {{Mod4Mask,                    XK_period}},    spawn,          SHCMD("rofi -show emoji") },
 | 
			
		||||
	/************************************* dwm keys *************************************/
 | 
			
		||||
	// Full screen mode
 | 
			
		||||
	{ MODKEY,				        XK_f,      fullscreen,     {0} },
 | 
			
		||||
	{1, {{MODKEY,			XK_f}},      fullscreen,     {0} },
 | 
			
		||||
	// Toggle the slstatus bar (hide/show)
 | 
			
		||||
	{ MODKEY,                       XK_b,      togglebar,      {0} },
 | 
			
		||||
 | 
			
		||||
	{ MODKEY,                       XK_j,      focusstack,     {.i = +1 } },
 | 
			
		||||
	{ MODKEY,                       XK_k,      focusstack,     {.i = -1 } },
 | 
			
		||||
	{ MODKEY,                       XK_i,      incnmaster,     {.i = +1 } },
 | 
			
		||||
	{ MODKEY,                       XK_d,      incnmaster,     {.i = -1 } },
 | 
			
		||||
	{ MODKEY,                       XK_h,      setmfact,       {.f = -0.05} },
 | 
			
		||||
	{ MODKEY,                       XK_l,      setmfact,       {.f = +0.05} },
 | 
			
		||||
	{1, {{MODKEY,                   XK_b}},      togglebar,      {0} },
 | 
			
		||||
        // Change the focus
 | 
			
		||||
	{1, {{MODKEY,                   XK_j}},      focusstack,     {.i = +1 } },
 | 
			
		||||
	{1, {{MODKEY,                   XK_k}},      focusstack,     {.i = -1 } },
 | 
			
		||||
        // Change the stack layout (horizontal/virtecal)
 | 
			
		||||
	{1, {{MODKEY,                   XK_i}},      incnmaster,     {.i = +1 } },
 | 
			
		||||
	{1, {{MODKEY,                   XK_d}},      incnmaster,     {.i = -1 } },
 | 
			
		||||
        // Change the focus window size (in the tile mode)
 | 
			
		||||
	{1, {{MODKEY,                   XK_h}},      setmfact,       {.f = -0.05} },
 | 
			
		||||
	{1, {{MODKEY,                   XK_l}},      setmfact,       {.f = +0.05} },
 | 
			
		||||
//	{ MODKEY,                       XK_Return, zoom,           {0} },
 | 
			
		||||
	{ MODKEY,                       XK_Tab,    view,           {0} },
 | 
			
		||||
 | 
			
		||||
	{ MODKEY|ShiftMask,             XK_j,      movestack,      {.i = +1 } }, 
 | 
			
		||||
	{ MODKEY|ShiftMask,             XK_k,      movestack,      {.i = -1 } }, 
 | 
			
		||||
	{1, {{MODKEY,                   XK_Tab}},    view,           {0} },
 | 
			
		||||
 | 
			
		||||
	{1, {{MODKEY|ShiftMask,         XK_j}},      movestack,      {.i = +1 } }, 
 | 
			
		||||
	{1, {{MODKEY|ShiftMask,          XK_k}},      movestack,      {.i = -1 } }, 
 | 
			
		||||
    
 | 
			
		||||
	// Quit from the foucsed window (kill)
 | 
			
		||||
	{ MODKEY|ShiftMask,             XK_q,      killclient,     {0} },
 | 
			
		||||
	{2, {{MODKEY, XK_q},            {0, XK_q}},      killclient,     {0} },
 | 
			
		||||
        /************************* Switch between layouts *************************/
 | 
			
		||||
	// Tiled layout
 | 
			
		||||
	{ MODKEY,                       XK_t,      setlayout,      {.v = &layouts[0]} },
 | 
			
		||||
	{2, {{MODKEY, XK_s},           {0, XK_t}},      setlayout,      {.v = &layouts[0]} },
 | 
			
		||||
	// Floating layout
 | 
			
		||||
	{ MODKEY,                       XK_f,      setlayout,      {.v = &layouts[1]} },
 | 
			
		||||
	{2, {{MODKEY, XK_s},           {0, XK_f}},      setlayout,      {.v = &layouts[1]} },
 | 
			
		||||
	// Monocle layout
 | 
			
		||||
	{ MODKEY,                       XK_m,      setlayout,      {.v = &layouts[2]} },
 | 
			
		||||
	{ MODKEY,                       XK_g,      setlayout,      {.v = &layouts[3]} },
 | 
			
		||||
	{2, {{MODKEY, XK_s},           {0, XK_m}},      setlayout,      {.v = &layouts[2]} },
 | 
			
		||||
        // Grid layout
 | 
			
		||||
	{2, {{MODKEY, XK_s},           {0, XK_g}},      setlayout,      {.v = &layouts[3]} },
 | 
			
		||||
 | 
			
		||||
	{ MODKEY|ShiftMask,             XK_space,  setlayout,      {0} },
 | 
			
		||||
	{ MODKEY|Mod1Mask,             XK_f,  togglefloating,     {0} },
 | 
			
		||||
 | 
			
		||||
	{ MODKEY,                       XK_0,      view,           {.ui = ~0 } },
 | 
			
		||||
	{ MODKEY|ShiftMask,             XK_0,      tag,            {.ui = ~0 } },
 | 
			
		||||
	{ MODKEY,                       XK_comma,  focusmon,       {.i = -1 } },
 | 
			
		||||
	{ MODKEY,                       XK_period, focusmon,       {.i = +1 } },
 | 
			
		||||
	{ MODKEY|ShiftMask,             XK_comma,  tagmon,         {.i = -1 } },
 | 
			
		||||
	{ MODKEY|ShiftMask,             XK_period, tagmon,         {.i = +1 } },
 | 
			
		||||
	TAGKEYS(                        XK_1,                      0)
 | 
			
		||||
	TAGKEYS(                        XK_2,                      1)
 | 
			
		||||
	TAGKEYS(                        XK_3,                      2)
 | 
			
		||||
	TAGKEYS(                        XK_4,                      3)
 | 
			
		||||
	TAGKEYS(                        XK_5,                      4)
 | 
			
		||||
	TAGKEYS(                        XK_6,                      5)
 | 
			
		||||
	TAGKEYS(                        XK_7,                      6)
 | 
			
		||||
	TAGKEYS(                        XK_8,                      7)
 | 
			
		||||
	TAGKEYS(                        XK_9,                      8)
 | 
			
		||||
        // Toggle between current layout and tile layout  
 | 
			
		||||
	{2, {{MODKEY, XK_s},             {0, XK_space}},  setlayout,      {0} },
 | 
			
		||||
        // Toggle floating window
 | 
			
		||||
	{1, {{MODKEY|Mod1Mask,           XK_f}},        togglefloating,     {0} },
 | 
			
		||||
        // View all tags
 | 
			
		||||
	{1, {{MODKEY,                    XK_0}},        view,           {.ui = ~0 } },
 | 
			
		||||
        // Mirror the current tagg in all tags
 | 
			
		||||
	{1, {{MODKEY|ShiftMask,          XK_0}},        tag,            {.ui = ~0 } },
 | 
			
		||||
        // I don't know
 | 
			
		||||
	{1, {{MODKEY,                    XK_comma}},    focusmon,       {.i = -1 } },
 | 
			
		||||
	{1, {{MODKEY,                    XK_period}},   focusmon,       {.i = +1 } },
 | 
			
		||||
	{1, {{MODKEY|ShiftMask,          XK_comma}},    tagmon,         {.i = -1 } },
 | 
			
		||||
	{1, {{MODKEY|ShiftMask,          XK_period}},   tagmon,         {.i = +1 } },
 | 
			
		||||
        /************************* Tag keys *************************/
 | 
			
		||||
	TAGKEYS(                         XK_1,                      0)
 | 
			
		||||
	TAGKEYS(                         XK_2,                      1)
 | 
			
		||||
	TAGKEYS(                         XK_3,                      2)
 | 
			
		||||
	TAGKEYS(                         XK_4,                      3)
 | 
			
		||||
	TAGKEYS(                         XK_5,                      4)
 | 
			
		||||
	TAGKEYS(                         XK_6,                      5)
 | 
			
		||||
	TAGKEYS(                         XK_7,                      6)
 | 
			
		||||
	TAGKEYS(                         XK_8,                      7)
 | 
			
		||||
	TAGKEYS(                         XK_9,                      8)
 | 
			
		||||
	// Kill dwm (super + shift + alt + q)
 | 
			
		||||
	{ MODKEY|ShiftMask|Mod1Mask,             XK_c,      quit,           {0} },
 | 
			
		||||
	{1, {{MODKEY|ShiftMask|Mod1Mask,       XK_q}},      quit,           {0} },
 | 
			
		||||
	/* ---------------------------------- Control Keys ---------------------------------- */
 | 
			
		||||
	// Brightness controllers (requires xbacklight)
 | 
			
		||||
	{ 0,                            XF86XK_MonBrightnessUp,   spawn, SHCMD("xbacklight -inc 5") },
 | 
			
		||||
	{ 0,                            XF86XK_MonBrightnessDown, spawn, SHCMD("xbacklight -dec 5") },
 | 
			
		||||
	{1, {{0,                               XF86XK_MonBrightnessUp}},   spawn, SHCMD("xbacklight -inc 5") },
 | 
			
		||||
	{1, {{0,                               XF86XK_MonBrightnessDown}}, spawn, SHCMD("xbacklight -dec 5") },
 | 
			
		||||
	// Sound controllers (requires pamixer)
 | 
			
		||||
	{ 0,                            XF86XK_AudioRaiseVolume, spawn, SHCMD("pamixer --allow-boost -i 4") },
 | 
			
		||||
	{ 0,                            XF86XK_AudioLowerVolume, spawn, SHCMD("pamixer --allow-boost -d 4") },
 | 
			
		||||
	{ 0,                            XF86XK_AudioMute,        spawn, SHCMD("pamixer -t") },
 | 
			
		||||
	{1, {{0,                               XF86XK_AudioRaiseVolume}}, spawn, SHCMD("pamixer --allow-boost -i 4") },
 | 
			
		||||
	{1, {{0,                               XF86XK_AudioLowerVolume}}, spawn, SHCMD("pamixer --allow-boost -d 4") },
 | 
			
		||||
	{1, {{0,                               XF86XK_AudioMute}},        spawn, SHCMD("pamixer -t") },
 | 
			
		||||
	// Media controls (requires playerctl)
 | 
			
		||||
	{ 0,                            XF86XK_AudioPlay,	 spawn,	SHCMD("playerctl play-pause") },
 | 
			
		||||
	{ 0,                            XF86XK_AudioStop,        spawn, SHCMD("playerctl stop") },
 | 
			
		||||
	{ 0,                            XF86XK_AudioNext,	 spawn,	SHCMD("playerctl next") },
 | 
			
		||||
	{ 0,                            XF86XK_AudioPrev,	 spawn,	SHCMD("playerctl previous")  },
 | 
			
		||||
	{1, {{0,                               XF86XK_AudioPlay}},	 spawn,	SHCMD("playerctl play-pause") },
 | 
			
		||||
	{1, {{0,                               XF86XK_AudioStop}},       spawn, SHCMD("playerctl stop") },
 | 
			
		||||
	{1, {{0,                               XF86XK_AudioNext}},	 spawn,	SHCMD("playerctl next") },
 | 
			
		||||
	{1, {{0,                               XF86XK_AudioPrev}},	 spawn,	SHCMD("playerctl previous")  },
 | 
			
		||||
        // Mute and unmute mic
 | 
			
		||||
	{ 0,			        XF86XK_AudioMicMute,	spawn, SHCMD("pactl set-source-mute @DEFAULT_SOURCE@ toggle") },
 | 
			
		||||
	{1, {{0,			       XF86XK_AudioMicMute}},	spawn, SHCMD("pactl set-source-mute @DEFAULT_SOURCE@ toggle") },
 | 
			
		||||
	// Take a screenshot
 | 
			
		||||
	{ 0,			        XK_Print,		spawn, SHCMD(SCREENSHOT) },
 | 
			
		||||
	{1, {{0,			       XK_Print}},		spawn, SHCMD(SCREENSHOT) },
 | 
			
		||||
	/* ---------------------------------- lock Keys ---------------------------------- */
 | 
			
		||||
	// Lock the screen
 | 
			
		||||
	{ MODKEY|ShiftMask,    	        XK_x,     spawn,          SHCMD("betterlockscreen -l dim") },
 | 
			
		||||
	{1, {{MODKEY|ShiftMask,    	       XK_x}},     spawn,          SHCMD("betterlockscreen -l dim") },
 | 
			
		||||
	// Plasma screen lock (super + ctrl + shift + x)
 | 
			
		||||
	{ MODKEY|ShiftMask|ControlMask, XK_x,     spawn,          SHCMD("qdbus-qt5 org.kde.ksmserver /KSMServer org.kde.KSMServerInterface.logout -1 -1 -1") }
 | 
			
		||||
	{1, {{MODKEY|ShiftMask|ControlMask,    XK_x}},     spawn,          SHCMD("qdbus-qt5 org.kde.ksmserver /KSMServer org.kde.KSMServerInterface.logout -1 -1 -1") }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* button definitions */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										67
									
								
								dwm.c
									
										
									
									
									
								
							
							
						
						
									
										67
									
								
								dwm.c
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -117,9 +117,14 @@ struct Client {
 | 
			
		|||
typedef struct {
 | 
			
		||||
	unsigned int mod;
 | 
			
		||||
	KeySym keysym;
 | 
			
		||||
} Key;
 | 
			
		||||
 | 
			
		||||
typedef struct {
 | 
			
		||||
	unsigned int n;
 | 
			
		||||
	const Key keys[5];
 | 
			
		||||
	void (*func)(const Arg *);
 | 
			
		||||
	const Arg arg;
 | 
			
		||||
} Key;
 | 
			
		||||
} Keychord;
 | 
			
		||||
 | 
			
		||||
typedef struct {
 | 
			
		||||
	const char *symbol;
 | 
			
		||||
| 
						 | 
				
			
			@ -304,6 +309,7 @@ static Display *dpy;
 | 
			
		|||
static Drw *drw;
 | 
			
		||||
static Monitor *mons, *selmon;
 | 
			
		||||
static Window root, wmcheckwin;
 | 
			
		||||
unsigned int currentkey = 0;
 | 
			
		||||
 | 
			
		||||
/* configuration, allows nested code to access above variables */
 | 
			
		||||
#include "config.h"
 | 
			
		||||
| 
						 | 
				
			
			@ -1131,16 +1137,16 @@ grabkeys(void)
 | 
			
		|||
{
 | 
			
		||||
	updatenumlockmask();
 | 
			
		||||
	{
 | 
			
		||||
		unsigned int i, j;
 | 
			
		||||
		unsigned int i, k;
 | 
			
		||||
		unsigned int modifiers[] = { 0, LockMask, numlockmask, numlockmask|LockMask };
 | 
			
		||||
		KeyCode code;
 | 
			
		||||
 | 
			
		||||
		XUngrabKey(dpy, AnyKey, AnyModifier, root);
 | 
			
		||||
		for (i = 0; i < LENGTH(keys); i++)
 | 
			
		||||
			if ((code = XKeysymToKeycode(dpy, keys[i].keysym)))
 | 
			
		||||
				for (j = 0; j < LENGTH(modifiers); j++)
 | 
			
		||||
					XGrabKey(dpy, code, keys[i].mod | modifiers[j], root,
 | 
			
		||||
						True, GrabModeAsync, GrabModeAsync);
 | 
			
		||||
		for (i = 0; i < LENGTH(keychords); i++)
 | 
			
		||||
			if ((code = XKeysymToKeycode(dpy, keychords[i].keys[currentkey].keysym)))
 | 
			
		||||
				for (k = 0; k < LENGTH(modifiers); k++)
 | 
			
		||||
					XGrabKey(dpy, code, keychords[i].keys[currentkey].mod | modifiers[k], root,
 | 
			
		||||
							 True, GrabModeAsync, GrabModeAsync);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1166,17 +1172,48 @@ isuniquegeom(XineramaScreenInfo *unique, size_t n, XineramaScreenInfo *info)
 | 
			
		|||
void
 | 
			
		||||
keypress(XEvent *e)
 | 
			
		||||
{
 | 
			
		||||
	unsigned int i;
 | 
			
		||||
	XEvent event = *e;
 | 
			
		||||
	Keychord *keychord;
 | 
			
		||||
	unsigned int ran = 0;
 | 
			
		||||
	KeySym keysym;
 | 
			
		||||
	XKeyEvent *ev;
 | 
			
		||||
	Keychord *newoptions;
 | 
			
		||||
	Keychord *oldoptions = (Keychord *)malloc(sizeof(keychords));
 | 
			
		||||
 | 
			
		||||
	ev = &e->xkey;
 | 
			
		||||
	keysym = XKeycodeToKeysym(dpy, (KeyCode)ev->keycode, 0);
 | 
			
		||||
	for (i = 0; i < LENGTH(keys); i++)
 | 
			
		||||
		if (keysym == keys[i].keysym
 | 
			
		||||
		&& CLEANMASK(keys[i].mod) == CLEANMASK(ev->state)
 | 
			
		||||
		&& keys[i].func)
 | 
			
		||||
			keys[i].func(&(keys[i].arg));
 | 
			
		||||
	memcpy(oldoptions, keychords, sizeof(keychords));
 | 
			
		||||
	size_t numoption = 0;
 | 
			
		||||
	while(!ran){
 | 
			
		||||
		ev = &event.xkey;
 | 
			
		||||
		keysym = XKeycodeToKeysym(dpy, (KeyCode)ev->keycode, 0);
 | 
			
		||||
		newoptions = (Keychord *)malloc(0);
 | 
			
		||||
		numoption = 0;
 | 
			
		||||
		for (keychord = oldoptions; keychord->n != 0 && currentkey < 5; keychord = (Keychord *)((char *)keychord + sizeof(Keychord))){
 | 
			
		||||
			if(keysym == keychord->keys[currentkey].keysym
 | 
			
		||||
			   && CLEANMASK(keychord->keys[currentkey].mod) == CLEANMASK(ev->state)
 | 
			
		||||
			   && keychord->func){
 | 
			
		||||
				if(keychord->n == currentkey +1){
 | 
			
		||||
					keychord->func(&(keychord->arg));
 | 
			
		||||
					ran = 1;
 | 
			
		||||
				}else{
 | 
			
		||||
					numoption++;
 | 
			
		||||
					newoptions = (Keychord *)realloc(newoptions, numoption * sizeof(Keychord));
 | 
			
		||||
					memcpy((char *)newoptions + (numoption -1) * sizeof(Keychord),keychord, sizeof(Keychord));
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		currentkey++;
 | 
			
		||||
		if(numoption == 0)
 | 
			
		||||
			break;
 | 
			
		||||
		grabkeys();
 | 
			
		||||
		while (running && !XNextEvent(dpy, &event) && !ran)
 | 
			
		||||
			if(event.type == KeyPress)
 | 
			
		||||
				break;
 | 
			
		||||
		free(oldoptions);
 | 
			
		||||
		oldoptions = newoptions;
 | 
			
		||||
	}
 | 
			
		||||
	free(newoptions);
 | 
			
		||||
	currentkey = 0;
 | 
			
		||||
	grabkeys();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										2609
									
								
								dwm.c.orig
									
										
									
									
									
								
							
							
						
						
									
										2609
									
								
								dwm.c.orig
									
										
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							
							
								
								
									
										217
									
								
								patches/dwm-keychord-20211210-a786211.diff
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										217
									
								
								patches/dwm-keychord-20211210-a786211.diff
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,217 @@
 | 
			
		|||
From e61a957ff8b7e14219b5fbaab9da794b722e7874 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Hai Nguyen <hhai2105@gmail.com>
 | 
			
		||||
Date: Fri, 10 Dec 2021 21:45:00 -0500
 | 
			
		||||
Subject: [PATCH] add Keychord struct, change keypress() and grabkeys() to be
 | 
			
		||||
 able to grab a sequence of keystroke
 | 
			
		||||
 | 
			
		||||
---
 | 
			
		||||
 config.def.h | 67 ++++++++++++++++++++++++++------------------------
 | 
			
		||||
 dwm.c        | 69 ++++++++++++++++++++++++++++++++++++++++------------
 | 
			
		||||
 2 files changed, 88 insertions(+), 48 deletions(-)
 | 
			
		||||
 | 
			
		||||
diff --git a/config.def.h b/config.def.h
 | 
			
		||||
index a2ac963..15a3e05 100644
 | 
			
		||||
--- a/config.def.h
 | 
			
		||||
+++ b/config.def.h
 | 
			
		||||
@@ -46,11 +46,12 @@ static const Layout layouts[] = {
 | 
			
		||||
 
 | 
			
		||||
 /* key definitions */
 | 
			
		||||
 #define MODKEY Mod1Mask
 | 
			
		||||
-#define TAGKEYS(KEY,TAG) \
 | 
			
		||||
-	{ MODKEY,                       KEY,      view,           {.ui = 1 << TAG} }, \
 | 
			
		||||
-	{ MODKEY|ControlMask,           KEY,      toggleview,     {.ui = 1 << TAG} }, \
 | 
			
		||||
-	{ MODKEY|ShiftMask,             KEY,      tag,            {.ui = 1 << TAG} }, \
 | 
			
		||||
-	{ MODKEY|ControlMask|ShiftMask, KEY,      toggletag,      {.ui = 1 << TAG} },
 | 
			
		||||
+
 | 
			
		||||
+#define TAGKEYS(KEY,TAG)												\
 | 
			
		||||
+	{1, {{MODKEY, KEY}},								view,           {.ui = 1 << TAG} },	\
 | 
			
		||||
+	{1, {{MODKEY|ControlMask, KEY}},					toggleview,     {.ui = 1 << TAG} }, \
 | 
			
		||||
+	{1, {{MODKEY|ShiftMask, KEY}},						tag,            {.ui = 1 << TAG} }, \
 | 
			
		||||
+	{1, {{MODKEY|ControlMask|ShiftMask, KEY}},			toggletag,      {.ui = 1 << TAG} },
 | 
			
		||||
 
 | 
			
		||||
 /* helper for spawning shell commands in the pre dwm-5.0 fashion */
 | 
			
		||||
 #define SHCMD(cmd) { .v = (const char*[]){ "/bin/sh", "-c", cmd, NULL } }
 | 
			
		||||
@@ -59,32 +60,34 @@ static const Layout layouts[] = {
 | 
			
		||||
 static char dmenumon[2] = "0"; /* component of dmenucmd, manipulated in spawn() */
 | 
			
		||||
 static const char *dmenucmd[] = { "dmenu_run", "-m", dmenumon, "-fn", dmenufont, "-nb", col_gray1, "-nf", col_gray3, "-sb", col_cyan, "-sf", col_gray4, NULL };
 | 
			
		||||
 static const char *termcmd[]  = { "st", NULL };
 | 
			
		||||
+static const char *emacs[]  = { "emacs", NULL };
 | 
			
		||||
 
 | 
			
		||||
-static Key keys[] = {
 | 
			
		||||
-	/* modifier                     key        function        argument */
 | 
			
		||||
-	{ MODKEY,                       XK_p,      spawn,          {.v = dmenucmd } },
 | 
			
		||||
-	{ MODKEY|ShiftMask,             XK_Return, spawn,          {.v = termcmd } },
 | 
			
		||||
-	{ MODKEY,                       XK_b,      togglebar,      {0} },
 | 
			
		||||
-	{ MODKEY,                       XK_j,      focusstack,     {.i = +1 } },
 | 
			
		||||
-	{ MODKEY,                       XK_k,      focusstack,     {.i = -1 } },
 | 
			
		||||
-	{ MODKEY,                       XK_i,      incnmaster,     {.i = +1 } },
 | 
			
		||||
-	{ MODKEY,                       XK_d,      incnmaster,     {.i = -1 } },
 | 
			
		||||
-	{ MODKEY,                       XK_h,      setmfact,       {.f = -0.05} },
 | 
			
		||||
-	{ MODKEY,                       XK_l,      setmfact,       {.f = +0.05} },
 | 
			
		||||
-	{ MODKEY,                       XK_Return, zoom,           {0} },
 | 
			
		||||
-	{ MODKEY,                       XK_Tab,    view,           {0} },
 | 
			
		||||
-	{ MODKEY|ShiftMask,             XK_c,      killclient,     {0} },
 | 
			
		||||
-	{ MODKEY,                       XK_t,      setlayout,      {.v = &layouts[0]} },
 | 
			
		||||
-	{ MODKEY,                       XK_f,      setlayout,      {.v = &layouts[1]} },
 | 
			
		||||
-	{ MODKEY,                       XK_m,      setlayout,      {.v = &layouts[2]} },
 | 
			
		||||
-	{ MODKEY,                       XK_space,  setlayout,      {0} },
 | 
			
		||||
-	{ MODKEY|ShiftMask,             XK_space,  togglefloating, {0} },
 | 
			
		||||
-	{ MODKEY,                       XK_0,      view,           {.ui = ~0 } },
 | 
			
		||||
-	{ MODKEY|ShiftMask,             XK_0,      tag,            {.ui = ~0 } },
 | 
			
		||||
-	{ MODKEY,                       XK_comma,  focusmon,       {.i = -1 } },
 | 
			
		||||
-	{ MODKEY,                       XK_period, focusmon,       {.i = +1 } },
 | 
			
		||||
-	{ MODKEY|ShiftMask,             XK_comma,  tagmon,         {.i = -1 } },
 | 
			
		||||
-	{ MODKEY|ShiftMask,             XK_period, tagmon,         {.i = +1 } },
 | 
			
		||||
+static Keychord keychords[] = {
 | 
			
		||||
+	/* Keys        function        argument */
 | 
			
		||||
+	{1, {{MODKEY, XK_p}},							spawn,          {.v = dmenucmd } },
 | 
			
		||||
+	{1, {{MODKEY|ShiftMask, XK_Return}},			spawn,          {.v = termcmd } },
 | 
			
		||||
+	{2, {{MODKEY, XK_e}, {MODKEY, XK_e}},			spawn,          {.v = termcmd } },
 | 
			
		||||
+	{1, {{MODKEY, XK_b}},							togglebar,      {0} },
 | 
			
		||||
+	{1, {{MODKEY, XK_j}},							focusstack,     {.i = +1 } },
 | 
			
		||||
+	{1, {{MODKEY, XK_k}},							focusstack,     {.i = -1 } },
 | 
			
		||||
+	{1, {{MODKEY, XK_i}},							incnmaster,     {.i = +1 } },
 | 
			
		||||
+	{1, {{MODKEY, XK_d}},							incnmaster,     {.i = -1 } },
 | 
			
		||||
+	{1, {{MODKEY, XK_h}},							setmfact,       {.f = -0.05} },
 | 
			
		||||
+	{1, {{MODKEY, XK_l}},							setmfact,       {.f = +0.05} },
 | 
			
		||||
+	{1, {{MODKEY, XK_Return}},						zoom,           {0} },
 | 
			
		||||
+	{1, {{MODKEY, XK_Tab}},							view,           {0} },
 | 
			
		||||
+	{1, {{MODKEY|ShiftMask, XK_c}},					killclient,     {0} },
 | 
			
		||||
+	{1, {{MODKEY, XK_t}},							setlayout,      {.v = &layouts[0]} },
 | 
			
		||||
+	{1, {{MODKEY, XK_f}},							setlayout,      {.v = &layouts[1]} },
 | 
			
		||||
+	{1, {{MODKEY, XK_m}},							setlayout,      {.v = &layouts[2]} },
 | 
			
		||||
+	{1, {{MODKEY, XK_space}},						setlayout,      {0} },
 | 
			
		||||
+	{1, {{MODKEY|ShiftMask, XK_space}},				togglefloating, {0} },
 | 
			
		||||
+	{1, {{MODKEY, XK_0}},							view,           {.ui = ~0 } },
 | 
			
		||||
+	{1, {{MODKEY|ShiftMask, XK_0}},					tag,            {.ui = ~0 } },
 | 
			
		||||
+	{1, {{MODKEY, XK_comma}},						focusmon,       {.i = -1 } },
 | 
			
		||||
+	{1, {{MODKEY, XK_period}},						focusmon,       {.i = +1 } },
 | 
			
		||||
+	{1, {{MODKEY|ShiftMask, XK_comma}},				tagmon,         {.i = -1 } },
 | 
			
		||||
+	{1, {{MODKEY|ShiftMask, XK_period}},			tagmon,         {.i = +1 } },
 | 
			
		||||
 	TAGKEYS(                        XK_1,                      0)
 | 
			
		||||
 	TAGKEYS(                        XK_2,                      1)
 | 
			
		||||
 	TAGKEYS(                        XK_3,                      2)
 | 
			
		||||
@@ -92,9 +95,9 @@ static Key keys[] = {
 | 
			
		||||
 	TAGKEYS(                        XK_5,                      4)
 | 
			
		||||
 	TAGKEYS(                        XK_6,                      5)
 | 
			
		||||
 	TAGKEYS(                        XK_7,                      6)
 | 
			
		||||
-	TAGKEYS(                        XK_8,                      7)
 | 
			
		||||
+	 TAGKEYS(                        XK_8,                      7)
 | 
			
		||||
 	TAGKEYS(                        XK_9,                      8)
 | 
			
		||||
-	{ MODKEY|ShiftMask,             XK_q,      quit,           {0} },
 | 
			
		||||
+	{1, {{MODKEY|ShiftMask, XK_q}},					quit,           {0} },
 | 
			
		||||
 };
 | 
			
		||||
 
 | 
			
		||||
 /* button definitions */
 | 
			
		||||
diff --git a/dwm.c b/dwm.c
 | 
			
		||||
index 5e4d494..56c4661 100644
 | 
			
		||||
--- a/dwm.c
 | 
			
		||||
+++ b/dwm.c
 | 
			
		||||
@@ -102,9 +102,14 @@ struct Client {
 | 
			
		||||
 typedef struct {
 | 
			
		||||
 	unsigned int mod;
 | 
			
		||||
 	KeySym keysym;
 | 
			
		||||
+} Key;
 | 
			
		||||
+
 | 
			
		||||
+typedef struct {
 | 
			
		||||
+	unsigned int n;
 | 
			
		||||
+	const Key keys[5];
 | 
			
		||||
 	void (*func)(const Arg *);
 | 
			
		||||
 	const Arg arg;
 | 
			
		||||
-} Key;
 | 
			
		||||
+} Keychord;
 | 
			
		||||
 
 | 
			
		||||
 typedef struct {
 | 
			
		||||
 	const char *symbol;
 | 
			
		||||
@@ -268,6 +273,7 @@ static Display *dpy;
 | 
			
		||||
 static Drw *drw;
 | 
			
		||||
 static Monitor *mons, *selmon;
 | 
			
		||||
 static Window root, wmcheckwin;
 | 
			
		||||
+unsigned int currentkey = 0;
 | 
			
		||||
 
 | 
			
		||||
 /* configuration, allows nested code to access above variables */
 | 
			
		||||
 #include "config.h"
 | 
			
		||||
@@ -951,16 +957,16 @@ grabkeys(void)
 | 
			
		||||
 {
 | 
			
		||||
 	updatenumlockmask();
 | 
			
		||||
 	{
 | 
			
		||||
-		unsigned int i, j;
 | 
			
		||||
+		unsigned int i, k;
 | 
			
		||||
 		unsigned int modifiers[] = { 0, LockMask, numlockmask, numlockmask|LockMask };
 | 
			
		||||
 		KeyCode code;
 | 
			
		||||
 
 | 
			
		||||
 		XUngrabKey(dpy, AnyKey, AnyModifier, root);
 | 
			
		||||
-		for (i = 0; i < LENGTH(keys); i++)
 | 
			
		||||
-			if ((code = XKeysymToKeycode(dpy, keys[i].keysym)))
 | 
			
		||||
-				for (j = 0; j < LENGTH(modifiers); j++)
 | 
			
		||||
-					XGrabKey(dpy, code, keys[i].mod | modifiers[j], root,
 | 
			
		||||
-						True, GrabModeAsync, GrabModeAsync);
 | 
			
		||||
+		for (i = 0; i < LENGTH(keychords); i++)
 | 
			
		||||
+			if ((code = XKeysymToKeycode(dpy, keychords[i].keys[currentkey].keysym)))
 | 
			
		||||
+				for (k = 0; k < LENGTH(modifiers); k++)
 | 
			
		||||
+					XGrabKey(dpy, code, keychords[i].keys[currentkey].mod | modifiers[k], root,
 | 
			
		||||
+							 True, GrabModeAsync, GrabModeAsync);
 | 
			
		||||
 	}
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
@@ -986,17 +992,48 @@ isuniquegeom(XineramaScreenInfo *unique, size_t n, XineramaScreenInfo *info)
 | 
			
		||||
 void
 | 
			
		||||
 keypress(XEvent *e)
 | 
			
		||||
 {
 | 
			
		||||
-	unsigned int i;
 | 
			
		||||
+	XEvent event = *e;
 | 
			
		||||
+	Keychord *keychord;
 | 
			
		||||
+	unsigned int ran = 0;
 | 
			
		||||
 	KeySym keysym;
 | 
			
		||||
 	XKeyEvent *ev;
 | 
			
		||||
-
 | 
			
		||||
-	ev = &e->xkey;
 | 
			
		||||
-	keysym = XKeycodeToKeysym(dpy, (KeyCode)ev->keycode, 0);
 | 
			
		||||
-	for (i = 0; i < LENGTH(keys); i++)
 | 
			
		||||
-		if (keysym == keys[i].keysym
 | 
			
		||||
-		&& CLEANMASK(keys[i].mod) == CLEANMASK(ev->state)
 | 
			
		||||
-		&& keys[i].func)
 | 
			
		||||
-			keys[i].func(&(keys[i].arg));
 | 
			
		||||
+	Keychord *newoptions;
 | 
			
		||||
+	Keychord *oldoptions = (Keychord *)malloc(sizeof(keychords));
 | 
			
		||||
+
 | 
			
		||||
+	memcpy(oldoptions, keychords, sizeof(keychords));
 | 
			
		||||
+	size_t numoption = 0;
 | 
			
		||||
+	while(!ran){
 | 
			
		||||
+		ev = &event.xkey;
 | 
			
		||||
+		keysym = XKeycodeToKeysym(dpy, (KeyCode)ev->keycode, 0);
 | 
			
		||||
+		newoptions = (Keychord *)malloc(0);
 | 
			
		||||
+		numoption = 0;
 | 
			
		||||
+		for (keychord = oldoptions; keychord->n != 0 && currentkey < 5; keychord = (Keychord *)((char *)keychord + sizeof(Keychord))){
 | 
			
		||||
+			if(keysym == keychord->keys[currentkey].keysym
 | 
			
		||||
+			   && CLEANMASK(keychord->keys[currentkey].mod) == CLEANMASK(ev->state)
 | 
			
		||||
+			   && keychord->func){
 | 
			
		||||
+				if(keychord->n == currentkey +1){
 | 
			
		||||
+					keychord->func(&(keychord->arg));
 | 
			
		||||
+					ran = 1;
 | 
			
		||||
+				}else{
 | 
			
		||||
+					numoption++;
 | 
			
		||||
+					newoptions = (Keychord *)realloc(newoptions, numoption * sizeof(Keychord));
 | 
			
		||||
+					memcpy((char *)newoptions + (numoption -1) * sizeof(Keychord),keychord, sizeof(Keychord));
 | 
			
		||||
+				}
 | 
			
		||||
+			}
 | 
			
		||||
+		}
 | 
			
		||||
+		currentkey++;
 | 
			
		||||
+		if(numoption == 0)
 | 
			
		||||
+			break;
 | 
			
		||||
+		grabkeys();
 | 
			
		||||
+		while (running && !XNextEvent(dpy, &event) && !ran)
 | 
			
		||||
+			if(event.type == KeyPress)
 | 
			
		||||
+				break;
 | 
			
		||||
+		free(oldoptions);
 | 
			
		||||
+		oldoptions = newoptions;
 | 
			
		||||
+	}
 | 
			
		||||
+	free(newoptions);
 | 
			
		||||
+	currentkey = 0;
 | 
			
		||||
+	grabkeys();
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
 void
 | 
			
		||||
-- 
 | 
			
		||||
2.34.1
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue