mirror of
https://github.com/mintycube/dwm.git
synced 2024-10-22 14:05:45 +02:00
Adding xkb patch as per request #111
This commit is contained in:
parent
0c88a49e27
commit
ac737f9dfc
11
config.def.h
11
config.def.h
@ -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
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);
|
||||
|
67
patch/xkb.c
Normal file
67
patch/xkb.c
Normal file
@ -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;
|
||||
}
|
7
patch/xkb.h
Normal file
7
patch/xkb.h
Normal file
@ -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…
Reference in New Issue
Block a user