key.c
changeset 73 c2ddb9dbbd10
child 74 5370ef170cc9
equal deleted inserted replaced
72:d0eb0bb63c40 73:c2ddb9dbbd10
       
     1 /*
       
     2  * (C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com>
       
     3  * See LICENSE file for license details.
       
     4  */
       
     5 
       
     6 #include <fcntl.h>
       
     7 #include <stdio.h>
       
     8 #include <stdlib.h>
       
     9 #include <string.h>
       
    10 #include <unistd.h>
       
    11 #include <X11/keysym.h>
       
    12 #include <X11/Xatom.h>
       
    13 
       
    14 #include "dwm.h"
       
    15 
       
    16 static void ckill(Arg *arg);
       
    17 static void nextc(Arg *arg);
       
    18 static void prevc(Arg *arg);
       
    19 static void max(Arg *arg);
       
    20 static void ttrunc(Arg *arg);
       
    21 static void tappend(Arg *arg);
       
    22 static void zoom(Arg *arg);
       
    23 
       
    24 /********** CUSTOMIZE **********/
       
    25 
       
    26 const char *term[] = { 
       
    27 	"urxvtc", "-tr", "+sb", "-bg", "black", "-fg", "white", "-fn",
       
    28 	"-*-terminus-medium-*-*-*-13-*-*-*-*-*-iso10646-*",NULL
       
    29 };
       
    30 const char *browse[] = { "firefox", NULL };
       
    31 const char *xlock[] = { "xlock", NULL };
       
    32 
       
    33 Key key[] = {
       
    34 	/* modifier				key			function	arguments */
       
    35 	{ Mod1Mask,				XK_Return,	zoom,		{ 0 } },
       
    36 	{ Mod1Mask,				XK_k,		prevc,		{ 0 } },
       
    37 	{ Mod1Mask,				XK_j,		nextc,		{ 0 } }, 
       
    38 	{ Mod1Mask,				XK_m,		max,		{ 0 } }, 
       
    39 	{ Mod1Mask,				XK_0,		view,		{ .i = Tscratch } }, 
       
    40 	{ Mod1Mask,				XK_1,		view,		{ .i = Tdev } }, 
       
    41 	{ Mod1Mask,				XK_2,		view,		{ .i = Twww } }, 
       
    42 	{ Mod1Mask,				XK_3,		view,		{ .i = Twork } }, 
       
    43 	{ Mod1Mask,				XK_space,	tiling,		{ 0 } }, 
       
    44 	{ Mod1Mask|ShiftMask,	XK_space,	floating,	{ 0 } }, 
       
    45 	{ Mod1Mask|ShiftMask,	XK_0,		ttrunc,		{ .i = Tscratch } }, 
       
    46 	{ Mod1Mask|ShiftMask,	XK_1,		ttrunc,		{ .i = Tdev } }, 
       
    47 	{ Mod1Mask|ShiftMask,	XK_2,		ttrunc,		{ .i = Twww } }, 
       
    48 	{ Mod1Mask|ShiftMask,	XK_3,		ttrunc,		{ .i = Twork } }, 
       
    49 	{ Mod1Mask|ShiftMask,	XK_c,		ckill,		{ 0 } }, 
       
    50 	{ Mod1Mask|ShiftMask,	XK_q,		quit,		{ 0 } },
       
    51 	{ Mod1Mask|ShiftMask,	XK_Return,	spawn,		{ .argv = term } },
       
    52 	{ Mod1Mask|ShiftMask,	XK_w,		spawn,		{ .argv = browse } },
       
    53 	{ Mod1Mask|ShiftMask,	XK_l,		spawn,		{ .argv = xlock } },
       
    54 	{ ControlMask,			XK_0,		tappend,	{ .i = Tscratch } }, 
       
    55 	{ ControlMask,			XK_1,		tappend,	{ .i = Tdev } }, 
       
    56 	{ ControlMask,			XK_2,		tappend,	{ .i = Twww } }, 
       
    57 	{ ControlMask,			XK_3,		tappend,	{ .i = Twork } }, 
       
    58 };
       
    59 
       
    60 /********** CUSTOMIZE **********/
       
    61 
       
    62 void
       
    63 grabkeys()
       
    64 {
       
    65 	static unsigned int len = key ? sizeof(key) / sizeof(key[0]) : 0;
       
    66 	unsigned int i;
       
    67 	KeyCode code;
       
    68 
       
    69 	for(i = 0; i < len; i++) {
       
    70 		code = XKeysymToKeycode(dpy, key[i].keysym);
       
    71 		XUngrabKey(dpy, code, key[i].mod, root);
       
    72 		XGrabKey(dpy, code, key[i].mod, root, True,
       
    73 				GrabModeAsync, GrabModeAsync);
       
    74 	}
       
    75 }
       
    76 
       
    77 void
       
    78 keypress(XEvent *e)
       
    79 {
       
    80 	XKeyEvent *ev = &e->xkey;
       
    81 	static unsigned int len = key ? sizeof(key) / sizeof(key[0]) : 0;
       
    82 	unsigned int i;
       
    83 	KeySym keysym;
       
    84 
       
    85 	keysym = XKeycodeToKeysym(dpy, (KeyCode)ev->keycode, 0);
       
    86 	for(i = 0; i < len; i++)
       
    87 		if((keysym == key[i].keysym) && (key[i].mod == ev->state)) {
       
    88 			if(key[i].func)
       
    89 				key[i].func(&key[i].arg);
       
    90 			return;
       
    91 		}
       
    92 }
       
    93 
       
    94 static void
       
    95 zoom(Arg *arg)
       
    96 {
       
    97 	Client **l, *c;
       
    98 
       
    99 	if(!sel)
       
   100 		return;
       
   101 
       
   102 	if(sel == next(clients) && sel->next)  {
       
   103 		if((c = next(sel->next)))
       
   104 			sel = c;
       
   105 	}
       
   106 
       
   107 	for(l = &clients; *l && *l != sel; l = &(*l)->next);
       
   108 	*l = sel->next;
       
   109 
       
   110 	sel->next = clients; /* pop */
       
   111 	clients = sel;
       
   112 	arrange(NULL);
       
   113 	focus(sel);
       
   114 }
       
   115 
       
   116 static void
       
   117 max(Arg *arg)
       
   118 {
       
   119 	if(!sel)
       
   120 		return;
       
   121 	sel->x = sx;
       
   122 	sel->y = sy + bh;
       
   123 	sel->w = sw - 2 * sel->border;
       
   124 	sel->h = sh - 2 * sel->border - bh;
       
   125 	craise(sel);
       
   126 	resize(sel, False);
       
   127 }
       
   128 
       
   129 static void
       
   130 tappend(Arg *arg)
       
   131 {
       
   132 	if(!sel)
       
   133 		return;
       
   134 
       
   135 	sel->tags[arg->i] = tags[arg->i];
       
   136 	arrange(NULL);
       
   137 }
       
   138 
       
   139 static void
       
   140 ttrunc(Arg *arg)
       
   141 {
       
   142 	int i;
       
   143 	if(!sel)
       
   144 		return;
       
   145 
       
   146 	for(i = 0; i < TLast; i++)
       
   147 		sel->tags[i] = NULL;
       
   148 	tappend(arg);
       
   149 }
       
   150 
       
   151 static void
       
   152 prevc(Arg *arg)
       
   153 {
       
   154 	Client *c;
       
   155 
       
   156 	if(!sel)
       
   157 		return;
       
   158 
       
   159 	if((c = sel->revert && sel->revert->tags[tsel] ? sel->revert : NULL)) {
       
   160 		craise(c);
       
   161 		focus(c);
       
   162 	}
       
   163 }
       
   164 
       
   165 static void
       
   166 nextc(Arg *arg)
       
   167 {
       
   168 	Client *c;
       
   169    
       
   170 	if(!sel)
       
   171 		return;
       
   172 
       
   173 	if(!(c = next(sel->next)))
       
   174 		c = next(clients);
       
   175 	if(c) {
       
   176 		craise(c);
       
   177 		c->revert = sel;
       
   178 		focus(c);
       
   179 	}
       
   180 }
       
   181 
       
   182 static void
       
   183 ckill(Arg *arg)
       
   184 {
       
   185 	if(!sel)
       
   186 		return;
       
   187 	if(sel->proto & WM_PROTOCOL_DELWIN)
       
   188 		send_message(sel->win, wm_atom[WMProtocols], wm_atom[WMDelete]);
       
   189 	else
       
   190 		XKillClient(dpy, sel->win);
       
   191 }
       
   192