Introduction
Introduction Statistics Contact Development Disclaimer Help
dwm-6.1-xkb.diff - sites - public wiki contents of suckless.org
git clone git://git.suckless.org/sites
Log
Files
Refs
---
dwm-6.1-xkb.diff (8882B)
---
1 diff --git a/config.def.h b/config.def.h
2 index 875885b..780ff6f 100644
3 --- a/config.def.h
4 +++ b/config.def.h
5 @@ -21,9 +21,9 @@ static const Rule rules[] = {
6 * WM_CLASS(STRING) = instance, class
7 * WM_NAME(STRING) = title
8 */
9 - /* class instance title tags mask isfloating …
10 - { "Gimp", NULL, NULL, 0, True, …
11 - { "Firefox", NULL, NULL, 1 << 8, False, …
12 + /* class instance title tags mask isfloating …
13 + { "Gimp", NULL, NULL, 0, True, …
14 + { "Firefox", NULL, NULL, 1 << 8, False, …
15 };
16
17 /* layout(s) */
18 @@ -31,6 +31,13 @@ static const float mfact = 0.55; /* factor of ma…
19 static const int nmaster = 1; /* number of clients in master ar…
20 static const Bool resizehints = True; /* True means respect size hints …
21
22 +/* xkb frontend */
23 +static const Bool showxkb = True; /* False means no xkb layout …
24 +static const char *xkb_layouts [] = {
25 + "en",
26 + "ru",
27 +};
28 +
29 static const Layout layouts[] = {
30 /* symbol arrange function */
31 { "[]=", tile }, /* first entry is default */
32 diff --git a/dwm.c b/dwm.c
33 index 1bbb4b3..ec39eef 100644
34 --- a/dwm.c
35 +++ b/dwm.c
36 @@ -36,6 +36,7 @@
37 #include <X11/Xlib.h>
38 #include <X11/Xproto.h>
39 #include <X11/Xutil.h>
40 +#include <X11/XKBlib.h>
41 #ifdef XINERAMA
42 #include <X11/extensions/Xinerama.h>
43 #endif /* XINERAMA */
44 @@ -83,6 +84,7 @@ typedef struct {
45
46 typedef struct Monitor Monitor;
47 typedef struct Client Client;
48 +typedef struct XkbInfo XkbInfo;
49 struct Client {
50 char name[256];
51 float mina, maxa;
52 @@ -96,6 +98,13 @@ struct Client {
53 Client *snext;
54 Monitor *mon;
55 Window win;
56 + XkbInfo *xkb;
57 +};
58 +struct XkbInfo {
59 + XkbInfo *next;
60 + XkbInfo *prev;
61 + int group;
62 + Window w;
63 };
64
65 typedef struct {
66 @@ -138,6 +147,7 @@ typedef struct {
67 unsigned int tags;
68 Bool isfloating;
69 int monitor;
70 + int xkb_layout;
71 } Rule;
72
73 /* function declarations */
74 @@ -157,6 +167,7 @@ static void configure(Client *c);
75 static void configurenotify(XEvent *e);
76 static void configurerequest(XEvent *e);
77 static Monitor *createmon(void);
78 +static XkbInfo *createxkb(Window w);
79 static void destroynotify(XEvent *e);
80 static void detach(Client *c);
81 static void detachstack(Client *c);
82 @@ -165,6 +176,7 @@ static void drawbar(Monitor *m);
83 static void drawbars(void);
84 static void enternotify(XEvent *e);
85 static void expose(XEvent *e);
86 +static XkbInfo *findxkb(Window w);
87 static void focus(Client *c);
88 static void focusin(XEvent *e);
89 static void focusmon(const Arg *arg);
90 @@ -231,6 +243,7 @@ static Monitor *wintomon(Window w);
91 static int xerror(Display *dpy, XErrorEvent *ee);
92 static int xerrordummy(Display *dpy, XErrorEvent *ee);
93 static int xerrorstart(Display *dpy, XErrorEvent *ee);
94 +static void xkbeventnotify(XEvent *e);
95 static void zoom(const Arg *arg);
96
97 /* variables */
98 @@ -241,6 +254,7 @@ static int sw, sh; /* X display screen geo…
99 static int bh, blw = 0; /* bar geometry */
100 static int (*xerrorxlib)(Display *, XErrorEvent *);
101 static unsigned int numlockmask = 0;
102 +static int xkbEventType = 0;
103 static void (*handler[LASTEvent]) (XEvent *) = {
104 [ButtonPress] = buttonpress,
105 [ClientMessage] = clientmessage,
106 @@ -266,6 +280,8 @@ static Drw *drw;
107 static Fnt *fnt;
108 static Monitor *mons, *selmon;
109 static Window root;
110 +static XkbInfo xkbGlobal;
111 +static XkbInfo *xkbSaved = NULL;
112
113 /* configuration, allows nested code to access above variables */
114 #include "config.h"
115 @@ -299,6 +315,9 @@ applyrules(Client *c) {
116 for(m = mons; m && m->num != r->monitor; m = m-…
117 if(m)
118 c->mon = m;
119 + if(r->xkb_layout > -1 ) {
120 + c->xkb->group = r->xkb_layout;
121 + }
122 }
123 }
124 if(ch.res_class)
125 @@ -644,6 +663,25 @@ createmon(void) {
126 strncpy(m->ltsymbol, layouts[0].symbol, sizeof m->ltsymbol);
127 return m;
128 }
129 +static XkbInfo *
130 +createxkb(Window w){
131 + XkbInfo *xkb;
132 +
133 + xkb = malloc(sizeof *xkb);
134 + if (xkb == NULL) {
135 + die("fatal: could not malloc() %u bytes\n", sizeof *xkb);
136 + }
137 + xkb->group = xkbGlobal.group;
138 + xkb->w = w;
139 + xkb->next = xkbSaved;
140 + if (xkbSaved != NULL) {
141 + xkbSaved->prev = xkb;
142 + }
143 + xkb->prev = NULL;
144 + xkbSaved = xkb;
145 +
146 + return xkb;
147 +}
148
149 void
150 destroynotify(XEvent *e) {
151 @@ -693,6 +731,7 @@ dirtomon(int dir) {
152 void
153 drawbar(Monitor *m) {
154 int x, xx, w;
155 + int ww = 0;
156 unsigned int i, occ = 0, urg = 0;
157 Client *c;
158
159 @@ -718,14 +757,23 @@ drawbar(Monitor *m) {
160 if(m == selmon) { /* status is only drawn on selected monitor */
161 w = TEXTW(stext);
162 x = m->ww - w;
163 + if (showxkb) {
164 + ww = TEXTW(xkb_layouts[xkbGlobal.group]);
165 + x -= ww;
166 + }
167 if(x < xx) {
168 x = xx;
169 w = m->ww - xx;
170 }
171 drw_text(drw, x, 0, w, bh, stext, 0);
172 + if (showxkb) {
173 + drw_setscheme(drw, &scheme[SchemeNorm]);
174 + drw_text(drw, x+w, 0, ww, bh, xkb_layouts[xkbGlobal.group],…
175 + }
176 }
177 else
178 x = m->ww;
179 +
180 if((w = x - xx) > bh) {
181 x = xx;
182 if(m->sel) {
183 @@ -777,6 +825,18 @@ expose(XEvent *e) {
184 drawbar(m);
185 }
186
187 +XkbInfo *
188 +findxkb(Window w)
189 +{
190 + XkbInfo *xkb;
191 + for (xkb = xkbSaved; xkb != NULL; xkb=xkb->next) {
192 + if (xkb->w == w) {
193 + return xkb;
194 + }
195 + }
196 + return NULL;
197 +}
198 +
199 void
200 focus(Client *c) {
201 if(!c || !ISVISIBLE(c))
202 @@ -1008,11 +1068,20 @@ manage(Window w, XWindowAttributes *wa) {
203 Client *c, *t = NULL;
204 Window trans = None;
205 XWindowChanges wc;
206 + XkbInfo *xkb;
207
208 if(!(c = calloc(1, sizeof(Client))))
209 die("fatal: could not malloc() %u bytes\n", sizeof(Clie…
210 c->win = w;
211 updatetitle(c);
212 +
213 + /* Setting current xkb state must be before applyrules */
214 + xkb = findxkb(c->win);
215 + if (xkb == NULL) {
216 + xkb = createxkb(c->win);
217 + }
218 + c->xkb = xkb;
219 +
220 if(XGetTransientForHint(dpy, w, &trans) && (t = wintoclient(tra…
221 c->mon = t->mon;
222 c->tags = t->tags;
223 @@ -1344,8 +1413,14 @@ run(void) {
224 /* main event loop */
225 XSync(dpy, False);
226 while(running && !XNextEvent(dpy, &ev))
227 + {
228 + if(ev.type == xkbEventType) {
229 + xkbeventnotify(&ev);
230 + continue;
231 + }
232 if(handler[ev.type])
233 handler[ev.type](&ev); /* call handler */
234 + }
235 }
236
237 void
238 @@ -1428,6 +1503,7 @@ setfocus(Client *c) {
239 XChangeProperty(dpy, root, netatom[NetActiveWindow],
240 XA_WINDOW, 32, PropModeReplace,
241 (unsigned char *) &(c->win), 1);
242 + XkbLockGroup(dpy, XkbUseCoreKbd, c->xkb->group);
243 }
244 sendevent(c, wmatom[WMTakeFocus]);
245 }
246 @@ -1490,6 +1566,7 @@ setmfact(const Arg *arg) {
247 void
248 setup(void) {
249 XSetWindowAttributes wa;
250 + XkbStateRec xkbstate;
251
252 /* clean up any zombies immediately */
253 sigchld(0);
254 @@ -1541,6 +1618,16 @@ setup(void) {
255 |EnterWindowMask|LeaveWindowMask|StructureNotif…
256 XChangeWindowAttributes(dpy, root, CWEventMask|CWCursor, &wa);
257 XSelectInput(dpy, root, wa.event_mask);
258 +
259 + /* get xkb extension info, events and current state */
260 + if (!XkbQueryExtension(dpy, NULL, &xkbEventType, NULL, NULL, NULL))…
261 + fputs("warning: can not query xkb extension\n", stderr);
262 + }
263 + XkbSelectEventDetails(dpy, XkbUseCoreKbd, XkbStateNotify,
264 + XkbAllStateComponentsMask, XkbGroupStateMask);
265 + XkbGetState(dpy, XkbUseCoreKbd, &xkbstate);
266 + xkbGlobal.group = xkbstate.locked_group;
267 +
268 grabkeys();
269 focus(NULL);
270 }
271 @@ -1687,6 +1774,7 @@ void
272 unmanage(Client *c, Bool destroyed) {
273 Monitor *m = c->mon;
274 XWindowChanges wc;
275 + XkbInfo *xkb;
276
277 /* The server grab construct avoids race conditions. */
278 detach(c);
279 @@ -1702,6 +1790,18 @@ unmanage(Client *c, Bool destroyed) {
280 XSetErrorHandler(xerror);
281 XUngrabServer(dpy);
282 }
283 + else {
284 + xkb = findxkb(c->win);
285 + if (xkb != NULL) {
286 + if (xkb->prev) {
287 + xkb->prev->next = xkb->next;
288 + }
289 + if (xkb->next) {
290 + xkb->next->prev = xkb->prev;
291 + }
292 + free(xkb);
293 + }
294 + }
295 free(c);
296 focus(NULL);
297 updateclientlist();
298 @@ -2030,6 +2130,23 @@ xerrorstart(Display *dpy, XErrorEvent *ee) {
299 return -1;
300 }
301
302 +void xkbeventnotify(XEvent *e)
303 +{
304 + XkbEvent *ev;
305 +
306 + ev = (XkbEvent *) e;
307 + switch (ev->any.xkb_type) {
308 + case XkbStateNotify:
309 + xkbGlobal.group = ev->state.locked_group;
310 + if (selmon != NULL && selmon->sel != NULL) {
311 + selmon->sel->xkb->group = xkbGlobal.group;
312 + }
313 + if (showxkb) {
314 + drawbars();
315 + }
316 + break;
317 + }
318 +}
319 void
320 zoom(const Arg *arg) {
321 Client *c = selmon->sel;
You are viewing proxied material from suckless.org. The copyright of proxied material belongs to its original authors. Any comments or complaints in relation to proxied material should be directed to the original authors of the content concerned. Please see the disclaimer for more details.