sites

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

commit 63b4c950ec21c895a48d805912bfd09930d5c806
parent a9b201c1ce529bf1931909b83ba773963cc1087d
Author: Shvedov Yury <shved@lvk.cs.msu.su>
Date:   Sat, 15 Feb 2014 14:30:15 +0400

add xkb patch

Diffstat:
Adwm.suckless.org/patches/dwm-6.1-xkb.diff | 272+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Adwm.suckless.org/patches/xkb.md | 24++++++++++++++++++++++++
2 files changed, 296 insertions(+), 0 deletions(-)

diff --git a/dwm.suckless.org/patches/dwm-6.1-xkb.diff b/dwm.suckless.org/patches/dwm-6.1-xkb.diff @@ -0,0 +1,272 @@ +Author: Yury Shvedov <shved@lvk.cs.msu.su> +URL: http://dwm.suckless.org/patches/xkb +Implements a xxkb-like behaviour. + +diff --git a/config.def.h b/config.def.h +index 875885b..2dd24c6 100644 +--- a/config.def.h ++++ b/config.def.h +@@ -31,6 +31,13 @@ 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 Bool resizehints = True; /* True means respect size hints in tiled resizals */ + ++/* xkb frontend */ ++static const Bool showxkb = True; /* False means no xkb layout text */ ++static const char *xkb_layouts [] = { ++ "en", ++ "ru", ++}; ++ + static const Layout layouts[] = { + /* symbol arrange function */ + { "[]=", tile }, /* first entry is default */ +diff --git a/dwm.c b/dwm.c +index 1bbb4b3..35bd4d7 100644 +--- a/dwm.c ++++ b/dwm.c +@@ -36,6 +36,7 @@ + #include <X11/Xlib.h> + #include <X11/Xproto.h> + #include <X11/Xutil.h> ++#include <X11/XKBlib.h> + #ifdef XINERAMA + #include <X11/extensions/Xinerama.h> + #endif /* XINERAMA */ +@@ -83,6 +84,7 @@ typedef struct { + + typedef struct Monitor Monitor; + typedef struct Client Client; ++typedef struct XkbInfo XkbInfo; + struct Client { + char name[256]; + float mina, maxa; +@@ -96,6 +98,13 @@ struct Client { + Client *snext; + Monitor *mon; + Window win; ++ XkbInfo *xkb; ++}; ++struct XkbInfo { ++ XkbInfo *next; ++ XkbInfo *prev; ++ int group; ++ Window w; + }; + + typedef struct { +@@ -165,6 +174,7 @@ static void drawbar(Monitor *m); + static void drawbars(void); + static void enternotify(XEvent *e); + static void expose(XEvent *e); ++static XkbInfo *findxkb(Window w); + static void focus(Client *c); + static void focusin(XEvent *e); + static void focusmon(const Arg *arg); +@@ -231,6 +241,7 @@ static Monitor *wintomon(Window w); + static int xerror(Display *dpy, XErrorEvent *ee); + static int xerrordummy(Display *dpy, XErrorEvent *ee); + static int xerrorstart(Display *dpy, XErrorEvent *ee); ++static void xkbeventnotify(XEvent *e); + static void zoom(const Arg *arg); + + /* variables */ +@@ -241,6 +252,7 @@ static int sw, sh; /* X display screen geometry width, height */ + static int bh, blw = 0; /* bar geometry */ + static int (*xerrorxlib)(Display *, XErrorEvent *); + static unsigned int numlockmask = 0; ++static int xkbEventType = 0; + static void (*handler[LASTEvent]) (XEvent *) = { + [ButtonPress] = buttonpress, + [ClientMessage] = clientmessage, +@@ -266,6 +278,8 @@ static Drw *drw; + static Fnt *fnt; + static Monitor *mons, *selmon; + static Window root; ++static XkbInfo xkbGlobal; ++static XkbInfo *xkbSaved = NULL; + + /* configuration, allows nested code to access above variables */ + #include "config.h" +@@ -693,6 +707,7 @@ dirtomon(int dir) { + void + drawbar(Monitor *m) { + int x, xx, w; ++ int ww = 0; + unsigned int i, occ = 0, urg = 0; + Client *c; + +@@ -718,14 +733,23 @@ drawbar(Monitor *m) { + if(m == selmon) { /* status is only drawn on selected monitor */ + w = TEXTW(stext); + x = m->ww - w; ++ if (showxkb) { ++ ww = TEXTW(xkb_layouts[xkbGlobal.group]); ++ x -= ww; ++ } + if(x < xx) { + x = xx; + w = m->ww - xx; + } + drw_text(drw, x, 0, w, bh, stext, 0); ++ if (showxkb) { ++ drw_setscheme(drw, &scheme[SchemeNorm]); ++ drw_text(drw, x+w, 0, ww, bh, xkb_layouts[xkbGlobal.group], 0); ++ } + } + else + x = m->ww; ++ + if((w = x - xx) > bh) { + x = xx; + if(m->sel) { +@@ -777,6 +801,18 @@ expose(XEvent *e) { + drawbar(m); + } + ++XkbInfo * ++findxkb(Window w) ++{ ++ XkbInfo *xkb; ++ for (xkb = xkbSaved; xkb != NULL; xkb=xkb->next) { ++ if (xkb->w == w) { ++ return xkb; ++ } ++ } ++ return NULL; ++} ++ + void + focus(Client *c) { + if(!c || !ISVISIBLE(c)) +@@ -1008,6 +1044,7 @@ manage(Window w, XWindowAttributes *wa) { + Client *c, *t = NULL; + Window trans = None; + XWindowChanges wc; ++ XkbInfo *xkb; + + if(!(c = calloc(1, sizeof(Client)))) + die("fatal: could not malloc() %u bytes\n", sizeof(Client)); +@@ -1038,6 +1075,24 @@ manage(Window w, XWindowAttributes *wa) { + && (c->x + (c->w / 2) < c->mon->wx + c->mon->ww)) ? bh : c->mon->my); + c->bw = borderpx; + ++ /* Set current xkb state */ ++ xkb = findxkb(c->win); ++ if (xkb == NULL) { ++ xkb = malloc(sizeof *xkb); ++ if (xkb == NULL) { ++ die("fatal: could not malloc() %u bytes\n", sizeof *xkb); ++ } ++ xkb->group = xkbGlobal.group; ++ xkb->w = c->win; ++ xkb->next = xkbSaved; ++ if (xkbSaved != NULL) { ++ xkbSaved->prev = xkb; ++ } ++ xkb->prev = NULL; ++ xkbSaved = xkb; ++ } ++ c->xkb = xkb; ++ + wc.border_width = c->bw; + XConfigureWindow(dpy, w, CWBorderWidth, &wc); + XSetWindowBorder(dpy, w, scheme[SchemeNorm].border->rgb); +@@ -1344,8 +1399,14 @@ run(void) { + /* main event loop */ + XSync(dpy, False); + while(running && !XNextEvent(dpy, &ev)) ++ { ++ if(ev.type == xkbEventType) { ++ xkbeventnotify(&ev); ++ continue; ++ } + if(handler[ev.type]) + handler[ev.type](&ev); /* call handler */ ++ } + } + + void +@@ -1428,6 +1489,7 @@ setfocus(Client *c) { + XChangeProperty(dpy, root, netatom[NetActiveWindow], + XA_WINDOW, 32, PropModeReplace, + (unsigned char *) &(c->win), 1); ++ XkbLockGroup(dpy, XkbUseCoreKbd, c->xkb->group); + } + sendevent(c, wmatom[WMTakeFocus]); + } +@@ -1490,6 +1552,7 @@ setmfact(const Arg *arg) { + void + setup(void) { + XSetWindowAttributes wa; ++ XkbStateRec xkbstate; + + /* clean up any zombies immediately */ + sigchld(0); +@@ -1541,6 +1604,16 @@ setup(void) { + |EnterWindowMask|LeaveWindowMask|StructureNotifyMask|PropertyChangeMask; + XChangeWindowAttributes(dpy, root, CWEventMask|CWCursor, &wa); + XSelectInput(dpy, root, wa.event_mask); ++ ++ /* get xkb extension info, events and current state */ ++ if (!XkbQueryExtension(dpy, NULL, &xkbEventType, NULL, NULL, NULL)) { ++ fputs("warning: can not query xkb extension\n", stderr); ++ } ++ XkbSelectEventDetails(dpy, XkbUseCoreKbd, XkbStateNotify, ++ XkbAllStateComponentsMask, XkbGroupStateMask); ++ XkbGetState(dpy, XkbUseCoreKbd, &xkbstate); ++ xkbGlobal.group = xkbstate.locked_group; ++ + grabkeys(); + focus(NULL); + } +@@ -1687,6 +1760,7 @@ void + unmanage(Client *c, Bool destroyed) { + Monitor *m = c->mon; + XWindowChanges wc; ++ XkbInfo *xkb; + + /* The server grab construct avoids race conditions. */ + detach(c); +@@ -1702,6 +1776,18 @@ unmanage(Client *c, Bool destroyed) { + XSetErrorHandler(xerror); + XUngrabServer(dpy); + } ++ else { ++ xkb = findxkb(c->win); ++ if (xkb != NULL) { ++ if (xkb->prev) { ++ xkb->prev->next = xkb->next; ++ } ++ if (xkb->next) { ++ xkb->next->prev = xkb->prev; ++ } ++ free(xkb); ++ } ++ } + free(c); + focus(NULL); + updateclientlist(); +@@ -2030,6 +2116,23 @@ xerrorstart(Display *dpy, XErrorEvent *ee) { + return -1; + } + ++void xkbeventnotify(XEvent *e) ++{ ++ XkbEvent *ev; ++ ++ ev = (XkbEvent *) e; ++ switch (ev->any.xkb_type) { ++ case XkbStateNotify: ++ xkbGlobal.group = ev->state.locked_group; ++ if (selmon != NULL && selmon->sel != NULL) { ++ selmon->sel->xkb->group = xkbGlobal.group; ++ } ++ if (showxkb) { ++ drawbars(); ++ } ++ break; ++ } ++} + void + zoom(const Arg *arg) { + Client *c = selmon->sel; diff --git a/dwm.suckless.org/patches/xkb.md b/dwm.suckless.org/patches/xkb.md @@ -0,0 +1,24 @@ +xkb +===== +Description +----------- +This patch replaces main functionality of xxkb. It will remember the +client's xkb status and restores it when client became focused. + +Applying +-------- +Firstly you have to configure xkb as you need as described here: +http://www.x.org/archive/X11R7.5/doc/input/XKB-Config.html +The patch depends on two variables: showxkb flag defines, should patch show +current xkb group on the bar; xkb_layouts array defines the text, which will +appear on the bar according to current group if showxkb set to TRUE. + +Download +-------- + + * [dwm-6.1-xkb.diff](dwm-6.1-xkb.diff) (2014-02-15) + +Author +------ + + * Yury Shvedov - shved at lvk dot cs dot msu dot su (or mestofel13 at gmail dot com).