Adds the ability to have an on screen keyboard

I'm going to be using dwm on my new pinephone and need the ability to
type.

Almost all the code for this has come from minego:
https://github.com/minego/dwm-customized
keyboard
Jonathan Hodgson 3 years ago
parent ed39b70a71
commit 88ac289837
  1. 14
      config.def.h
  2. 249
      dwm.c

@ -31,12 +31,14 @@ static const Rule rules[] = {
* WM_CLASS(STRING) = instance, class * WM_CLASS(STRING) = instance, class
* WM_NAME(STRING) = title * WM_NAME(STRING) = title
*/ */
/* class instance title tags mask isfloating isterminal noswallow nofakefullscreen monitor */ /* class instance title tags mask isfloating isterminal noswallow nofakefullscreen iskeyboard monitor */
//{ "Gimp", NULL, NULL, 0, 0, 0, 0, 0, -1 }, //{ "Gimp", NULL, NULL, 0, 0, 0, 0, 0, 0, -1 },
//{ "Firefox", NULL, NULL, 1 << 8, 0, 0, 0, 0, -1 }, //{ "Firefox", NULL, NULL, 1 << 8, 0, 0, 0, 0, 0, -1 },
{ "xterm-256color", NULL, NULL, 0, 0, 1, 1, 0, -1 }, { "xterm-256color", NULL, NULL, 0, 0, 1, 1, 0, 0, -1 },
{ "Thunderbird", NULL, NULL, 1 << 8 , 0, 0, 0, 0, -1 }, { "Thunderbird", NULL, NULL, 1 << 8 , 0, 0, 0, 0, 0, -1 },
{ NULL, NULL, "noswallow", 0, 0, 0, 1, 0, -1 } { NULL, NULL, "noswallow", 0, 0, 0, 1, 0, 0, -1 },
{ "Onboard", NULL, NULL, 0, 1, 0, 1, 0, 1, -1 },
{ "Onboard-settings", NULL, NULL, 0, 0, 0, 0, 0, 0, -1 }
}; };

249
dwm.c

