Adding xkb patch as per request #111

pull/112/head
bakkeby 3 years ago
parent 0c88a49e27
commit ac737f9dfc

@ -483,6 +483,9 @@ static const BarRule barrules[] = {
#elif BAR_STATUS_PATCH
{ 'A', 0, BAR_ALIGN_RIGHT, width_status, draw_status, click_status, "status" },
#endif // BAR_STATUS2D_PATCH | BAR_STATUSCMD_PATCH
#if XKB_PATCH
{ 0, 0, BAR_ALIGN_RIGHT, width_xkb, draw_xkb, click_xkb, "xkb" },
#endif // XKB_PATCH
#if BAR_FLEXWINTITLE_PATCH
{ -1, 0, BAR_ALIGN_NONE, width_flexwintitle, draw_flexwintitle, click_flexwintitle, "flexwintitle" },
#elif BAR_TABGROUPS_PATCH
@ -660,6 +663,14 @@ static const Layout layouts[] = {
};
#endif // FLEXTILE_DELUXE_LAYOUT
#if XKB_PATCH
/* xkb frontend */
static const char *xkb_layouts[] = {
"en",
"ru",
};
#endif // XKB_PATCH
/* key definitions */
#define MODKEY Mod1Mask
#if COMBO_PATCH && SWAPTAGS_PATCH && TAGOTHERMONITOR_PATCH

87
dwm.c

@ -55,6 +55,10 @@
#include <pango/pango.h>
#endif // BAR_PANGO_PATCH
#if XKB_PATCH
#include <X11/XKBlib.h>
#endif // XKB_PATCH
#if SPAWNCMD_PATCH
#include <assert.h>
#include <libgen.h>
@ -217,6 +221,9 @@ enum {
ClkWinTitle,
ClkClientWin,
ClkRootWin,
#if XKB_PATCH
ClkXKB,
#endif // XKB_PATCH
ClkLast
}; /* clicks */
@ -303,6 +310,16 @@ typedef struct {
const Arg arg;
} Button;
#if XKB_PATCH
typedef struct XkbInfo XkbInfo;
struct XkbInfo {
XkbInfo *next;
XkbInfo *prev;
int group;
Window w;
};
#endif // XKB_PATCH
typedef struct Client Client;
struct Client {
char name[256];
@ -367,6 +384,9 @@ struct Client {
#if IPC_PATCH
ClientState prevstate;
#endif // IPC_PATCH
#if XKB_PATCH
XkbInfo *xkb;
#endif // XKB_PATCH
};
typedef struct {
@ -496,9 +516,16 @@ typedef struct {
const char *floatpos;
#endif // FLOATPOS_PATCH
int monitor;
#if XKB_PATCH
int xkb_layout;
#endif // XKB_PATCH
} Rule;
#if XKB_PATCH
#define RULE(...) { .monitor = -1, .xkb_layout = -1, ##__VA_ARGS__ },
#else
#define RULE(...) { .monitor = -1, ##__VA_ARGS__ },
#endif // XKB_PATCH
/* Cross patch compatibility rule macro helper macros */
#define FLOATING , .isfloating = 1
@ -688,6 +715,9 @@ static char rawestext[1024];
#endif // BAR_STATUS2D_PATCH | BAR_STATUSCMD_PATCH
#endif // BAR_EXTRASTATUS_PATCH
#if XKB_PATCH
static int xkbEventType = 0;
#endif // XKB_PATCH
static int screen;
static int sw, sh; /* X display screen geometry width, height */
static int bh; /* bar geometry */
@ -877,6 +907,10 @@ applyrules(Client *c)
}
}
#endif // SWITCHTAG_PATCH
#if XKB_PATCH
if (r->xkb_layout > -1)
c->xkb->group = r->xkb_layout;
#endif // XKB_PATCH
#if ONLY_ONE_RULE_MATCH_PATCH
break;
#endif // ONLY_ONE_RULE_MATCH_PATCH
@ -2246,6 +2280,13 @@ manage(Window w, XWindowAttributes *wa)
c->cfact = 1.0;
#endif // CFACTS_PATCH
updatetitle(c);
#if XKB_PATCH
/* Setting current xkb state must be before applyrules */
if (!(c->xkb = findxkb(c->win)))
c->xkb = createxkb(c->win);
#endif // XKB_PATCH
if (XGetTransientForHint(dpy, w, &trans) && (t = wintoclient(trans))) {
c->mon = t->mon;
c->tags = t->tags;
@ -3018,9 +3059,20 @@ run(void)
XEvent ev;
/* main event loop */
XSync(dpy, False);
while (running && !XNextEvent(dpy, &ev))
while (running && !XNextEvent(dpy, &ev)) {
#if XKB_PATCH
/* Unfortunately the xkbEventType is not constant hence it can't be part of the
* normal event handler below */
if (ev.type == xkbEventType) {
xkbeventnotify(&ev);
continue;
}
#endif // XKB_PATCH
if (handler[ev.type])
handler[ev.type](&ev); /* call handler */
}
}
#endif // IPC_PATCH
@ -3198,6 +3250,9 @@ setfocus(Client *c)
XChangeProperty(dpy, root, netatom[NetActiveWindow],
XA_WINDOW, 32, PropModeReplace,
(unsigned char *) &(c->win), 1);
#if XKB_PATCH
XkbLockGroup(dpy, XkbUseCoreKbd, c->xkb->group);
#endif // XKB_PATCH
}
#if BAR_SYSTRAY_PATCH
sendevent(c->win, wmatom[WMTakeFocus], NoEventMask, wmatom[WMTakeFocus], CurrentTime, 0, 0, 0);
@ -3381,6 +3436,9 @@ setup(void)
{
int i;
XSetWindowAttributes wa;
#if XKB_PATCH
XkbStateRec xkbstate;
#endif // XKB_PATCH
Atom utf8string;
/* clean up any zombies immediately */
@ -3553,6 +3611,17 @@ setup(void)
|LeaveWindowMask|StructureNotifyMask|PropertyChangeMask;
XChangeWindowAttributes(dpy, root, CWEventMask|CWCursor, &wa);
XSelectInput(dpy, root, wa.event_mask);
#if XKB_PATCH
/* 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;
#endif // XKB_PATCH
grabkeys();
focus(NULL);
#if IPC_PATCH
@ -4034,6 +4103,9 @@ unmanage(Client *c, int destroyed)
unsigned int switchtag = c->switchtag;
#endif // SWITCHTAG_PATCH
XWindowChanges wc;
#if XKB_PATCH
XkbInfo *xkb;
#endif // XKB_PATCH
#if SWALLOW_PATCH
if (c->swallowing) {
@ -4064,6 +4136,19 @@ unmanage(Client *c, int destroyed)
XSetErrorHandler(xerror);
XUngrabServer(dpy);
}
#if XKB_PATCH
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);
}
}
#endif // XKB_PATCH
free(c);
#if SWALLOW_PATCH
if (s)

@ -298,6 +298,9 @@
#if ZOOMSWAP_PATCH
#include "zoomswap.c"
#endif
#if XKB_PATCH
#include "xkb.c"
#endif
#if XRDB_PATCH && !BAR_VTCOLORS_PATCH
#include "xrdb.c"
#endif

@ -294,6 +294,9 @@
#if ZOOMSWAP_PATCH
#include "zoomswap.h"
#endif
#if XKB_PATCH
#include "xkb.h"
#endif
#if XRDB_PATCH && !BAR_VTCOLORS_PATCH
#include "xrdb.h"
#endif

@ -9,6 +9,15 @@ handlexevent(struct epoll_event *ev)
XEvent ev;
while (running && XPending(dpy)) {
XNextEvent(dpy, &ev);
#if XKB_PATCH
/* Unfortunately the xkbEventType is not constant hence it can't be part of the
* normal event handler below */
if (ev.type == xkbEventType) {
xkbeventnotify(&ev);
continue;
}
#endif // XKB_PATCH
if (handler[ev.type]) {
handler[ev.type](&ev); /* call handler */
ipc_send_events(mons, &lastselmon, selmon);

@ -0,0 +1,67 @@
static XkbInfo xkbGlobal;
static XkbInfo *xkbSaved = NULL;
static XkbInfo *
createxkb(Window w)
{
XkbInfo *xkb;
xkb = malloc(sizeof *xkb);
if (xkb == NULL)
die("fatal: could not malloc() %u bytes\n", sizeof *xkb);
xkb->group = xkbGlobal.group;
xkb->w = w;
xkb->next = xkbSaved;
if (xkbSaved != NULL)
xkbSaved->prev = xkb;
xkb->prev = NULL;
xkbSaved = xkb;
return xkb;
}
XkbInfo *
findxkb(Window w)
{
XkbInfo *xkb;
for (xkb = xkbSaved; xkb != NULL; xkb = xkb->next)
if (xkb->w == w)
return xkb;
return NULL;
}
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;
drawbars();
break;
}
}
/* xkb bar module */
int
width_xkb(Bar *bar, BarArg *a)
{
return TEXTW(xkb_layouts[xkbGlobal.group]);
}
int
draw_xkb(Bar *bar, BarArg *a)
{
drw_text(drw, a->x, a->y, a->w, a->h, lrpad / 2, xkb_layouts[xkbGlobal.group], 0, False);
return 1;
}
int
click_xkb(Bar *bar, Arg *arg, BarArg *a)
{
return ClkXKB;
}

@ -0,0 +1,7 @@
static XkbInfo *createxkb(Window w);
static XkbInfo *findxkb(Window w);
static void xkbeventnotify(XEvent *e);
static int width_xkb(Bar *bar, BarArg *a);
static int draw_xkb(Bar *bar, BarArg *a);
static int click_xkb(Bar *bar, Arg *arg, BarArg *a);

@ -1105,6 +1105,13 @@
*/
#define WINVIEW_PATCH 0
/* Remember keyboard layout per client.
* It is recommended that you configure xkb before using this patch as described in
* https://www.x.org/archive/X11R7.5/doc/input/XKB-Config.html
* https://dwm.suckless.org/patches/xkb/
*/
#define XKB_PATCH 0
/* Allows dwm to read colors from xrdb (.Xresources) during runtime. Compatible with
* the float border color, awesomebar, urgentborder and titlecolor patches.
* https://dwm.suckless.org/patches/xrdb/

Loading…
Cancel
Save