[dev] onscreen keyboards & dwm (updated patch)

From: Peter John Hartman <peterjohnhartman_AT_gmail.com>
Date: Fri, 6 Mar 2020 08:10:36 -0600

Hello Comrades,

Many years ago (2011 or so) I did some stuff to get svkbd to work with
dwm on a tablet. I didn't have a tablet for a long time and now I do
again. Here's an updated version of the patch to work against current
head of dwm. Comments are welcome --- things work, but I feel I missed
a spot or two (and the call in manage() is clunky).

The goals: (1) svkbd sometimes is present sometimes is not (manually
invoked); (2) when svkbd is present, it should be at the bottom of the
screen; (3) svkbd should not overlap a window; (4) svkbd should not
intrude on stacks, etc. and should act like it is invisible.

To get it to work, add the following to config.h's rules:

{ "svkbd", NULL, NULL, TAGMASK, 1, 1, -1 },

Also probably best to do topbar rather than bottombar.

diff --git a/dwm.c b/dwm.c
index 4465af1..0117701 100644
--- a/dwm.c
+++ b/dwm.c
_AT_@ -92,7 +92,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;
+ int isfixed, isfloating, isurgent, neverfocus, oldstate, isfullscreen, iskbd;
          Client *next;
          Client *snext;
          Monitor *mon;
_AT_@ -139,6 +139,7 @@ typedef struct {
          unsigned int tags;
          int isfloating;
          int monitor;
+ int iskbd;
  } Rule;
  
  /* function declarations */
_AT_@ -298,6 +299,7 @@ applyrules(Client *c)
                  && (!r->instance || strstr(instance, r->instance)))
                  {
                          c->isfloating = r->isfloating;
+ c->iskbd = r->iskbd;
                          c->tags |= r->tags;
                          for (m = mons; m && m->num != r->monitor; m = m->next);
                          if (m)
_AT_@ -709,9 +711,11 @@ drawbar(Monitor *m)
          }
  
          for (c = m->clients; c; c = c->next) {
- occ |= c->tags;
- if (c->isurgent)
- urg |= c->tags;
+ if (!c->iskbd) {
+ occ |= c->tags;
+ if (c->isurgent)
+ urg |= c->tags;
+ }
          }
          x = 0;
          for (i = 0; i < LENGTH(tags); i++) {
_AT_@ -788,6 +792,8 @@ focus(Client *c)
          if (selmon->sel && selmon->sel != c)
                  unfocus(selmon->sel, 0);
          if (c) {
+ if (c->iskbd)
+ return;
                  if (c->mon != selmon)
                          selmon = c->mon;
                  if (c->isurgent)
_AT_@ -837,16 +843,16 @@ focusstack(const Arg *arg)
          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->iskbd); c = c->next);
                  if (!c)
- for (c = selmon->clients; c && !ISVISIBLE(c); c = c->next);
+ for (c = selmon->clients; c && (!ISVISIBLE(c) || c->iskbd); c = c->next);
          } else {
                  for (i = selmon->clients; i != selmon->sel; i = i->next)
- if (ISVISIBLE(i))
+ if (ISVISIBLE(i) && !i->iskbd)
                                  c = i;
                  if (!c)
                          for (; i; i = i->next)
- if (ISVISIBLE(i))
+ if (ISVISIBLE(i) && !i->iskbd)
                                          c = i;
          }
          if (c) {
_AT_@ -1039,14 +1045,22 @@ manage(Window w, XWindowAttributes *wa)
                  applyrules(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);
+ if (c->iskbd) {
+ c->y = c->mon->my + c->mon->mh - c->h;
+ c->mon->mh = HEIGHT(c);
+ updatebarpos(selmon);
+ XMoveResizeWindow(dpy, selmon->barwin, selmon->wx, selmon->by, selmon->ww, bh);
+ arrange(selmon);
+ } 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);
+ }
          c->bw = borderpx;
  
          wc.border_width = c->bw;
_AT_@ -1107,7 +1121,7 @@ monocle(Monitor *m)
          Client *c;
  
          for (c = m->clients; c; c = c->next)
- if (ISVISIBLE(c))
+ if (ISVISIBLE(c) && !c->iskbd)
                          n++;
          if (n > 0) /* override layout symbol */
                  snprintf(m->ltsymbol, sizeof m->ltsymbol, "[%d]", n);
_AT_@ -1268,6 +1282,8 @@ recttomon(int x, int y, int w, int h)
  void
  resize(Client *c, int x, int y, int w, int h, int interact)
  {
+ if (c && c->iskbd)
+ return;
          if (applysizehints(c, &x, &y, &w, &h, interact))
                  resizeclient(c, x, y, w, h);
  }
_AT_@ -1765,6 +1781,9 @@ unmanage(Client *c, int destroyed)
          Monitor *m = c->mon;
          XWindowChanges wc;
  
+ if (c->iskbd)
+ updategeom();
+
          detach(c);
          detachstack(c);
          if (!destroyed) {



--
sic dicit magister P
https://phartman.sites.luc.edu/
GPG keyID 0xE0DBD3D6 (CAE6 3A6F 755F 7BC3 36CA  330D B3E6 39C6 E0DB D3D6)
Received on Fri Mar 06 2020 - 15:10:36 CET

This archive was generated by hypermail 2.3.0 : Fri Mar 06 2020 - 15:48:09 CET