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
|
#elif BAR_STATUS_PATCH
|
||||||
{ 'A', 0, BAR_ALIGN_RIGHT, width_status, draw_status, click_status, "status" },
|
{ 'A', 0, BAR_ALIGN_RIGHT, width_status, draw_status, click_status, "status" },
|
||||||
#endif // BAR_STATUS2D_PATCH | BAR_STATUSCMD_PATCH
|
#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
|
#if BAR_FLEXWINTITLE_PATCH
|
||||||
{ -1, 0, BAR_ALIGN_NONE, width_flexwintitle, draw_flexwintitle, click_flexwintitle, "flexwintitle" },
|
{ -1, 0, BAR_ALIGN_NONE, width_flexwintitle, draw_flexwintitle, click_flexwintitle, "flexwintitle" },
|
||||||
#elif BAR_TABGROUPS_PATCH
|
#elif BAR_TABGROUPS_PATCH
|
||||||
@ -660,6 +663,14 @@ static const Layout layouts[] = {
|
|||||||
};
|
};
|
||||||
#endif // FLEXTILE_DELUXE_LAYOUT
|
#endif // FLEXTILE_DELUXE_LAYOUT
|
||||||
|
|
||||||
|
#if XKB_PATCH
|
||||||
|
/* xkb frontend */
|
||||||
|
static const char *xkb_layouts[] = {
|
||||||
|
"en",
|
||||||
|
"ru",
|
||||||
|
};
|
||||||
|
#endif // XKB_PATCH
|
||||||
|
|
||||||
/* key definitions */
|
/* key definitions */
|
||||||
#define MODKEY Mod1Mask
|
#define MODKEY Mod1Mask
|
||||||
#if COMBO_PATCH && SWAPTAGS_PATCH && TAGOTHERMONITOR_PATCH
|
#if COMBO_PATCH && SWAPTAGS_PATCH && TAGOTHERMONITOR_PATCH
|
||||||
|
87
dwm.c
87
dwm.c
@ -55,6 +55,10 @@
|
|||||||
#include <pango/pango.h>
|
#include <pango/pango.h>
|
||||||
#endif // BAR_PANGO_PATCH
|
#endif // BAR_PANGO_PATCH
|
||||||
|
|
||||||
|
#if XKB_PATCH
|
||||||
|
#include <X11/XKBlib.h>
|
||||||
|
#endif // XKB_PATCH
|
||||||
|
|
||||||
#if SPAWNCMD_PATCH
|
#if SPAWNCMD_PATCH
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <libgen.h>
|
#include <libgen.h>
|
||||||
@ -217,6 +221,9 @@ enum {
|
|||||||
ClkWinTitle,
|
ClkWinTitle,
|
||||||
ClkClientWin,
|
ClkClientWin,
|
||||||
ClkRootWin,
|
ClkRootWin,
|
||||||
|
#if XKB_PATCH
|
||||||
|
ClkXKB,
|
||||||
|
#endif // XKB_PATCH
|
||||||
ClkLast
|
ClkLast
|
||||||
}; /* clicks */
|
}; /* clicks */
|
||||||
|
|
||||||
@ -303,6 +310,16 @@ typedef struct {
|
|||||||
const Arg arg;
|
const Arg arg;
|
||||||
} Button;
|
} 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;
|
typedef struct Client Client;
|
||||||
struct Client {
|
struct Client {
|
||||||
char name[256];
|
char name[256];
|
||||||
@ -367,6 +384,9 @@ struct Client {
|
|||||||
#if IPC_PATCH
|
#if IPC_PATCH
|
||||||
ClientState prevstate;
|
ClientState prevstate;
|
||||||
#endif // IPC_PATCH
|
#endif // IPC_PATCH
|
||||||
|
#if XKB_PATCH
|
||||||
|
XkbInfo *xkb;
|
||||||
|
#endif // XKB_PATCH
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@ -496,9 +516,16 @@ typedef struct {
|
|||||||
const char *floatpos;
|
const char *floatpos;
|
||||||
#endif // FLOATPOS_PATCH
|
#endif // FLOATPOS_PATCH
|
||||||
int monitor;
|
int monitor;
|
||||||
|
#if XKB_PATCH
|
||||||
|
int xkb_layout;
|
||||||
|
#endif // XKB_PATCH
|
||||||
} Rule;
|
} Rule;
|
||||||
|
|
||||||
|
#if XKB_PATCH
|
||||||
|
#define RULE(...) { .monitor = -1, .xkb_layout = -1, ##__VA_ARGS__ },
|
||||||
|
#else
|
||||||
#define RULE(...) { .monitor = -1, ##__VA_ARGS__ },
|
#define RULE(...) { .monitor = -1, ##__VA_ARGS__ },
|
||||||
|
#endif // XKB_PATCH
|
||||||
|
|
||||||
/* Cross patch compatibility rule macro helper macros */
|
/* Cross patch compatibility rule macro helper macros */
|
||||||
#define FLOATING , .isfloating = 1
|
#define FLOATING , .isfloating = 1
|
||||||
@ -688,6 +715,9 @@ static char rawestext[1024];
|
|||||||
#endif // BAR_STATUS2D_PATCH | BAR_STATUSCMD_PATCH
|
#endif // BAR_STATUS2D_PATCH | BAR_STATUSCMD_PATCH
|
||||||
#endif // BAR_EXTRASTATUS_PATCH
|
#endif // BAR_EXTRASTATUS_PATCH
|
||||||
|
|
||||||
|
#if XKB_PATCH
|
||||||
|
static int xkbEventType = 0;
|
||||||
|
#endif // XKB_PATCH
|
||||||
static int screen;
|
static int screen;
|
||||||
static int sw, sh; /* X display screen geometry width, height */
|
static int sw, sh; /* X display screen geometry width, height */
|
||||||
static int bh; /* bar geometry */
|
static int bh; /* bar geometry */
|
||||||
@ -877,6 +907,10 @@ applyrules(Client *c)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif // SWITCHTAG_PATCH
|
#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
|
#if ONLY_ONE_RULE_MATCH_PATCH
|
||||||
break;
|
break;
|
||||||
#endif // ONLY_ONE_RULE_MATCH_PATCH
|
#endif // ONLY_ONE_RULE_MATCH_PATCH
|
||||||
@ -2246,6 +2280,13 @@ manage(Window w, XWindowAttributes *wa)
|
|||||||
c->cfact = 1.0;
|
c->cfact = 1.0;
|
||||||
#endif // CFACTS_PATCH
|
#endif // CFACTS_PATCH
|
||||||
updatetitle(c);
|
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))) {
|
if (XGetTransientForHint(dpy, w, &trans) && (t = wintoclient(trans))) {
|
||||||
c->mon = t->mon;
|
c->mon = t->mon;
|
||||||
c->tags = t->tags;
|
c->tags = t->tags;
|
||||||
@ -3018,9 +3059,20 @@ run(void)
|
|||||||
XEvent ev;
|
XEvent ev;
|
||||||
/* main event loop */
|
/* main event loop */
|
||||||
XSync(dpy, False);
|
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])
|
if (handler[ev.type])
|
||||||
handler[ev.type](&ev); /* call handler */
|
handler[ev.type](&ev); /* call handler */
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif // IPC_PATCH
|
#endif // IPC_PATCH
|
||||||
|
|
||||||
@ -3198,6 +3250,9 @@ setfocus(Client *c)
|
|||||||
XChangeProperty(dpy, root, netatom[NetActiveWindow],
|
XChangeProperty(dpy, root, netatom[NetActiveWindow],
|
||||||
XA_WINDOW, 32, PropModeReplace,
|
XA_WINDOW, 32, PropModeReplace,
|
||||||
(unsigned char *) &(c->win), 1);
|
(unsigned char *) &(c->win), 1);
|
||||||
|
#if XKB_PATCH
|
||||||
|
XkbLockGroup(dpy, XkbUseCoreKbd, c->xkb->group);
|
||||||
|
#endif // XKB_PATCH
|
||||||
}
|
}
|
||||||
#if BAR_SYSTRAY_PATCH
|
#if BAR_SYSTRAY_PATCH
|
||||||
sendevent(c->win, wmatom[WMTakeFocus], NoEventMask, wmatom[WMTakeFocus], CurrentTime, 0, 0, 0);
|
sendevent(c->win, wmatom[WMTakeFocus], NoEventMask, wmatom[WMTakeFocus], CurrentTime, 0, 0, 0);
|
||||||
@ -3381,6 +3436,9 @@ setup(void)
|
|||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
XSetWindowAttributes wa;
|
XSetWindowAttributes wa;
|
||||||
|
#if XKB_PATCH
|
||||||
|
XkbStateRec xkbstate;
|
||||||
|
#endif // XKB_PATCH
|
||||||
Atom utf8string;
|
Atom utf8string;
|
||||||
|
|
||||||
/* clean up any zombies immediately */
|
/* clean up any zombies immediately */
|
||||||
@ -3553,6 +3611,17 @@ setup(void)
|
|||||||
|LeaveWindowMask|StructureNotifyMask|PropertyChangeMask;
|
|LeaveWindowMask|StructureNotifyMask|PropertyChangeMask;
|
||||||
XChangeWindowAttributes(dpy, root, CWEventMask|CWCursor, &wa);
|
XChangeWindowAttributes(dpy, root, CWEventMask|CWCursor, &wa);
|
||||||
XSelectInput(dpy, root, wa.event_mask);
|
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();
|
grabkeys();
|
||||||
focus(NULL);
|
focus(NULL);
|
||||||
#if IPC_PATCH
|
#if IPC_PATCH
|
||||||
@ -4034,6 +4103,9 @@ unmanage(Client *c, int destroyed)
|
|||||||
unsigned int switchtag = c->switchtag;
|
unsigned int switchtag = c->switchtag;
|
||||||
#endif // SWITCHTAG_PATCH
|
#endif // SWITCHTAG_PATCH
|
||||||
XWindowChanges wc;
|
XWindowChanges wc;
|
||||||
|
#if XKB_PATCH
|
||||||
|
XkbInfo *xkb;
|
||||||
|
#endif // XKB_PATCH
|
||||||
|
|
||||||
#if SWALLOW_PATCH
|
#if SWALLOW_PATCH
|
||||||
if (c->swallowing) {
|
if (c->swallowing) {
|
||||||
@ -4064,6 +4136,19 @@ unmanage(Client *c, int destroyed)
|
|||||||
XSetErrorHandler(xerror);
|
XSetErrorHandler(xerror);
|
||||||
XUngrabServer(dpy);
|
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);
|
free(c);
|
||||||
#if SWALLOW_PATCH
|
#if SWALLOW_PATCH
|
||||||
if (s)
|
if (s)
|
||||||
|
@ -298,6 +298,9 @@
|
|||||||
#if ZOOMSWAP_PATCH
|
#if ZOOMSWAP_PATCH
|
||||||
#include "zoomswap.c"
|
#include "zoomswap.c"
|
||||||
#endif
|
#endif
|
||||||
|
#if XKB_PATCH
|
||||||
|
#include "xkb.c"
|
||||||
|
#endif
|
||||||
#if XRDB_PATCH && !BAR_VTCOLORS_PATCH
|
#if XRDB_PATCH && !BAR_VTCOLORS_PATCH
|
||||||
#include "xrdb.c"
|
#include "xrdb.c"
|
||||||
#endif
|
#endif
|
||||||
|
@ -294,6 +294,9 @@
|
|||||||
#if ZOOMSWAP_PATCH
|
#if ZOOMSWAP_PATCH
|
||||||
#include "zoomswap.h"
|
#include "zoomswap.h"
|
||||||
#endif
|
#endif
|
||||||
|
#if XKB_PATCH
|
||||||
|
#include "xkb.h"
|
||||||
|
#endif
|
||||||
#if XRDB_PATCH && !BAR_VTCOLORS_PATCH
|
#if XRDB_PATCH && !BAR_VTCOLORS_PATCH
|
||||||
#include "xrdb.h"
|
#include "xrdb.h"
|
||||||
#endif
|
#endif
|
||||||
|
@ -9,6 +9,15 @@ handlexevent(struct epoll_event *ev)
|
|||||||
XEvent ev;
|
XEvent ev;
|
||||||
while (running && XPending(dpy)) {
|
while (running && XPending(dpy)) {
|
||||||
XNextEvent(dpy, &ev);
|
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]) {
|
if (handler[ev.type]) {
|
||||||
handler[ev.type](&ev); /* call handler */
|
handler[ev.type](&ev); /* call handler */
|
||||||
ipc_send_events(mons, &lastselmon, selmon);
|
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
|
#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
|
/* Allows dwm to read colors from xrdb (.Xresources) during runtime. Compatible with
|
||||||
* the float border color, awesomebar, urgentborder and titlecolor patches.
|
* the float border color, awesomebar, urgentborder and titlecolor patches.
|
||||||
* https://dwm.suckless.org/patches/xrdb/
|
* https://dwm.suckless.org/patches/xrdb/
|
||||||
|
Loading…
Reference in New Issue
Block a user