Hi folks, Below is a diff of the modifications I made to make xvkbd play more nice with dwm and to make dwm more friendly, in general, to touchscreens. Basic mods:
1. Added ISPANEL (really should be ISKBD) definition which gets checked here and there, notably in focus() (so it don't steal focus) and focusstack() (so I can flip through my stack and pass over the xvkbd). 2. I added a couple tweaks to config.h to make the bar more friendly. Notably, I have the title do a focusstack and the - close the bar. (I'm on a 8" touchscreen so I don't want the bar open too often.) There's probably a better way to do this, but I wasn't clever enough to figure it out Any other tips and kind words of advice are welcome. Here's the diff (off of hg tip): diff -r 23b71491e149 config.mk --- a/config.mk Thu Dec 02 10:16:47 2010 +0000 +++ b/config.mk Mon Dec 20 16:31:34 2010 -0500 @@ -11,8 +11,8 @@ X11LIB = /usr/X11R6/lib # Xinerama -XINERAMALIBS = -L${X11LIB} -lXinerama -XINERAMAFLAGS = -DXINERAMA +#XINERAMALIBS = -L${X11LIB} -lXinerama +#XINERAMAFLAGS = -DXINERAMA # includes and libs INCS = -I. -I/usr/include -I${X11INC} diff -r 23b71491e149 dwm.c --- a/dwm.c Thu Dec 02 10:16:47 2010 +0000 +++ b/dwm.c Mon Dec 20 16:31:34 2010 -0500 @@ -53,6 +53,7 @@ #define HEIGHT(X) ((X)->h + 2 * (X)->bw) #define TAGMASK ((1 << LENGTH(tags)) - 1) #define TEXTW(X) (textnw(X, strlen(X)) + dc.font.height) +#define ISPANEL(x) (ISVISIBLE(x)&&(strcmp("xvkbd - Virtual Keyboard",x->name) == 0)) /* enums */ enum { CurNormal, CurResize, CurMove, CurLast }; /* cursor */ @@ -88,7 +89,7 @@ int basew, baseh, incw, inch, maxw, maxh, minw, minh; int bw, oldbw; unsigned int tags; - Bool isfixed, isfloating, isurgent, oldstate; + Bool isfixed, isfloating, isurgent, oldstate; Client *next; Client *snext; Monitor *mon; @@ -810,7 +811,7 @@ if(!c || !ISVISIBLE(c)) for(c = selmon->stack; c && !ISVISIBLE(c); c = c->snext); /* was if(selmon->sel) */ - if(selmon->sel && selmon->sel != c) + if(selmon->sel && selmon->sel != c && !ISPANEL(c)) unfocus(selmon->sel, False); if(c) { if(c->mon != selmon) @@ -820,13 +821,16 @@ detachstack(c); attachstack(c); grabbuttons(c, True); - XSetWindowBorder(dpy, c->win, dc.sel[ColBorder]); - XSetInputFocus(dpy, c->win, RevertToPointerRoot, CurrentTime); + if (!ISPANEL(c)) { + XSetWindowBorder(dpy, c->win, dc.sel[ColBorder]); + XSetInputFocus(dpy, c->win, RevertToPointerRoot, CurrentTime); + } } else XSetInputFocus(dpy, root, RevertToPointerRoot, CurrentTime); selmon->sel = c; - drawbars(); + if (!ISPANEL(c)) + drawbars(); } void @@ -857,17 +861,17 @@ if(!selmon->sel) return; if(arg->i > 0) { - for(c = selmon->sel->next; c && !ISVISIBLE(c); c = c->next); + for(c = selmon->sel->next; c && (!ISVISIBLE(c) || ISPANEL(c)); c = c->next); if(!c) - for(c = selmon->clients; c && !ISVISIBLE(c); c = c->next); + for(c = selmon->clients; c && (!ISVISIBLE(c) || ISPANEL(c)); c = c->next); } else { for(i = selmon->clients; i != selmon->sel; i = i->next) - if(ISVISIBLE(i)) + if(ISVISIBLE(i) && !ISPANEL(i)) c = i; if(!c) for(; i; i = i->next) - if(ISVISIBLE(i)) + if(ISVISIBLE(i) && !ISPANEL(i)) c = i; } if(c) { Here's my config.h: /* See LICENSE file for copyright and license details. */ /* appearance */ static const char font[] = "-*-terminus-medium-r-*-*-20-*-*-*-*-*-*-*"; static const char normbordercolor[] = "#cccccc"; static const char normbgcolor[] = "#cccccc"; static const char normfgcolor[] = "#000000"; static const char selbordercolor[] = "#0066ff"; static const char selbgcolor[] = "#0066ff"; static const char selfgcolor[] = "#ffffff"; static const unsigned int borderpx = 1; /* border pixel of windows */ static const unsigned int snap = 32; /* snap pixel */ static const Bool showbar = False; /* False means no bar */ static const Bool topbar = True; /* False means bottom bar */ /* tagging */ // xprop | awk -F '"' '/^WM_CLASS/ { printf("%s:%s:",$4,$2) }; /^WM_NAME/ { printf("%s\n",$2) }' static const char *tags[] = { "1", "2" }; static const Rule rules[] = { /* class instance title tags mask isfloating monitor */ { "Gimp", NULL, NULL, 0, True, -1 }, { NULL, NULL, "xvkbd - Virtual Keyboard", ~0, True, -1 }, // { "Firefox", NULL, NULL, 0, False, -1 }, // pjh }; /* layout(s) */ static const float mfact = 0.55; /* factor of master area size [0.05..0.95] */ static const Bool resizehints = False; /* True means respect size hints in tiled resizals */ 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 Mod2Mask // pjh was Mod1Mask #define MODKEY1 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 const char *dmenucmd[] = { "dwm-dmenu", "-fn", font, "-nb", normbgcolor, "-nf", normfgcolor, "-sb", selbgcolor, "-sf", selfgcolor, NULL }; // pjh static const char *termcmd[] = { "uxterm.sh", NULL }; static const char *vtcmd[] = { "chvt.sh", NULL }; // pjh static const char *cutcmd[] = { "cut.sh", NULL }; // pjh static const char *tmuxcmd[] = { "dwm-tmux.sh", NULL }; // pjh 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} }, { 0, XK_Super_L, togglebar, {0} }, { 0, XK_Super_R, focusstack, {.i = +1 } }, { MODKEY, XK_j, focusstack, {.i = +1 } }, { MODKEY, XK_k, focusstack, {.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 } }, 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} }, { MODKEY, XK_q, killclient, {0} }, // pjh { MODKEY1, XK_Up, focusstack, {.i = +1 } }, { MODKEY1, XK_Down, focusstack, {.i = -1 } }, { MODKEY, XK_Up, focusstack, {.i = +1 } }, // pjh { MODKEY, XK_Down, focusstack, {.i = -1 } }, // pjh //{ 0, XK_x, spawn, {.v = dmenucmd } }, // pjh { 0, XK_Pause, spawn, {.v = vtcmd } }, // pjh { MODKEY, XK_c, spawn, {.v = cutcmd } }, // pjh { 0, XK_Shift_R,spawn, {.v = dmenucmd } }, // pjh { MODKEY, XK_Left, setmfact, {.f = -0.05} }, // pjh { MODKEY, XK_Right, setmfact, {.f = +0.05} }, // pjh { MODKEY, XK_a, spawn, {.v = tmuxcmd } }, // pjh }; /* button definitions */ /* click can be ClkLtSymbol, ClkStatusText, ClkWinTitle, ClkClientWin, or ClkRootWin */ static Button buttons[] = { /* click event mask button function argument */ { ClkLtSymbol, 0, Button1, setlayout, {0} }, { ClkWinTitle, 0, Button1, focusstack, {.i = +1} }, { ClkStatusText, 0, Button1, togglebar, {0} }, { ClkClientWin, MODKEY, Button1, movemouse, {0} }, // { ClkClientWin, MODKEY1, Button1, focusstack, {.i = +1 } }, // pjh { 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} }, }; -- sic dicit magister P PhD Candidate Collaborative Programme in Ancient and Medieval Philosophy University of Toronto http://individual.utoronto.ca/peterjh