@ -51,7 +51,7 @@
#define CLEANMASK(mask) (mask & ~(numlockmask|LockMask) & (ShiftMask|ControlMask|Mod1Mask|Mod2Mask|Mod3Mask|Mod4Mask|Mod5Mask)) #define CLEANMASK(mask) (mask & ~(numlockmask|LockMask) & (ShiftMask|ControlMask|Mod1Mask|Mod2Mask|Mod3Mask|Mod4Mask|Mod5Mask))
#define INTERSECT(x,y,w,h,m) (MAX(0, MIN((x)+(w),(m)->wx+(m)->ww) - MAX((x),(m)->wx)) \ #define INTERSECT(x,y,w,h,m) (MAX(0, MIN((x)+(w),(m)->wx+(m)->ww) - MAX((x),(m)->wx)) \
* MAX(0, MIN((y)+(h),(m)->wy+(m)->wh) - MAX((y),(m)->wy))) * MAX(0, MIN((y)+(h),(m)->wy+(m)->wh) - MAX((y),(m)->wy)))
#define ISVISIBLE(C) ((C->tags & C->mon->tagset[C->mon->seltags])) #define ISVISIBLE(C) (((C->tags & C->mon->tagset[C->mon->seltags])) || (C->iskeyboard))
#define LENGTH(X) (sizeof X / sizeof X[0]) #define LENGTH(X) (sizeof X / sizeof X[0])
#define MOUSEMASK (BUTTONMASK|PointerMotionMask) #define MOUSEMASK (BUTTONMASK|PointerMotionMask)
#define WIDTH(X) ((X)->w + 2 * (X)->bw + gappx) #define WIDTH(X) ((X)->w + 2 * (X)->bw + gappx)
@ -94,7 +94,7 @@ struct Client {
int basew, baseh, incw, inch, maxw, maxh, minw, minh; int basew, baseh, incw, inch, maxw, maxh, minw, minh;
int bw, oldbw; int bw, oldbw;
unsigned int tags; unsigned int tags;
int isfixed, isfloating, isurgent, neverfocus, oldstate, isfullscreen, isterminal, noswallow, nofakefullscreen; int isfixed, isfloating, isurgent, neverfocus, oldstate, isfullscreen, isterminal, noswallow, nofakefullscreen, iskeyboard;
pid_t pid; pid_t pid;
Client *next; Client *next;
Client *snext; Client *snext;
@ -145,6 +145,7 @@ typedef struct {
int isterminal; int isterminal;
int noswallow; int noswallow;
int nofakefullscreen; int nofakefullscreen;
int iskeyboard;
int monitor; int monitor;
} Rule; } Rule;
@ -244,6 +245,7 @@ static int xerror(Display *dpy, XErrorEvent *ee);
static int xerrordummy(Display *dpy, XErrorEvent *ee); static int xerrordummy(Display *dpy, XErrorEvent *ee);
static int xerrorstart(Display *dpy, XErrorEvent *ee); static int xerrorstart(Display *dpy, XErrorEvent *ee);
static void zoom(const Arg *arg); static void zoom(const Arg *arg);
static void adjustborders(Monitor *m);
static pid_t getparentprocess(pid_t p); static pid_t getparentprocess(pid_t p);
static int isdescprocess(pid_t p, pid_t c); static int isdescprocess(pid_t p, pid_t c);
@ -321,6 +323,7 @@ applyrules(Client *c)
c->noswallow = r->noswallow; c->noswallow = r->noswallow;
c->isfloating = r->isfloating; c->isfloating = r->isfloating;
c->nofakefullscreen = r->nofakefullscreen; c->nofakefullscreen = r->nofakefullscreen;
c->iskeyboard = r->iskeyboard;
c->tags |= r->tags; c->tags |= r->tags;
for (m = mons; m && m->num != r->monitor; m = m->next); for (m = mons; m && m->num != r->monitor; m = m->next);
if (m) if (m)
@ -340,6 +343,10 @@ applysizehints(Client *c, int *x, int *y, int *w, int *h, int interact)
int baseismin; int baseismin;
Monitor *m = c->mon; Monitor *m = c->mon;
if (c->iskeyboard){
return(False);
}
/* set minimum possible */ /* set minimum possible */
*w = MAX(1, *w); *w = MAX(1, *w);
*h = MAX(1, *h); *h = MAX(1, *h);
@ -401,12 +408,14 @@ applysizehints(Client *c, int *x, int *y, int *w, int *h, int interact)
} }
void void
arrange(Monitor *m) arrange(Monitor *m) {
{ if (m){
if (m) adjustborders(m);
showhide(m->stack); showhide(m->stack);
else for (m = mons; m; m = m->next) } else for (m = mons; m; m = m->next){
adjustborders(m);
showhide(m->stack); showhide(m->stack);
}
if (m) { if (m) {
arrangemon(m); arrangemon(m);
restack(m); restack(m);
@ -459,7 +468,7 @@ attachstack(Client *c)
void void
swallow(Client *p, Client *c) swallow(Client *p, Client *c)
{ {
if (c->noswallow || c->isterminal) if (c->noswallow || c->isterminal || c->isfloating)
return; return;
detach(c); detach(c);
@ -498,8 +507,7 @@ unswallow(Client *c)
} }
void void
buttonpress(XEvent *e) buttonpress(XEvent *e) {
{
unsigned int i, x, click; unsigned int i, x, click;
Arg arg = {0}; Arg arg = {0};
Client *c; Client *c;
@ -540,8 +548,7 @@ buttonpress(XEvent *e)
} }
void void
checkotherwm(void) checkotherwm(void) {
{
xerrorxlib = XSetErrorHandler(xerrorstart); xerrorxlib = XSetErrorHandler(xerrorstart);
/* this causes an error if some other window manager is running */ /* this causes an error if some other window manager is running */
XSelectInput(dpy, DefaultRootWindow(dpy), SubstructureRedirectMask); XSelectInput(dpy, DefaultRootWindow(dpy), SubstructureRedirectMask);
@ -551,8 +558,7 @@ checkotherwm(void)
} }
void void
cleanup(void) cleanup(void) {
{
Arg a = {.ui = ~0}; Arg a = {.ui = ~0};
Layout foo = { "", NULL }; Layout foo = { "", NULL };
Monitor *m; Monitor *m;
@ -578,8 +584,7 @@ cleanup(void)
} }
void void
cleanupmon(Monitor *mon) cleanupmon(Monitor *mon) {
{
Monitor *m; Monitor *m;
if (mon == mons) if (mon == mons)
@ -613,8 +618,7 @@ clientmessage(XEvent *e)
} }
void void
configure(Client *c) configure(Client *c) {
{
XConfigureEvent ce; XConfigureEvent ce;
ce.type = ConfigureNotify; ce.type = ConfigureNotify;
@ -632,8 +636,7 @@ configure(Client *c)
} }
void void
configurenotify(XEvent *e) configurenotify(XEvent *e) {
{
Monitor *m; Monitor *m;
XConfigureEvent *ev = &e->xconfigure; XConfigureEvent *ev = &e->xconfigure;
int dirty; int dirty;
@ -656,14 +659,13 @@ configurenotify(XEvent *e)
} }
void void
configurerequest(XEvent *e) configurerequest(XEvent *e) {
{
Client *c; Client *c;
Monitor *m; Monitor *m;
XConfigureRequestEvent *ev = &e->xconfigurerequest; XConfigureRequestEvent *ev = &e->xconfigurerequest;
XWindowChanges wc; XWindowChanges wc;
if ((c = wintoclient(ev->window))) { if ((c = wintoclient(ev->window)) && !c->iskeyboard) {
if (ev->value_mask & CWBorderWidth) if (ev->value_mask & CWBorderWidth)
c->bw = ev->border_width; c->bw = ev->border_width;
else if (c->isfloating || !selmon->lt[selmon->sellt]->arrange) { else if (c->isfloating || !selmon->lt[selmon->sellt]->arrange) {
@ -708,8 +710,7 @@ configurerequest(XEvent *e)
} }
Monitor * Monitor *
createmon(void) createmon(void) {
{
Monitor *m; Monitor *m;
m = ecalloc(1, sizeof(Monitor)); m = ecalloc(1, sizeof(Monitor));
@ -725,8 +726,7 @@ createmon(void)
} }
void void
destroynotify(XEvent *e) destroynotify(XEvent *e) {
{
Client *c; Client *c;
XDestroyWindowEvent *ev = &e->xdestroywindow; XDestroyWindowEvent *ev = &e->xdestroywindow;
@ -738,8 +738,7 @@ destroynotify(XEvent *e)
} }
void void
detach(Client *c) detach(Client *c) {
{
Client **tc; Client **tc;
for (tc = &c->mon->clients; *tc && *tc != c; tc = &(*tc)->next); for (tc = &c->mon->clients; *tc && *tc != c; tc = &(*tc)->next);
@ -747,8 +746,7 @@ detach(Client *c)
} }
void void
detachstack(Client *c) detachstack(Client *c) {
{
Client **tc, *t; Client **tc, *t;
for (tc = &c->mon->stack; *tc && *tc != c; tc = &(*tc)->snext); for (tc = &c->mon->stack; *tc && *tc != c; tc = &(*tc)->snext);
@ -761,8 +759,7 @@ detachstack(Client *c)
} }
Monitor * Monitor *
dirtomon(int dir) dirtomon(int dir) {
{
Monitor *m = NULL; Monitor *m = NULL;
if (dir > 0) { if (dir > 0) {
@ -775,8 +772,7 @@ dirtomon(int dir)
return m; return m;
} }
void void drawbar(Monitor *m)
drawbar(Monitor *m)
{ {
int x, w, tw = 0; int x, w, tw = 0;
int boxs = drw->fonts->h / 9; int boxs = drw->fonts->h / 9;
@ -844,6 +840,11 @@ enternotify(XEvent *e)
if ((ev->mode != NotifyNormal || ev->detail == NotifyInferior) && ev->window != root) if ((ev->mode != NotifyNormal || ev->detail == NotifyInferior) && ev->window != root)
return; return;
c = wintoclient(ev->window); c = wintoclient(ev->window);
if ( c && c->iskeyboard ){
return;
}
m = c ? c->mon : wintomon(ev->window); m = c ? c->mon : wintomon(ev->window);
if (m != selmon) { if (m != selmon) {
unfocus(selmon->sel, 1); unfocus(selmon->sel, 1);
@ -854,8 +855,7 @@ enternotify(XEvent *e)
} }
void void
expose(XEvent *e) expose(XEvent *e) {
{
Monitor *m; Monitor *m;
XExposeEvent *ev = &e->xexpose; XExposeEvent *ev = &e->xexpose;
@ -864,8 +864,10 @@ expose(XEvent *e)
} }
void void
focus(Client *c) focus(Client *c) {
{ if ( c && c->iskeyboard ) {
return;
}
if (!c || !ISVISIBLE(c)) if (!c || !ISVISIBLE(c))
for (c = selmon->stack; c && !ISVISIBLE(c); c = c->snext); for (c = selmon->stack; c && !ISVISIBLE(c); c = c->snext);
if (selmon->sel && selmon->sel != c) if (selmon->sel && selmon->sel != c)
@ -899,8 +901,7 @@ focusin(XEvent *e)
} }
void void
focusmon(const Arg *arg) focusmon(const Arg *arg) {
{
Monitor *m; Monitor *m;
if (!mons->next) if (!mons->next)
@ -914,23 +915,23 @@ focusmon(const Arg *arg)
} }
void void
focusstack(const Arg *arg) focusstack(const Arg *arg) {
{
Client *c = NULL, *i; Client *c = NULL, *i;
if (!selmon->sel) if (!selmon->sel)
return; return;
if (arg->i > 0) { if (arg->i > 0) {
for (c = selmon->sel->next; c && !ISVISIBLE(c); c = c->next); for(c = selmon->sel->next; c && (!ISVISIBLE(c) || c->iskeyboard); c = c->next);
if (!c) if (!c)
for (c = selmon->clients; c && !ISVISIBLE(c); c = c->next); for(c = selmon->clients; c && (!ISVISIBLE(c) || c->iskeyboard); c = c->next);
} else { }
else {
for (i = selmon->clients; i != selmon->sel; i = i->next) for (i = selmon->clients; i != selmon->sel; i = i->next)
if (ISVISIBLE(i)) if(ISVISIBLE(i) && !i->iskeyboard)
c = i; c = i;
if (!c) if (!c)
for (; i; i = i->next) for (; i; i = i->next)
if (ISVISIBLE(i)) if(ISVISIBLE(i) && !i->iskeyboard)
c = i; c = i;
} }
if (c) { if (c) {
@ -940,8 +941,7 @@ focusstack(const Arg *arg)
} }
Atom Atom
getatomprop(Client *c, Atom prop) getatomprop(Client *c, Atom prop) {
{
int di; int di;
unsigned long dl; unsigned long dl;
unsigned char *p = NULL; unsigned char *p = NULL;
@ -956,8 +956,7 @@ getatomprop(Client *c, Atom prop)
} }
int int
getrootptr(int *x, int *y) getrootptr(int *x, int *y) {
{
int di; int di;
unsigned int dui; unsigned int dui;
Window dummy; Window dummy;
@ -966,8 +965,7 @@ getrootptr(int *x, int *y)
} }
long long
getstate(Window w) getstate(Window w) {
{
int format; int format;
long result = -1; long result = -1;
unsigned char *p = NULL; unsigned char *p = NULL;
@ -1030,8 +1028,7 @@ grabbuttons(Client *c, int focused)
} }
void void
grabkeys(void) grabkeys(void) {
{
updatenumlockmask(); updatenumlockmask();
{ {
unsigned int i, j; unsigned int i, j;
@ -1048,8 +1045,7 @@ grabkeys(void)
} }
void void
incnmaster(const Arg *arg) incnmaster(const Arg *arg) {
{
selmon->nmaster = MAX(selmon->nmaster + arg->i, 0); selmon->nmaster = MAX(selmon->nmaster + arg->i, 0);
arrange(selmon); arrange(selmon);
} }
@ -1067,8 +1063,7 @@ isuniquegeom(XineramaScreenInfo *unique, size_t n, XineramaScreenInfo *info)
#endif /* XINERAMA */ #endif /* XINERAMA */
void void
keypress(XEvent *e) keypress(XEvent *e) {
{
unsigned int i; unsigned int i;
KeySym keysym; KeySym keysym;
XKeyEvent *ev; XKeyEvent *ev;
@ -1099,8 +1094,7 @@ killclient(const Arg *arg)
} }
void void
manage(Window w, XWindowAttributes *wa) manage(Window w, XWindowAttributes *wa) {
{
Client *c, *t = NULL, *term = NULL; Client *c, *t = NULL, *term = NULL;
Window trans = None; Window trans = None;
XWindowChanges wc; XWindowChanges wc;
@ -1108,13 +1102,6 @@ manage(Window w, XWindowAttributes *wa)
c = ecalloc(1, sizeof(Client)); c = ecalloc(1, sizeof(Client));
c->win = w; c->win = w;
c->pid = winpid(w); c->pid = winpid(w);
/* geometry */
c->x = c->oldx = wa->x;
c->y = c->oldy = wa->y;
c->w = c->oldw = wa->width;
c->h = c->oldh = wa->height;
c->oldbw = wa->border_width;
updatetitle(c); updatetitle(c);
if (XGetTransientForHint(dpy, w, &trans) && (t = wintoclient(trans))) { if (XGetTransientForHint(dpy, w, &trans) && (t = wintoclient(trans))) {
c->mon = t->mon; c->mon = t->mon;
@ -1125,15 +1112,43 @@ manage(Window w, XWindowAttributes *wa)
term = termforwin(c); term = termforwin(c);
} }
if (c->x + WIDTH(c) > c->mon->mx + c->mon->mw) /* geometry */
c->x = c->mon->mx + c->mon->mw - WIDTH(c); c->x = c->oldx = wa->x;
if (c->y + HEIGHT(c) > c->mon->my + c->mon->mh) c->y = c->oldy = wa->y;
c->y = c->mon->my + c->mon->mh - HEIGHT(c); c->w = c->oldw = wa->width;
c->x = MAX(c->x, c->mon->mx); c->h = c->oldh = wa->height;
/* only fix client y-offset, if the client center might cover the bar */ c->oldbw = wa->border_width;
c->y = MAX(c->y, ((c->mon->by == c->mon->my) && (c->x + (c->w / 2) >= c->mon->wx)
&& (c->x + (c->w / 2) < c->mon->wx + c->mon->ww)) ? bh : c->mon->my);
c->bw = borderpx; /* If Keyboard */
if (c->iskeyboard) {
c->y = c->mon->my + c->mon->mh - c->h;
c->mon->mh -= HEIGHT(c);
} else {
if (c->x + WIDTH(c) > c->mon->mx + c->mon->mw)
c->x = c->mon->mx + c->mon->mw - WIDTH(c);
if (c->y + HEIGHT(c) > c->mon->my + c->mon->mh)
c->y = c->mon->my + c->mon->mh - HEIGHT(c);
c->x = MAX(c->x, c->mon->mx);
/* only fix client y-offset, if the client center might cover the bar */
c->y = MAX(c->y, ((c->mon->by == c->mon->my) && (c->x + (c->w / 2) >= c->mon->wx)
&& (c->x + (c->w / 2) < c->mon->wx + c->mon->ww)) ? bh : c->mon->my);
}
updatewindowtype(c);
if (c->isfloating) {
c->bw = (c->isfullscreen || c->iskeyboard) ? 0 : borderpx;
} else {
c->bw = 0;
for(t = c->mon->clients; t; t = c->next) {
if (!t->isfloating && c != t && c->tags & t->tags) {
c->bw = borderpx;
break;
}
}
adjustborders(c->mon);
}
wc.border_width = c->bw; wc.border_width = c->bw;
XConfigureWindow(dpy, w, CWBorderWidth, &wc); XConfigureWindow(dpy, w, CWBorderWidth, &wc);
@ -1224,8 +1239,7 @@ motionnotify(XEvent *e)
} }
void void
movemouse(const Arg *arg) movemouse(const Arg *arg) {
{
int x, y, ocx, ocy, nx, ny; int x, y, ocx, ocy, nx, ny;
Client *c; Client *c;
Monitor *m; Monitor *m;
@ -1282,15 +1296,13 @@ movemouse(const Arg *arg)
} }
Client * Client *
nexttiled(Client *c) nexttiled(Client *c) {
{
for (; c && (c->isfloating || !ISVISIBLE(c)); c = c->next); for (; c && (c->isfloating || !ISVISIBLE(c)); c = c->next);
return c; return c;
} }
void void
pop(Client *c) pop(Client *c) {
{
detach(c); detach(c);
attach(c); attach(c);
focus(c); focus(c);
@ -1298,8 +1310,7 @@ pop(Client *c)
} }
void void
propertynotify(XEvent *e) propertynotify(XEvent *e) {
{
Client *c; Client *c;
Window trans; Window trans;
XPropertyEvent *ev = &e->xproperty; XPropertyEvent *ev = &e->xproperty;
@ -1355,15 +1366,67 @@ recttomon(int x, int y, int w, int h)
} }
void void
resize(Client *c, int x, int y, int w, int h, int interact) adjustborders(Monitor *m) {
{ Client *c, *l = NULL;
int visible = 0;
for(c = m->clients; c; c = c->next) {
if (ISVISIBLE(c) && !c->isfloating && m->lt[m->sellt]->arrange) {
if (m->lt[m->sellt]->arrange == monocle) {
visible = 1;
c->oldbw = c->bw;
c->bw = 0;
} else {
visible++;
c->oldbw = c->bw;
c->bw = borderpx;
}
l = c;
}
}
if (l && visible == 1 && l->bw) {
l->oldbw = l->bw;
l->bw = 0;
resizeclient(l, l->x, l->y, l->w, l->h);
}
}
void
resize(Client *c, int x, int y, int w, int h, int interact) {
int n;
if (c && c->iskeyboard) {
return;
}
n = c->mon->mx + c->mon->mw;
if (x + w + 1 + (2 * c->bw) >= n) {
w = n - x - c->bw;
}
n = c->mon->my + c->mon->mh;
if (y + h + 1 + (2 * c->bw) >= n) {
h = n - y - c->bw;
}
if (x <= c->mon->mx) {
x -= c->bw;
w += c->bw;
}
if (y <= c->mon->my) {
y -= c->bw;
y += c->bw;
}
if (applysizehints(c, &x, &y, &w, &h, interact)) if (applysizehints(c, &x, &y, &w, &h, interact))
resizeclient(c, x, y, w, h); resizeclient(c, x, y, w, h);
} }
void void
resizeclient(Client *c, int x, int y, int w, int h) resizeclient(Client *c, int x, int y, int w, int h) {
{
XWindowChanges wc; XWindowChanges wc;
unsigned int n; unsigned int n;
unsigned int gapoffset; unsigned int gapoffset;
@ -1372,6 +1435,10 @@ resizeclient(Client *c, int x, int y, int w, int h)
wc.border_width = c->bw; wc.border_width = c->bw;
if (c->iskeyboard) {
return;
}
/* Get number of clients for the selected monitor */ /* Get number of clients for the selected monitor */
for (n = 0, nbc = nexttiled(selmon->clients); nbc; nbc = nexttiled(nbc->next), n++); for (n = 0, nbc = nexttiled(selmon->clients); nbc; nbc = nexttiled(nbc->next), n++);
@ -1867,6 +1934,10 @@ unmanage(Client *c, int destroyed)
Monitor *m = c->mon; Monitor *m = c->mon;
XWindowChanges wc; XWindowChanges wc;
if (c->iskeyboard) {
updategeom();
}
if (c->swallowing) { if (c->swallowing) {
unswallow(c); unswallow(c);
return; return;

Loading…
Cancel
Save