On Tue, Aug 12, 2025 at 01:45:31PM +0200, arsen...@tuta.io wrote: > Set update interval for MotionNotify based on the highest > refresh rate among active outputs. Before, the interval was > constant - (1000 / 60) ms. > This change allows for a smoother image if output's refresh rate > is higher than 60 Hz. > > What do you think? > --- > config.mk | 3 ++- > dwm.c | 46 +++++++++++++++++++++++++++++++++++++++++++--- > 2 files changed, 45 insertions(+), 4 deletions(-) > > diff --git a/config.mk b/config.mk > index 8efca9a..8c3c202 100644 > --- a/config.mk > +++ b/config.mk > @@ -13,6 +13,7 @@ X11LIB = /usr/X11R6/lib > # Xinerama, comment if you don't want it > XINERAMALIBS = -lXinerama > XINERAMAFLAGS = -DXINERAMA > +XRANDRLIBS = -lXrandr > > # freetype > FREETYPELIBS = -lfontconfig -lXft > @@ -23,7 +24,7 @@ FREETYPEINC = /usr/include/freetype2 > > # includes and libs > INCS = -I${X11INC} -I${FREETYPEINC} > -LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} ${FREETYPELIBS} > +LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} ${XRANDRLIBS} ${FREETYPELIBS} > > # flags > CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_XOPEN_SOURCE=700L > -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS} > diff --git a/dwm.c b/dwm.c > index 1443802..d2c2882 100644 > --- a/dwm.c > +++ b/dwm.c > @@ -39,6 +39,7 @@ > #ifdef XINERAMA > #include <X11/extensions/Xinerama.h> > #endif /* XINERAMA */ > +#include <X11/extensions/Xrandr.h> > #include <X11/Xft/Xft.h> > > #include "drw.h" > @@ -188,6 +189,7 @@ static void pop(Client *c); > static void propertynotify(XEvent *e); > static void quit(const Arg *arg); > static Monitor *recttomon(int x, int y, int w, int h); > +static double refresh_rate(XRRModeInfo *mode_info); > static void resize(Client *c, int x, int y, int w, int h, int interact); > static void resizeclient(Client *c, int x, int y, int w, int h); > static void resizemouse(const Arg *arg); > @@ -266,6 +268,7 @@ static Display *dpy; > static Drw *drw; > static Monitor *mons, *selmon; > static Window root, wmcheckwin; > +static unsigned int rate = 60; > > /* configuration, allows nested code to access above variables */ > #include "config.h" > @@ -1171,7 +1174,7 @@ movemouse(const Arg *arg) > handler[ev.type](&ev); > break; > case MotionNotify: > - if ((ev.xmotion.time - lasttime) <= (1000 / 60)) > + if ((ev.xmotion.time - lasttime) <= (1000 / rate)) > continue; > lasttime = ev.xmotion.time; > > @@ -1274,6 +1277,17 @@ recttomon(int x, int y, int w, int h) > return r; > } > > +static double > +refresh_rate(XRRModeInfo *m) > +{ > + /* from xrandr(1) source code */ > + double r = 0.0; > + if (m->hTotal && m->vTotal) > + r = ((double) m->dotClock / > + ((double) m->hTotal * (double) m->vTotal)); > + return r; > +} > + > void > resize(Client *c, int x, int y, int w, int h, int interact) > { > @@ -1325,7 +1339,7 @@ resizemouse(const Arg *arg) > handler[ev.type](&ev); > break; > case MotionNotify: > - if ((ev.xmotion.time - lasttime) <= (1000 / 60)) > + if ((ev.xmotion.time - lasttime) <= (1000 / rate)) > continue; > lasttime = ev.xmotion.time; > > @@ -1538,8 +1552,10 @@ setmfact(const Arg *arg) > void > setup(void) > { > - int i; > + int i, j, k, n; > XSetWindowAttributes wa; > + XRRScreenResources *res; > + XRRMonitorInfo *monitors; > Atom utf8string; > struct sigaction sa; > > @@ -1557,6 +1573,30 @@ setup(void) > sw = DisplayWidth(dpy, screen); > sh = DisplayHeight(dpy, screen); > root = RootWindow(dpy, screen); > + > + /* refresh rate */ > + monitors = XRRGetMonitors(dpy, root, 1, &n); > + res = XRRGetScreenResources(dpy, root); > + XRROutputInfo *o; > + XRRCrtcInfo *crtc; > + XRRModeInfo *mode; > + double r = 0.0; > + for (i = 0; i < n; i++) { > + for (j = 0; j < monitors[i].noutput; j++) { > + o = XRRGetOutputInfo(dpy, res, monitors[i].outputs[j]); > + crtc = XRRGetCrtcInfo(dpy, res, o->crtc); > + for (k = 0; k < res->nmode; k++) { > + mode = &res->modes[k]; > + if (crtc->mode == mode->id) { > + r = MAX(refresh_rate(mode), r); > + break; > + } > + } > + } > + } > + if (r) > + rate = (unsigned int)r + 1; > + > drw = drw_create(dpy, screen, root, sw, sh); > if (!drw_fontset_create(drw, fonts, LENGTH(fonts))) > die("no fonts could be loaded."); > -- > 2.50.1 > > >
Hi, I like the idea and I think it has also been reported a few times over the years. For simplicity a config.h variable is OK I think. I have committed the below diff which makes it a bit more clear what to modify and bumped the default from 60 to 120: https://git.suckless.org/dwm/commit/74edc27caa65aba9ea8d1fe03d26e3b449f79590.html iirc there can be some lag on old machines or ones with software rendering etc. Then they can change the default to 60 again or lower. -- Kind regards, Hiltjo