URI:
       [dwm][patches][clkanywhere] Add ClkAnywhere click type for location-agnostic mouse bindings - sites - public wiki contents of suckless.org
  HTML git clone git://git.suckless.org/sites
   DIR Log
   DIR Files
   DIR Refs
       ---
   DIR commit 0ce088b70ab72822c96c078d8f5ff740662314e2
   DIR parent af043eaf6ca068f0c4f0f011400d1c30d5f72e5a
  HTML Author: Jameel Sawafta <jsawafta@restaurant365.com>
       Date:   Thu, 22 Jan 2026 16:02:42 +0200
       
       [dwm][patches][clkanywhere] Add ClkAnywhere click type for location-agnostic mouse bindings
       
       Diffstat:
         A dwm.suckless.org/patches/clkanywhe… |     119 +++++++++++++++++++++++++++++++
         A dwm.suckless.org/patches/clkanywhe… |      33 +++++++++++++++++++++++++++++++
       
       2 files changed, 152 insertions(+), 0 deletions(-)
       ---
   DIR diff --git a/dwm.suckless.org/patches/clkanywhere/dwm-clkanywhere-20260122-a9aa0d8.diff b/dwm.suckless.org/patches/clkanywhere/dwm-clkanywhere-20260122-a9aa0d8.diff
       @@ -0,0 +1,119 @@
       +From ce289911cbbb48ce3900e434ac4d1f5a3fa35400 Mon Sep 17 00:00:00 2001
       +From: jameel-sawafta <jameelhsawafta@gmail.com>
       +Date: Thu, 22 Jan 2026 15:47:37 +0200
       +Subject: [PATCH] dwm: add ClkAnywhere and viewnext/viewprev for cyclic tag
       + navigation
       +
       +---
       + config.def.h |  8 +++++++-
       + dwm.c        | 35 ++++++++++++++++++++++++++++++++---
       + 2 files changed, 39 insertions(+), 4 deletions(-)
       +
       +diff --git a/config.def.h b/config.def.h
       +index 81c3fc0..8c850be 100644
       +--- a/config.def.h
       ++++ b/config.def.h
       +@@ -1,5 +1,9 @@
       + /* See LICENSE file for copyright and license details. */
       + 
       ++/* mouse buttons */
       ++#define Button8 8
       ++#define Button9 9
       ++
       + /* appearance */
       + static const unsigned int borderpx  = 1;        /* border pixel of windows */
       + static const unsigned int snap      = 32;       /* snap pixel */
       +@@ -99,7 +103,7 @@ static const Key keys[] = {
       + };
       + 
       + /* button definitions */
       +-/* click can be ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle, ClkClientWin, or ClkRootWin */
       ++/* click can be ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle, ClkClientWin, ClkRootWin, or ClkAnywhere */
       + static const Button buttons[] = {
       +         /* click                event mask      button          function        argument */
       +         { ClkLtSymbol,          0,              Button1,        setlayout,      {0} },
       +@@ -113,5 +117,7 @@ static const Button buttons[] = {
       +         { ClkTagBar,            0,              Button3,        toggleview,     {0} },
       +         { ClkTagBar,            MODKEY,         Button1,        tag,            {0} },
       +         { ClkTagBar,            MODKEY,         Button3,        toggletag,      {0} },
       ++        { ClkAnywhere,          MODKEY,         Button9,        viewnext,       {0} },
       ++        { ClkAnywhere,          MODKEY,         Button8,        viewprev,       {0} },
       + };
       + 
       +diff --git a/dwm.c b/dwm.c
       +index 53b393e..3ed105f 100644
       +--- a/dwm.c
       ++++ b/dwm.c
       +@@ -64,7 +64,7 @@ enum { NetSupported, NetWMName, NetWMState, NetWMCheck,
       +        NetWMWindowTypeDialog, NetClientList, NetLast }; /* EWMH atoms */
       + enum { WMProtocols, WMDelete, WMState, WMTakeFocus, WMLast }; /* default atoms */
       + enum { ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle,
       +-       ClkClientWin, ClkRootWin, ClkLast }; /* clicks */
       ++       ClkClientWin, ClkRootWin, ClkAnywhere, ClkLast }; /* clicks */
       + 
       + typedef union {
       +         int i;
       +@@ -226,6 +226,8 @@ static void updatetitle(Client *c);
       + static void updatewindowtype(Client *c);
       + static void updatewmhints(Client *c);
       + static void view(const Arg *arg);
       ++static void viewnext(const Arg *arg);
       ++static void viewprev(const Arg *arg);
       + static Client *wintoclient(Window w);
       + static Monitor *wintomon(Window w);
       + static int xerror(Display *dpy, XErrorEvent *ee);
       +@@ -451,7 +453,8 @@ buttonpress(XEvent *e)
       +                 click = ClkClientWin;
       +         }
       +         for (i = 0; i < LENGTH(buttons); i++)
       +-                if (click == buttons[i].click && buttons[i].func && buttons[i].button == ev->button
       ++                if ((click == buttons[i].click || buttons[i].click == ClkAnywhere)
       ++                && buttons[i].func && buttons[i].button == ev->button
       +                 && CLEANMASK(buttons[i].mask) == CLEANMASK(ev->state))
       +                         buttons[i].func(click == ClkTagBar && buttons[i].arg.i == 0 ? &arg : &buttons[i].arg);
       + }
       +@@ -940,7 +943,7 @@ grabbuttons(Client *c, int focused)
       +                         XGrabButton(dpy, AnyButton, AnyModifier, c->win, False,
       +                                 BUTTONMASK, GrabModeSync, GrabModeSync, None, None);
       +                 for (i = 0; i < LENGTH(buttons); i++)
       +-                        if (buttons[i].click == ClkClientWin)
       ++                        if (buttons[i].click == ClkClientWin || buttons[i].click == ClkAnywhere)
       +                                 for (j = 0; j < LENGTH(modifiers); j++)
       +                                         XGrabButton(dpy, buttons[i].button,
       +                                                 buttons[i].mask | modifiers[j],
       +@@ -2062,6 +2065,32 @@ view(const Arg *arg)
       +         arrange(selmon);
       + }
       + 
       ++void
       ++viewnext(const Arg *arg)
       ++{
       ++        unsigned int i;
       ++        unsigned int curtag = selmon->tagset[selmon->seltags] & TAGMASK;
       ++
       ++        for (i = 0; i < LENGTH(tags) && !(curtag & (1 << i)); i++);
       ++        i = (i + 1) % LENGTH(tags);
       ++
       ++        Arg a = {.ui = 1 << i};
       ++        view(&a);
       ++}
       ++
       ++void
       ++viewprev(const Arg *arg)
       ++{
       ++        unsigned int i;
       ++        unsigned int curtag = selmon->tagset[selmon->seltags] & TAGMASK;
       ++
       ++        for (i = 0; i < LENGTH(tags) && !(curtag & (1 << i)); i++);
       ++        i = (i == 0) ? LENGTH(tags) - 1 : i - 1;
       ++
       ++        Arg a = {.ui = 1 << i};
       ++        view(&a);
       ++}
       ++
       + Client *
       + wintoclient(Window w)
       + {
       +-- 
       +2.52.0
       +
   DIR diff --git a/dwm.suckless.org/patches/clkanywhere/index.md b/dwm.suckless.org/patches/clkanywhere/index.md
       @@ -0,0 +1,33 @@
       +clkanywhere
       +===========
       +
       +Description
       +-----------
       +This patch adds a new click type `ClkAnywhere` that matches any click location
       +(bar, windows, root window). This allows defining mouse button bindings that
       +work anywhere on the screen with a single config entry, rather than duplicating
       +bindings for each click location.
       +
       +The patch also includes `viewnext` and `viewprev` functions for cyclic tag
       +navigation with wrap-around (tag 9 wraps to tag 1 and vice versa), as well as
       +`Button8` and `Button9` definitions for extended mouse buttons.
       +
       +Default bindings
       +----------------
       +* `Mod+Button9` - view the next tag (anywhere on screen)
       +* `Mod+Button8` - view the previous tag (anywhere on screen)
       +
       +Example usage
       +-------------
       +You can bind any function to work anywhere on screen:
       +
       +        { ClkAnywhere,          MODKEY,         Button9,        viewnext,       {0} },
       +        { ClkAnywhere,          MODKEY,         Button8,        viewprev,       {0} },
       +
       +Download
       +--------
       +* [dwm-clkanywhere-20260122-a9aa0d8.diff](dwm-clkanywhere-20260122-a9aa0d8.diff)
       +
       +Author
       +------
       +* Jameel Sawafta - <jameelhsawafta@gmail.com>