lightweight X11 utility to dim the screen and/or keyboard backlight when idle
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Add a -K option to only watch for keyboard input to reset idle

Use XInput to list devices and find the master keyboard device id,
then find the corresponding "DEVICEIDLETIME #" idle timer to listen
to instead of the global IDLETIME timer.

+48 -9
+1 -1
Makefile
··· 14 14 X11BASE ?= /usr/X11R6 15 15 INCLUDES?= -I$(X11BASE)/include 16 16 LDPATH ?= -L$(X11BASE)/lib 17 - LIBS += -lX11 -lXrandr -lXext -lm 17 + LIBS += -lX11 -lXrandr -lXext -lXi -lm 18 18 19 19 PROG = xdimmer 20 20 OBJS = xdimmer.o
+4 -1
xdimmer.1
··· 1 - .Dd $Mdocdate: August 27 2019$ 1 + .Dd $Mdocdate: January 18 2024$ 2 2 .Dt XDIMMER 1 3 3 .Os 4 4 .Sh NAME ··· 10 10 .Op Fl a 11 11 .Op Fl b Ar brighten steps 12 12 .Op Fl d 13 + .Op Fl K 13 14 .Op Fl k 14 15 .Op Fl n 15 16 .Op Fl p Ar percent ··· 58 59 steps. 59 60 .It Fl d 60 61 Print debugging messages to stdout. 62 + .It Fl K 63 + Only listen for keyboard input when resetting the idle timer. 61 64 .It Fl k 62 65 Affect the keyboard backlight as well as the screen backlight. 63 66 Currently only supported on OpenBSD.
+43 -7
xdimmer.c
··· 61 61 #include <X11/Xlib.h> 62 62 #include <X11/extensions/sync.h> 63 63 #include <X11/extensions/Xrandr.h> 64 + #include <X11/extensions/XInput.h> 65 + #include <X11/extensions/XInput2.h> 64 66 65 67 #define DEFAULT_DIM_TIMEOUT 120 66 68 #define DEFAULT_DIM_PERCENTAGE 10 ··· 120 122 static int dimmed = 0; 121 123 static int dim_screen = 1; 122 124 static int use_als = 0; 125 + static int kbd_idle_only = 0; 123 126 124 127 /* ALS reading */ 125 128 static float als = -1; ··· 154 157 { 155 158 int ch; 156 159 157 - while ((ch = getopt(argc, argv, "ab:dknp:s:t:")) != -1) { 160 + while ((ch = getopt(argc, argv, "ab:dkKnp:s:t:")) != -1) { 158 161 const char *errstr; 159 162 160 163 switch (ch) { ··· 180 183 #endif 181 184 dim_kbd = 1; 182 185 break; 186 + case 'K': 187 + kbd_idle_only = 1; 188 + break; 183 189 case 'n': 184 190 dim_screen = 0; 185 191 break; ··· 189 195 errx(2, "dim percentage: %s", errstr); 190 196 break; 191 197 case 's': 192 - dim_steps = strtonum(optarg, 1, 100, &errstr); 198 + dim_steps = strtonum(optarg, 1, 500, &errstr); 193 199 if (errstr) 194 200 errx(2, "dim steps: %s", errstr); 195 201 break; ··· 241 247 dim_timeout)); 242 248 if (use_als) 243 249 DPRINTF(("automatically updating brightness from ALS\n")); 250 + if (kbd_idle_only) 251 + DPRINTF(("only watching idle state of keyboard\n")); 244 252 245 253 signal(SIGINT, bail); 246 254 signal(SIGTERM, bail); ··· 261 269 XSyncSystemCounter *counters; 262 270 XSyncAlarm idle_alarm = None; 263 271 XSyncAlarm reset_alarm = None; 272 + XIDeviceInfo *xinfo; 273 + char masdname[25]; 264 274 int sync_event, error; 265 - int major, minor, ncounters; 266 - int i; 275 + int major, minor, ncounters, ndevices; 276 + int i, j; 267 277 268 278 if (XSyncQueryExtension(dpy, &sync_event, &error) != True) 269 279 errx(1, "no sync extension available"); 270 280 271 281 XSyncInitialize(dpy, &major, &minor); 272 282 283 + if (kbd_idle_only) { 284 + xinfo = XIQueryDevice(dpy, XIAllDevices, &ndevices); 285 + masdname[0] = '\0'; 286 + for (j = 0; j < ndevices; j++) { 287 + if (xinfo[j].use != XIMasterKeyboard) 288 + continue; 289 + 290 + snprintf(masdname, sizeof(masdname), 291 + "DEVICEIDLETIME %d", xinfo[j].deviceid); 292 + break; 293 + } 294 + if (masdname[0] == '\0') 295 + errx(1, "no xinput master keyboard device found"); 296 + } 297 + 273 298 counters = XSyncListSystemCounters(dpy, &ncounters); 274 299 for (i = 0; i < ncounters; i++) { 275 - if (!strcmp(counters[i].name, "IDLETIME")) { 276 - idler_counter = counters[i].counter; 277 - break; 300 + if (kbd_idle_only) { 301 + if (strcmp(counters[i].name, masdname) == 0) { 302 + DPRINTF(("using idle time of %s\n", 303 + counters[i].name)); 304 + idler_counter = counters[i].counter; 305 + break; 306 + } 307 + } else { 308 + if (strcmp(counters[i].name, "IDLETIME") == 0) { 309 + idler_counter = counters[i].counter; 310 + break; 311 + } 278 312 } 279 313 } 280 314 XSyncFreeSystemCounterList(counters); 315 + if (kbd_idle_only) 316 + XIFreeDeviceInfo(xinfo); 281 317 282 318 if (!idler_counter) 283 319 errx(1, "no idle counter");