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



Reply via email to