dwm-torus-20240901-5687f46.diff - sites - public wiki contents of suckless.org
 (HTM) git clone git://git.suckless.org/sites
 (DIR) Log
 (DIR) Files
 (DIR) Refs
       ---
       dwm-torus-20240901-5687f46.diff (7358B)
       ---
            1 From bdd2dcfc0d33b894c4bddb00008f33abcd3478a5 Mon Sep 17 00:00:00 2001
            2 From: Elizabeth Hunt <elizabeth@simponic.xyz>
            3 Date: Sun, 1 Sep 2024 14:37:36 -0700
            4 Subject: [PATCH] wrap the cursor around the monitor(s) like a torus!
            5 
            6 ---
            7  config.def.h |   3 ++
            8  config.mk    |   8 +++-
            9  dwm.c        | 120 ++++++++++++++++++++++++++++++++++++++++++++++++++-
           10  3 files changed, 128 insertions(+), 3 deletions(-)
           11 
           12 diff --git a/config.def.h b/config.def.h
           13 index 9efa774..8251624 100644
           14 --- a/config.def.h
           15 +++ b/config.def.h
           16 @@ -114,3 +114,6 @@ static const Button buttons[] = {
           17          { ClkTagBar,            MODKEY,         Button3,        toggletag,      {0} },
           18  };
           19  
           20 +/* torus config */
           21 +static int torusenabled = 1;
           22 +static int wormholedelta = 1; // how close to the edge do we get before we take a wormhole to the other side.
           23 diff --git a/config.mk b/config.mk
           24 index 8efca9a..5f7634f 100644
           25 --- a/config.mk
           26 +++ b/config.mk
           27 @@ -14,6 +14,10 @@ X11LIB = /usr/X11R6/lib
           28  XINERAMALIBS  = -lXinerama
           29  XINERAMAFLAGS = -DXINERAMA
           30  
           31 +# Xinput extensions, comment if you don't want it
           32 +XINPUTLIBS = -lXi
           33 +XINPUTFLAGS = -DXINPUT
           34 +
           35  # freetype
           36  FREETYPELIBS = -lfontconfig -lXft
           37  FREETYPEINC = /usr/include/freetype2
           38 @@ -23,10 +27,10 @@ FREETYPEINC = /usr/include/freetype2
           39  
           40  # includes and libs
           41  INCS = -I${X11INC} -I${FREETYPEINC}
           42 -LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} ${FREETYPELIBS}
           43 +LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} ${FREETYPELIBS} ${XINPUTLIBS}
           44  
           45  # flags
           46 -CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_XOPEN_SOURCE=700L -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS}
           47 +CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_XOPEN_SOURCE=700L -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS} ${XINPUTFLAGS}
           48  #CFLAGS   = -g -std=c99 -pedantic -Wall -O0 ${INCS} ${CPPFLAGS}
           49  CFLAGS   = -std=c99 -pedantic -Wall -Wno-deprecated-declarations -Os ${INCS} ${CPPFLAGS}
           50  LDFLAGS  = ${LIBS}
           51 diff --git a/dwm.c b/dwm.c
           52 index 67c6b2b..392496e 100644
           53 --- a/dwm.c
           54 +++ b/dwm.c
           55 @@ -39,6 +39,9 @@
           56  #ifdef XINERAMA
           57  #include <X11/extensions/Xinerama.h>
           58  #endif /* XINERAMA */
           59 +#ifdef XINPUT
           60 +#include <X11/extensions/XInput2.h>
           61 +#endif /* XINPUT */
           62  #include <X11/Xft/Xft.h>
           63  
           64  #include "drw.h"
           65 @@ -183,12 +186,16 @@ static void mappingnotify(XEvent *e);
           66  static void maprequest(XEvent *e);
           67  static void monocle(Monitor *m);
           68  static void motionnotify(XEvent *e);
           69 +static void rawmotionnotify(XEvent *e);
           70 +static void genericeventnotify(XEvent *e);
           71  static void movemouse(const Arg *arg);
           72  static Client *nexttiled(Client *c);
           73  static void pop(Client *c);
           74  static void propertynotify(XEvent *e);
           75  static void quit(const Arg *arg);
           76  static Monitor *recttomon(int x, int y, int w, int h);
           77 +static Monitor *raycastx(Monitor *src, int y, int dx);
           78 +static Monitor *raycasty(Monitor *src, int x, int dy);
           79  static void resize(Client *c, int x, int y, int w, int h, int interact);
           80  static void resizeclient(Client *c, int x, int y, int w, int h);
           81  static void resizemouse(const Arg *arg);
           82 @@ -242,6 +249,9 @@ static int sw, sh;           /* X display screen geometry width, height */
           83  static int bh;               /* bar height */
           84  static int lrpad;            /* sum of left and right padding for text */
           85  static int (*xerrorxlib)(Display *, XErrorEvent *);
           86 +#ifdef XINPUT
           87 +static int xinputextensionop;
           88 +#endif /* XINPUT */
           89  static unsigned int numlockmask = 0;
           90  static void (*handler[LASTEvent]) (XEvent *) = {
           91          [ButtonPress] = buttonpress,
           92 @@ -257,7 +267,8 @@ static void (*handler[LASTEvent]) (XEvent *) = {
           93          [MapRequest] = maprequest,
           94          [MotionNotify] = motionnotify,
           95          [PropertyNotify] = propertynotify,
           96 -        [UnmapNotify] = unmapnotify
           97 +        [UnmapNotify] = unmapnotify,
           98 +        [GenericEvent] = genericeventnotify,
           99  };
          100  static Atom wmatom[WMLast], netatom[NetLast];
          101  static int running = 1;
          102 @@ -1142,6 +1153,58 @@ motionnotify(XEvent *e)
          103          mon = m;
          104  }
          105  
          106 +void
          107 +genericeventnotify(XEvent *e)
          108 +{
          109 +        if (e->xcookie.extension == xinputextensionop &&
          110 +            e->xcookie.evtype == XI_RawMotion) {
          111 +                rawmotionnotify(e);
          112 +        }
          113 +}
          114 +
          115 +void
          116 +rawmotionnotify(XEvent *e)
          117 +{
          118 +        if (torusenabled == 0) return;
          119 +
          120 +        int x, y;
          121 +        if (!getrootptr(&x, &y)) return;
          122 +
          123 +        int warpx = x;
          124 +        int warpy = y;
          125 +        if (BETWEEN(x, selmon->mx, selmon->mx + wormholedelta)) {
          126 +                /* ensure there's no monitor to the left */
          127 +                if (recttomon(selmon->mx - 1, y, 1, 1) != selmon)
          128 +                        return;
          129 +                /* take the wormhole */
          130 +                Monitor *farright = raycastx(selmon, y, 1);
          131 +                warpx = farright->mx + farright->mw - wormholedelta - 1;
          132 +        } else if (BETWEEN(x, selmon->mx + selmon->mw - wormholedelta,
          133 +                           selmon->mx + selmon->mw)) {
          134 +                /* ensure there's no monitor to the right */
          135 +                if (recttomon(selmon->mx + selmon->mw + 1, y, 1, 1) != selmon)
          136 +                        return;
          137 +                Monitor *farleft = raycastx(selmon, y, -1);
          138 +                warpx = farleft->mx + wormholedelta + 1;
          139 +        } else if (BETWEEN(y, selmon->my, selmon->my + wormholedelta)) {
          140 +                /* ensure there's no monitor under us */
          141 +                if (recttomon(x, y, selmon->my - 1, 1) != selmon)
          142 +                        return;
          143 +                Monitor *farup = raycasty(selmon, x, 1);
          144 +                warpy = farup->my + farup->mh - wormholedelta - 1;
          145 +        } else if (BETWEEN(y, selmon->my + selmon->mh - wormholedelta,
          146 +                           selmon->my + selmon->mh)) {
          147 +                /* ensure there's no monitor above us */
          148 +                if (recttomon(x, y, selmon->my + selmon->mh + 1, 1) != selmon)
          149 +                        return;
          150 +                Monitor *fardown = raycasty(selmon, x, -1);
          151 +                warpy = fardown->my + wormholedelta + 1;
          152 +        }
          153 +
          154 +        if (warpx != x || warpy != y)
          155 +                XWarpPointer(dpy, None, root, 0, 0, 0, 0, warpx, warpy);
          156 +}
          157 +
          158  void
          159  movemouse(const Arg *arg)
          160  {
          161 @@ -1275,6 +1338,44 @@ recttomon(int x, int y, int w, int h)
          162          return r;
          163  }
          164  
          165 +Monitor *
          166 +raycastx(Monitor *src, int y, int dx)
          167 +{
          168 +        Monitor *farthest = src;
          169 +        for (Monitor *m = mons; m; m = m->next) {
          170 +                int scansy = BETWEEN(y, m->my, m->my + m->mh);
          171 +                if (!scansy) {
          172 +                        continue;
          173 +                }
          174 +                if (dx == 1 && (m->mx + m->mw > farthest->mx + farthest->mw)) {
          175 +                        farthest = m;
          176 +                }
          177 +                if (dx == -1 && (m->mx < farthest->mx)) {
          178 +                        farthest = m;
          179 +                }
          180 +        }
          181 +        return farthest;
          182 +}
          183 +
          184 +Monitor *
          185 +raycasty(Monitor *src, int x, int dy)
          186 +{
          187 +        Monitor *farthest = src;
          188 +        for (Monitor *m = mons; m; m = m->next) {
          189 +                int scansx = BETWEEN(x, m->mx, m->mx + m->mw);
          190 +                if (!scansx) {
          191 +                        continue;
          192 +                }
          193 +                if (dy == 1 && (m->my + m->mh > farthest->my + farthest->mh)) {
          194 +                        farthest = m;
          195 +                }
          196 +                if (dy == -1 && (m->my < farthest->my)) {
          197 +                        farthest = m;
          198 +                }
          199 +        }
          200 +        return farthest;
          201 +}
          202 +
          203  void
          204  resize(Client *c, int x, int y, int w, int h, int interact)
          205  {
          206 @@ -1609,6 +1710,23 @@ setup(void)
          207                  |LeaveWindowMask|StructureNotifyMask|PropertyChangeMask;
          208          XChangeWindowAttributes(dpy, root, CWEventMask|CWCursor, &wa);
          209          XSelectInput(dpy, root, wa.event_mask);
          210 +#ifdef XINPUT
          211 +        /* select XInput raw motion events; we can't hook into PointerMotionMask since some windows block it. */
          212 +        size_t maskbyteslen = XIMaskLen(XI_RawMotion);
          213 +        unsigned char *maskbytes = calloc(maskbyteslen, sizeof(unsigned char));
          214 +        XISetMask(maskbytes, XI_RawMotion);
          215 +        XIEventMask mask;
          216 +        int _unused;
          217 +        if (!XQueryExtension(dpy, "XInputExtension", &xinputextensionop,
          218 +                             &_unused, &_unused)) {
          219 +                fprintf(stderr, "XInputExtension not found");
          220 +                exit(1);
          221 +        }
          222 +        mask.deviceid = XIAllMasterDevices;
          223 +        mask.mask_len = maskbyteslen * sizeof(unsigned char);
          224 +        mask.mask = maskbytes;
          225 +        XISelectEvents(dpy, root, &mask, 1);
          226 +#endif /* XINPUT */
          227          grabkeys();
          228          focus(NULL);
          229  }
          230 -- 
          231 2.46.0
          232