From b89b2e566c7c62988adb2075173e17f245d9862c Mon Sep 17 00:00:00 2001 From: Igor Kolokolnikov Date: Tue, 15 Sep 2026 18:06:23 -0700 Subject: [PATCH] More appropriate run loop. --- Makefile | 4 +++ README | 4 ++- slock.c | 85 ++++++++++++++++++++++++++++++-------------------------- 3 files changed, 52 insertions(+), 41 deletions(-) diff --git a/Makefile b/Makefile index a11f414..21463f0 100644 --- a/Makefile +++ b/Makefile @@ -88,5 +88,9 @@ perf: run: @ clear; ./$(EXE) +install: + chmod u+s ./$(EXE) + mv ./$(EXE) /usr/local/bin + clean: @ rm -rf $(EXE) $(EXE).dSYM diff --git a/README b/README index 971e482..2998687 100644 --- a/README +++ b/README @@ -10,8 +10,10 @@ In order to build slock you need the Xlib header files. Notes ------------ -As of right now, this implementation assumes that the user has no automatic +* As of right now, this implementation assumes that the user has no automatic display management utilities, like mutter. +* Also, I have not tested this program with multiple displays. The assumption +is that you have one display, for now. Installation diff --git a/slock.c b/slock.c index 49da1d3..e3d19e2 100644 --- a/slock.c +++ b/slock.c @@ -628,11 +628,13 @@ readpw(struct arena *arena, struct timeval tv; KeySym ksym; XEvent ev; - unsigned long long last_millis; + unsigned long long rendering_timeout_millis; struct dpms_state dpms_state; struct fonts fonts; int error; + int needs_rendering; + len = 0; running = 1; failure = 0; @@ -655,35 +657,35 @@ readpw(struct arena *arena, if(!load_fonts(&fonts)) die("slock: load_fonts\n"); - render_screen(arena, - dpy, locks, - fonts.main_face, fonts.secondary_face, - len); - - last_millis = millis(); + needs_rendering = 1; + + rendering_timeout_millis = millis(); + while(running) { fd_set fds; FD_ZERO(&fds); FD_SET(xfd, &fds); FD_SET(tfd, &fds); - XFlush(dpy); - update_timerfd(tfd); + XFlush(dpy); + while(XPending(dpy)) { XNextEvent(dpy, &ev); if(ev.type == MotionNotify) { + needs_rendering = 1; dson = 1; set_screen_on(dpy); } else if (ev.type == KeyPress) { explicit_bzero(&buf, sizeof(buf)); num = XLookupString(&ev.xkey, buf, sizeof(buf), &ksym, 0); + needs_rendering = 1; + if(ksym != XK_Escape) { dson = 1; - set_screen_on(dpy); } if (IsKeypadKey(ksym)) { @@ -730,11 +732,6 @@ readpw(struct arena *arena, exit(1); #else dson = !dson; - if(dson) - set_screen_on(dpy); - else - set_screen_off(dpy); - continue; #endif } @@ -796,34 +793,42 @@ readpw(struct arena *arena, for(screen = 0; screen < nscreens; screen++) XRaiseWindow(dpy, locks[screen]->win); } - - /* cap redraw at roughly 30 FPS */ - if(millis() - last_millis >= 33) { - render_screen(arena, - dpy, locks, - fonts.main_face, fonts.secondary_face, - len); - last_millis = millis(); - } } - int ret; - if(displaytimeout > 0 && dson) { - tv.tv_sec = displaytimeout; - tv.tv_usec = 0; - ret = select(tfd + 1, &fds, 0, 0, &tv); - } else { - ret = select(tfd + 1, &fds, 0, 0, 0); - } - if (ret == 0) { - dson = 0; + if(dson) + set_screen_on(dpy); + else set_screen_off(dpy); - } else if (ret > 0 && FD_ISSET(xfd, &fds)) { - } else if (ret > 0 && FD_ISSET(tfd, &fds)) { - render_screen(arena, - dpy, locks, - fonts.main_face, fonts.secondary_face, - len); + + render_screen(arena, + dpy, locks, + fonts.main_face, fonts.secondary_face, + len); + + if(millis() - rendering_timeout_millis >= 500) { + needs_rendering = 0; + rendering_timeout_millis = millis(); + } + + int ret; + if(needs_rendering) { + tv.tv_sec = 0; + tv.tv_usec = 33*1000; /* ~30 FPS */ + ret = select(0, 0, 0, 0, &tv); + } else { + if(displaytimeout > 0 && dson) { + tv.tv_sec = displaytimeout; + tv.tv_usec = 0; + ret = select(tfd + 1, &fds, 0, 0, &tv); + } else { + ret = select(tfd + 1, &fds, 0, 0, 0); + } + if(ret == 0) { + dson = 0; + set_screen_off(dpy); + } else if(ret > 0 && FD_ISSET(xfd, &fds)) { + } else if(ret > 0 && FD_ISSET(tfd, &fds)) { + } } }