diff --git a/suckless/slock/config.def.h b/suckless/slock/config.def.h index 9855e211..e7106fb9 100644 --- a/suckless/slock/config.def.h +++ b/suckless/slock/config.def.h @@ -3,10 +3,14 @@ static const char *user = "nobody"; static const char *group = "nogroup"; static const char *colorname[NUMCOLS] = { - [INIT] = "black", /* after initialization */ + [BG] = "black", /* background */ + [INIT] = "#4f525c", /* after initialization */ [INPUT] = "#005577", /* during input */ [FAILED] = "#CC3333", /* wrong password */ }; /* treat a cleared input like a wrong password (color) */ static const int failonclear = 1; + +/* size of square in px */ +static const int squaresize = 50; diff --git a/suckless/slock/patches/slock-squares-1.5.diff b/suckless/slock/patches/slock-squares-1.5.diff new file mode 100644 index 00000000..e9e9ad0d --- /dev/null +++ b/suckless/slock/patches/slock-squares-1.5.diff @@ -0,0 +1,157 @@ +From 2f6938b87a09abcd41fd6792a40b0bd7b088f41a Mon Sep 17 00:00:00 2001 +From: bsuth +Date: Tue, 27 Dec 2022 12:44:23 +0900 +Subject: [PATCH] Use centered squares to indicate lock state + +Instead of changing the color of the entire screen to indicate the +current lock state, draw centered squares on each monitor and change the +square colors. + +This patch requires xrandr to be active and otherwise defaults to the +original slock behavior. +--- + config.def.h | 6 +++++- + slock.c | 58 +++++++++++++++++++++++++++++++++++++++++++++------- + 2 files changed, 56 insertions(+), 8 deletions(-) + +diff --git a/config.def.h b/config.def.h +index 9855e21..e7106fb 100644 +--- a/config.def.h ++++ b/config.def.h +@@ -3,10 +3,14 @@ static const char *user = "nobody"; + static const char *group = "nogroup"; + + static const char *colorname[NUMCOLS] = { +- [INIT] = "black", /* after initialization */ ++ [BG] = "black", /* background */ ++ [INIT] = "#4f525c", /* after initialization */ + [INPUT] = "#005577", /* during input */ + [FAILED] = "#CC3333", /* wrong password */ + }; + + /* treat a cleared input like a wrong password (color) */ + static const int failonclear = 1; ++ ++/* size of square in px */ ++static const int squaresize = 50; +diff --git a/slock.c b/slock.c +index 5ae738c..0750768 100644 +--- a/slock.c ++++ b/slock.c +@@ -25,6 +25,7 @@ + char *argv0; + + enum { ++ BG, + INIT, + INPUT, + FAILED, +@@ -36,6 +37,8 @@ struct lock { + Window root, win; + Pixmap pmap; + unsigned long colors[NUMCOLS]; ++ GC gc; ++ XRRScreenResources *rrsr; + }; + + struct xrandr { +@@ -124,6 +127,44 @@ gethash(void) + return hash; + } + ++static void ++draw(Display *dpy, struct xrandr *rr, struct lock **locks, int nscreens, ++ unsigned int color) ++{ ++ int screen, crtc; ++ XRRCrtcInfo* rrci; ++ ++ if (rr->active) { ++ for (screen = 0; screen < nscreens; screen++) { ++ XSetWindowBackground(dpy, locks[screen]->win,locks[screen]->colors[BG]); ++ XClearWindow(dpy, locks[screen]->win); ++ XSetForeground(dpy, locks[screen]->gc, locks[screen]->colors[color]); ++ for (crtc = 0; crtc < locks[screen]->rrsr->ncrtc; ++crtc) { ++ rrci = XRRGetCrtcInfo(dpy, ++ locks[screen]->rrsr, ++ locks[screen]->rrsr->crtcs[crtc]); ++ /* skip disabled crtc */ ++ if (rrci->noutput > 0) ++ XFillRectangle(dpy, ++ locks[screen]->win, ++ locks[screen]->gc, ++ rrci->x + (rrci->width - squaresize) / 2, ++ rrci->y + (rrci->height - squaresize) / 2, ++ squaresize, ++ squaresize); ++ XRRFreeCrtcInfo(rrci); ++ } ++ } ++ } else { ++ for (screen = 0; screen < nscreens; screen++) { ++ XSetWindowBackground(dpy, ++ locks[screen]->win, ++ locks[screen]->colors[color]); ++ XClearWindow(dpy, locks[screen]->win); ++ } ++ } ++} ++ + static void + readpw(Display *dpy, struct xrandr *rr, struct lock **locks, int nscreens, + const char *hash) +@@ -189,12 +230,7 @@ readpw(Display *dpy, struct xrandr *rr, struct lock **locks, int nscreens, + } + color = len ? INPUT : ((failure || failonclear) ? FAILED : INIT); + if (running && oldc != color) { +- for (screen = 0; screen < nscreens; screen++) { +- XSetWindowBackground(dpy, +- locks[screen]->win, +- locks[screen]->colors[color]); +- XClearWindow(dpy, locks[screen]->win); +- } ++ draw(dpy, rr, locks, nscreens, color); + oldc = color; + } + } else if (rr->active && ev.type == rr->evbase + RRScreenChangeNotify) { +@@ -228,6 +264,7 @@ lockscreen(Display *dpy, struct xrandr *rr, int screen) + XColor color, dummy; + XSetWindowAttributes wa; + Cursor invisible; ++ XGCValues gcvalues; + + if (dpy == NULL || screen < 0 || !(lock = malloc(sizeof(struct lock)))) + return NULL; +@@ -243,7 +280,7 @@ lockscreen(Display *dpy, struct xrandr *rr, int screen) + + /* init */ + wa.override_redirect = 1; +- wa.background_pixel = lock->colors[INIT]; ++ wa.background_pixel = lock->colors[BG]; + lock->win = XCreateWindow(dpy, lock->root, 0, 0, + DisplayWidth(dpy, lock->screen), + DisplayHeight(dpy, lock->screen), +@@ -255,6 +292,10 @@ lockscreen(Display *dpy, struct xrandr *rr, int screen) + invisible = XCreatePixmapCursor(dpy, lock->pmap, lock->pmap, + &color, &color, 0, 0); + XDefineCursor(dpy, lock->win, invisible); ++ lock->gc = XCreateGC(dpy, lock->win, 0, &gcvalues); ++ XSetForeground(dpy, lock->gc, lock->colors[INIT]); ++ if (rr->active) ++ lock->rrsr = XRRGetScreenResourcesCurrent(dpy, lock->root); + + /* Try to grab mouse pointer *and* keyboard for 600ms, else fail the lock */ + for (i = 0, ptgrab = kbgrab = -1; i < 6; i++) { +@@ -388,6 +429,9 @@ main(int argc, char **argv) { + } + } + ++ /* draw the initial rectangle */ ++ draw(dpy, &rr, locks, nscreens, INIT); ++ + /* everything is now blank. Wait for the correct password */ + readpw(dpy, &rr, locks, nscreens, hash); + +-- +2.39.0 + diff --git a/suckless/slock/slock.c b/suckless/slock/slock.c index 5ae738c1..0750768e 100644 --- a/suckless/slock/slock.c +++ b/suckless/slock/slock.c @@ -25,6 +25,7 @@ char *argv0; enum { + BG, INIT, INPUT, FAILED, @@ -36,6 +37,8 @@ struct lock { Window root, win; Pixmap pmap; unsigned long colors[NUMCOLS]; + GC gc; + XRRScreenResources *rrsr; }; struct xrandr { @@ -124,6 +127,44 @@ gethash(void) return hash; } +static void +draw(Display *dpy, struct xrandr *rr, struct lock **locks, int nscreens, + unsigned int color) +{ + int screen, crtc; + XRRCrtcInfo* rrci; + + if (rr->active) { + for (screen = 0; screen < nscreens; screen++) { + XSetWindowBackground(dpy, locks[screen]->win,locks[screen]->colors[BG]); + XClearWindow(dpy, locks[screen]->win); + XSetForeground(dpy, locks[screen]->gc, locks[screen]->colors[color]); + for (crtc = 0; crtc < locks[screen]->rrsr->ncrtc; ++crtc) { + rrci = XRRGetCrtcInfo(dpy, + locks[screen]->rrsr, + locks[screen]->rrsr->crtcs[crtc]); + /* skip disabled crtc */ + if (rrci->noutput > 0) + XFillRectangle(dpy, + locks[screen]->win, + locks[screen]->gc, + rrci->x + (rrci->width - squaresize) / 2, + rrci->y + (rrci->height - squaresize) / 2, + squaresize, + squaresize); + XRRFreeCrtcInfo(rrci); + } + } + } else { + for (screen = 0; screen < nscreens; screen++) { + XSetWindowBackground(dpy, + locks[screen]->win, + locks[screen]->colors[color]); + XClearWindow(dpy, locks[screen]->win); + } + } +} + static void readpw(Display *dpy, struct xrandr *rr, struct lock **locks, int nscreens, const char *hash) @@ -189,12 +230,7 @@ readpw(Display *dpy, struct xrandr *rr, struct lock **locks, int nscreens, } color = len ? INPUT : ((failure || failonclear) ? FAILED : INIT); if (running && oldc != color) { - for (screen = 0; screen < nscreens; screen++) { - XSetWindowBackground(dpy, - locks[screen]->win, - locks[screen]->colors[color]); - XClearWindow(dpy, locks[screen]->win); - } + draw(dpy, rr, locks, nscreens, color); oldc = color; } } else if (rr->active && ev.type == rr->evbase + RRScreenChangeNotify) { @@ -228,6 +264,7 @@ lockscreen(Display *dpy, struct xrandr *rr, int screen) XColor color, dummy; XSetWindowAttributes wa; Cursor invisible; + XGCValues gcvalues; if (dpy == NULL || screen < 0 || !(lock = malloc(sizeof(struct lock)))) return NULL; @@ -243,7 +280,7 @@ lockscreen(Display *dpy, struct xrandr *rr, int screen) /* init */ wa.override_redirect = 1; - wa.background_pixel = lock->colors[INIT]; + wa.background_pixel = lock->colors[BG]; lock->win = XCreateWindow(dpy, lock->root, 0, 0, DisplayWidth(dpy, lock->screen), DisplayHeight(dpy, lock->screen), @@ -255,6 +292,10 @@ lockscreen(Display *dpy, struct xrandr *rr, int screen) invisible = XCreatePixmapCursor(dpy, lock->pmap, lock->pmap, &color, &color, 0, 0); XDefineCursor(dpy, lock->win, invisible); + lock->gc = XCreateGC(dpy, lock->win, 0, &gcvalues); + XSetForeground(dpy, lock->gc, lock->colors[INIT]); + if (rr->active) + lock->rrsr = XRRGetScreenResourcesCurrent(dpy, lock->root); /* Try to grab mouse pointer *and* keyboard for 600ms, else fail the lock */ for (i = 0, ptgrab = kbgrab = -1; i < 6; i++) { @@ -388,6 +429,9 @@ main(int argc, char **argv) { } } + /* draw the initial rectangle */ + draw(dpy, &rr, locks, nscreens, INIT); + /* everything is now blank. Wait for the correct password */ readpw(dpy, &rr, locks, nscreens, hash);