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 4 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_NAME(STRING) = title
*/
/* class instance title tags mask isfloating isterminal noswallow nofakefullscreen monitor */
//{ "Gimp", NULL, NULL, 0, 0, 0, 0, 0, -1 },
//{ "Firefox", NULL, NULL, 1 << 8, 0, 0, 0, 0, -1 },
{ "xterm-256color", NULL, NULL, 0, 0, 1, 1, 0, -1 },
{ "Thunderbird", NULL, NULL, 1 << 8 , 0, 0, 0, 0, -1 },
{ NULL, NULL, "noswallow", 0, 0, 0, 1, 0, -1 }
/* class instance title tags mask isfloating isterminal noswallow nofakefullscreen iskeyboard monitor */
//{ "Gimp", NULL, NULL, 0, 0, 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, 0, -1 },
{ "Thunderbird", NULL, NULL, 1 << 8 , 0, 0, 0, 0, 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 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)))
#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 MOUSEMASK (BUTTONMASK|PointerMotionMask)
#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 bw, oldbw;
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;
Client *next;
Client *snext;
@ -145,6 +145,7 @@ typedef struct {
int isterminal;
int noswallow;
int nofakefullscreen;
int iskeyboard;
int monitor;
} Rule;
@ -244,6 +245,7 @@ static int xerror(Display *dpy, XErrorEvent *ee);
static int xerrordummy(Display *dpy, XErrorEvent *ee);
static int xerrorstart(Display *dpy, XErrorEvent *ee);
static void zoom(const Arg *arg);
static void adjustborders(Monitor *m);
static pid_t getparentprocess(pid_t p);
static int isdescprocess(pid_t p, pid_t c);
@ -321,6 +323,7 @@ applyrules(Client *c)
c->noswallow = r->noswallow;
c->isfloating = r->isfloating;
c->nofakefullscreen = r->nofakefullscreen;
c->iskeyboard = r->iskeyboard;
c->tags |= r->tags;
for (m = mons; m && m->num != r->monitor; m = m->next);
if (m)
@ -340,6 +343,10 @@ applysizehints(Client *c, int *x, int *y, int *w, int *h, int interact)
int baseismin;
Monitor *m = c->mon;
if (c->iskeyboard){
return(False);
}
/* set minimum possible */
*w = MAX(1, *w);
*h = MAX(1, *h);
@ -401,12 +408,14 @@ applysizehints(Client *c, int *x, int *y, int *w, int *h, int interact)
}
void
arrange(Monitor *m)
{
if (m)
arrange(Monitor *m) {
if (m){
adjustborders(m);
showhide(m->stack);
else for (m = mons; m; m = m->next)
} else for (m = mons; m; m = m->next){
adjustborders(m);
showhide(m->stack);
}
if (m) {
arrangemon(m);
restack(m);
@ -459,7 +468,7 @@ attachstack(Client *c)
void
swallow(Client *p, Client *c)
{
if (c->noswallow || c->isterminal)
if (c->noswallow || c->isterminal || c->isfloating)
return;
detach(c);
@ -498,8 +507,7 @@ unswallow(Client *c)
}
void
buttonpress(XEvent *e)
{
buttonpress(XEvent *e) {
unsigned int i, x, click;
Arg arg = {0};
Client *c;
@ -540,8 +548,7 @@ buttonpress(XEvent *e)
}
void
checkotherwm(void)
{
checkotherwm(void) {
xerrorxlib = XSetErrorHandler(xerrorstart);
/* this causes an error if some other window manager is running */
XSelectInput(dpy, DefaultRootWindow(dpy), SubstructureRedirectMask);
@ -551,8 +558,7 @@ checkotherwm(void)
}
void
cleanup(void)
{
cleanup(void) {
Arg a = {.ui = ~0};
Layout foo = { "", NULL };
Monitor *m;
@ -578,8 +584,7 @@ cleanup(void)
}
void
cleanupmon(Monitor *mon)
{
cleanupmon(Monitor *mon) {
Monitor *m;
if (mon == mons)
@ -613,8 +618,7 @@ clientmessage(XEvent *e)
}
void
configure(Client *c)
{
configure(Client *c) {
XConfigureEvent ce;
ce.type = ConfigureNotify;
@ -632,8 +636,7 @@ configure(Client *c)
}
void
configurenotify(XEvent *e)
{
configurenotify(XEvent *e) {
Monitor *m;
XConfigureEvent *ev = &e->xconfigure;
int dirty;
@ -656,14 +659,13 @@ configurenotify(XEvent *e)
}
void
configurerequest(XEvent *e)
{
configurerequest(XEvent *e) {
Client *c;
Monitor *m;
XConfigureRequestEvent *ev = &e->xconfigurerequest;
XWindowChanges wc;
if ((c = wintoclient(ev->window))) {
if ((c = wintoclient(ev->window)) && !c->iskeyboard) {
if (ev->value_mask & CWBorderWidth)
c->bw = ev->border_width;
else if (c->isfloating || !selmon->lt[selmon->sellt]->arrange) {
@ -708,8 +710,7 @@ configurerequest(XEvent *e)
}
Monitor *
createmon(void)
{
createmon(void) {
Monitor *m;
m = ecalloc(1, sizeof(Monitor));
@ -725,8 +726,7 @@ createmon(void)
}
void
destroynotify(XEvent *e)
{
destroynotify(XEvent *e) {
Client *c;
XDestroyWindowEvent *ev = &e->xdestroywindow;
@ -738,8 +738,7 @@ destroynotify(XEvent *e)
}
void
detach(Client *c)
{
detach(Client *c) {
Client **tc;
for (tc = &c->mon->clients; *tc && *tc != c; tc = &(*tc)->next);
@ -747,8 +746,7 @@ detach(Client *c)
}
void
detachstack(Client *c)
{
detachstack(Client *c) {
Client **tc, *t;
for (tc = &c->mon->stack; *tc && *tc != c; tc = &(*tc)->snext);
@ -761,8 +759,7 @@ detachstack(Client *c)
}
Monitor *
dirtomon(int dir)
{
dirtomon(int dir) {
Monitor *m = NULL;
if (dir > 0) {
@ -775,8 +772,7 @@ dirtomon(int dir)
return m;
}
void
drawbar(Monitor *m)
void drawbar(Monitor *m)
{
int x, w, tw = 0;
int boxs = drw->fonts->h / 9;
@ -844,6 +840,11 @@ enternotify(XEvent *e)
if ((ev->mode != NotifyNormal || ev->detail == NotifyInferior) && ev->window != root)
return;
c = wintoclient(ev->window);
if ( c && c->iskeyboard ){
return;
}
m = c ? c->mon : wintomon(ev->window);
if (m != selmon) {
unfocus(selmon->sel, 1);
@ -854,8 +855,7 @@ enternotify(XEvent *e)
}
void
expose(XEvent *e)
{
expose(XEvent *e) {
Monitor *m;
XExposeEvent *ev = &e->xexpose;
@ -864,8 +864,10 @@ expose(XEvent *e)
}
void
focus(Client *c)
{
focus(Client *c) {
if ( c && c->iskeyboard ) {
return;
}
if (!c || !ISVISIBLE(c))
for (c = selmon->stack; c && !ISVISIBLE(c); c = c->snext);
if (selmon->sel && selmon->sel != c)
@ -899,8 +901,7 @@ focusin(XEvent *e)
}
void
focusmon(const Arg *arg)
{
focusmon(const Arg *arg) {
Monitor *m;
if (!mons->next)
@ -914,23 +915,23 @@ focusmon(const Arg *arg)
}
void
focusstack(const Arg *arg)
{
focusstack(const Arg *arg) {
Client *c = NULL, *i;
if (!selmon->sel)
return;
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)
for (c = selmon->clients; c && !ISVISIBLE(c); c = c->next);
} else {
for(c = selmon->clients; c && (!ISVISIBLE(c) || c->iskeyboard); c = c->next);
}
else {
for (i = selmon->clients; i != selmon->sel; i = i->next)
if (ISVISIBLE(i))
if(ISVISIBLE(i) && !i->iskeyboard)
c = i;
if (!c)
for (; i; i = i->next)
if (ISVISIBLE(i))
if(ISVISIBLE(i) && !i->iskeyboard)
c = i;
}
if (c) {
@ -940,8 +941,7 @@ focusstack(const Arg *arg)
}
Atom
getatomprop(Client *c, Atom prop)
{
getatomprop(Client *c, Atom prop) {
int di;
unsigned long dl;
unsigned char *p = NULL;
@ -956,8 +956,7 @@ getatomprop(Client *c, Atom prop)
}
int
getrootptr(int *x, int *y)
{
getrootptr(int *x, int *y) {
int di;
unsigned int dui;
Window dummy;
@ -966,8 +965,7 @@ getrootptr(int *x, int *y)
}
long
getstate(Window w)
{
getstate(Window w) {
int format;
long result = -1;
unsigned char *p = NULL;
@ -1030,8 +1028,7 @@ grabbuttons(Client *c, int focused)
}
void
grabkeys(void)
{
grabkeys(void) {
updatenumlockmask();
{
unsigned int i, j;
@ -1048,8 +1045,7 @@ grabkeys(void)
}
void
incnmaster(const Arg *arg)
{
incnmaster(const Arg *arg) {
selmon->nmaster = MAX(selmon->nmaster + arg->i, 0);
arrange(selmon);
}
@ -1067,8 +1063,7 @@ isuniquegeom(XineramaScreenInfo *unique, size_t n, XineramaScreenInfo *info)
#endif /* XINERAMA */
void
keypress(XEvent *e)
{
keypress(XEvent *e) {
unsigned int i;
KeySym keysym;
XKeyEvent *ev;
@ -1099,8 +1094,7 @@ killclient(const Arg *arg)
}
void
manage(Window w, XWindowAttributes *wa)
{
manage(Window w, XWindowAttributes *wa) {
Client *c, *t = NULL, *term = NULL;
Window trans = None;
XWindowChanges wc;
@ -1108,13 +1102,6 @@ manage(Window w, XWindowAttributes *wa)
c = ecalloc(1, sizeof(Client));
c->win = 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);
if (XGetTransientForHint(dpy, w, &trans) && (t = wintoclient(trans))) {
c->mon = t->mon;
@ -1125,15 +1112,43 @@ manage(Window w, XWindowAttributes *wa)
term = termforwin(c);
}
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);
c->bw = borderpx;
/* 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;
/* 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;
XConfigureWindow(dpy, w, CWBorderWidth, &wc);
@ -1224,8 +1239,7 @@ motionnotify(XEvent *e)
}
void
movemouse(const Arg *arg)
{
movemouse(const Arg *arg) {
int x, y, ocx, ocy, nx, ny;
Client *c;
Monitor *m;
@ -1282,15 +1296,13 @@ movemouse(const Arg *arg)
}
Client *
nexttiled(Client *c)
{
nexttiled(Client *c) {
for (; c && (c->isfloating || !ISVISIBLE(c)); c = c->next);
return c;
}
void
pop(Client *c)
{
pop(Client *c) {
detach(c);
attach(c);
focus(c);
@ -1298,8 +1310,7 @@ pop(Client *c)
}
void
propertynotify(XEvent *e)
{
propertynotify(XEvent *e) {
Client *c;
Window trans;
XPropertyEvent *ev = &e->xproperty;
@ -1355,15 +1366,67 @@ recttomon(int x, int y, int w, int h)
}
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))
resizeclient(c, x, y, w, h);
}
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;
unsigned int n;
unsigned int gapoffset;
@ -1372,6 +1435,10 @@ resizeclient(Client *c, int x, int y, int w, int h)
wc.border_width = c->bw;
if (c->iskeyboard) {
return;
}
/* Get number of clients for the selected monitor */
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;
XWindowChanges wc;
if (c->iskeyboard) {
updategeom();
}
if (c->swallowing) {
unswallow(c);
return;

Loading…
Cancel
Save