sites

public wiki contents of suckless.org
git clone git://git.suckless.org/sites
Log | Files | Refs

commit 6f5f7bec88bb2ea1b7d7b5e1f602d4b2d13e73f0
parent 0f0f6a8f64cb750cefbd17d70324f38dededa15d
Author: Matthias Schoth <mschoth@gmail.com>
Date:   Thu, 17 Feb 2022 00:31:37 +0100

[st][patch][background_image] corrections and improvements

- detect maximize/minimize events and refresh background position accordingly
- more efficient farbfeld loading
- don't exit on fail to load background, just print error
- remove not needed global Drawable

Diffstat:
Mst.suckless.org/patches/background_image/st-background-image-0.8.4.diff | 200++++++++++++++++++++++++++++++++++++++++++++++++++++++-------------------------
1 file changed, 136 insertions(+), 64 deletions(-)

diff --git a/st.suckless.org/patches/background_image/st-background-image-0.8.4.diff b/st.suckless.org/patches/background_image/st-background-image-0.8.4.diff @@ -1,12 +1,12 @@ -From fdf9692358326993f0dc6a6896cc0a7194ba6152 Mon Sep 17 00:00:00 2001 +From 2c984d74ca15806dcfa174b7e75f48c0d01a49bf Mon Sep 17 00:00:00 2001 From: Matthias Schoth <mschoth@gmail.com> -Date: Sun, 4 Jul 2021 19:18:20 +0200 +Date: Thu, 17 Feb 2022 00:23:23 +0100 Subject: [PATCH] Implements background image and pseudo transparancy support. --- - config.def.h | 8 +++++ - x.c | 91 ++++++++++++++++++++++++++++++++++++++++++++++++---- - 2 files changed, 93 insertions(+), 6 deletions(-) + config.def.h | 8 +++ + x.c | 141 +++++++++++++++++++++++++++++++++++++++++++++++---- + 2 files changed, 139 insertions(+), 10 deletions(-) diff --git a/config.def.h b/config.def.h index 6f05dce..3d352db 100644 @@ -28,7 +28,7 @@ index 6f05dce..3d352db 100644 * What program is execed by st depends of these precedence rules: * 1: program passed with -e diff --git a/x.c b/x.c -index 210f184..22653ea 100644 +index 210f184..5ecb8e5 100644 --- a/x.c +++ b/x.c @@ -14,6 +14,7 @@ @@ -47,24 +47,62 @@ index 210f184..22653ea 100644 int ch; /* char height */ int cw; /* char width */ int mode; /* window state/mode flags */ -@@ -101,6 +103,8 @@ typedef struct { +@@ -101,6 +103,7 @@ typedef struct { XVaNestedList spotlist; } ime; Draw draw; -+ Drawable bgimg; /* background image */ + GC bggc; /* Graphics Context for background */ Visual *vis; XSetWindowAttributes attrs; int scr; -@@ -151,6 +155,7 @@ static void ximinstantiate(Display *, XPointer, XPointer); +@@ -151,6 +154,9 @@ static void ximinstantiate(Display *, XPointer, XPointer); static void ximdestroy(XIM, XPointer, XPointer); static int xicdestroy(XIC, XPointer, XPointer); static void xinit(int, int); ++static void updatexy(void); ++static XImage *loadff(const char *); +static void bginit(); static void cresize(int, int); static void xresize(int, int); static void xhints(void); -@@ -820,9 +825,9 @@ xsetcolorname(int x, const char *name) +@@ -502,6 +508,12 @@ propnotify(XEvent *e) + xpev->atom == clipboard)) { + selnotify(e); + } ++ ++ if (pseudotransparency && ++ !strncmp(XGetAtomName(xw.dpy, e->xproperty.atom), "_NET_WM_STATE", 13)) { ++ updatexy(); ++ redraw(); ++ } + } + + void +@@ -532,7 +544,8 @@ selnotify(XEvent *e) + return; + } + +- if (e->type == PropertyNotify && nitems == 0 && rem == 0) { ++ if (e->type == PropertyNotify && nitems == 0 && rem == 0 && ++ !pseudotransparency) { + /* + * If there is some PropertyNotify with no data, then + * this is the signal of the selection owner that all +@@ -550,9 +563,11 @@ selnotify(XEvent *e) + * when the selection owner does send us the next + * chunk of data. + */ +- MODBIT(xw.attrs.event_mask, 1, PropertyChangeMask); +- XChangeWindowAttributes(xw.dpy, xw.win, CWEventMask, ++ if (!pseudotransparency) { ++ MODBIT(xw.attrs.event_mask, 1, PropertyChangeMask); ++ XChangeWindowAttributes(xw.dpy, xw.win, CWEventMask, + &xw.attrs); ++ } + + /* + * Deleting the property is the transfer start signal. +@@ -820,9 +835,9 @@ xsetcolorname(int x, const char *name) void xclear(int x1, int y1, int x2, int y2) { @@ -77,73 +115,108 @@ index 210f184..22653ea 100644 } void -@@ -1207,6 +1212,65 @@ xinit(int cols, int rows) +@@ -1207,6 +1222,100 @@ xinit(int cols, int rows) xsel.xtarget = XA_STRING; } ++void ++updatexy() ++{ ++ Window child; ++ XTranslateCoordinates(xw.dpy, xw.win, DefaultRootWindow(xw.dpy), 0, 0, ++ &win.x, &win.y, &child); ++} ++ +/* -+ * initialize background image ++ * load farbfeld file to XImage + */ -+void -+bginit() ++XImage* ++loadff(const char *filename) +{ -+ uint32_t hdr[4], bgw, bgh, i = 0; -+ char buf[8], *image32; -+ FILE *bgf = fopen(bgfile, "rb"); -+ XGCValues gcvalues; -+ XImage *bgxi; ++ uint32_t i, hdr[4], w, h, size; ++ uint64_t *data; ++ FILE *f = fopen(filename, "rb"); + -+ if (bgf == NULL) die("could not load background image.\n"); ++ if (f == NULL) { ++ fprintf(stderr, "could not load background image.\n"); ++ return NULL; ++ } + -+ if (fread(hdr, sizeof(*hdr), LEN(hdr), bgf) != LEN(hdr)) -+ if (ferror(bgf)) -+ die("fread:"); -+ else -+ die("fread: Unexpected end of file\n"); ++ if (fread(hdr, sizeof(*hdr), LEN(hdr), f) != LEN(hdr)) ++ if (ferror(f)) { ++ fprintf(stderr, "fread:"); ++ return NULL; ++ } ++ else { ++ fprintf(stderr, "fread: Unexpected end of file\n"); ++ return NULL; ++ } + -+ if (memcmp("farbfeld", hdr, sizeof("farbfeld") - 1)) -+ die("Invalid magic value"); ++ if (memcmp("farbfeld", hdr, sizeof("farbfeld") - 1)) { ++ fprintf(stderr, "Invalid magic value"); ++ return NULL; ++ } + -+ bgw = ntohl(hdr[2]); -+ bgh = ntohl(hdr[3]); -+ image32 = (char *)malloc(bgw * bgh * 4 * sizeof(char)); ++ w = ntohl(hdr[2]); ++ h = ntohl(hdr[3]); ++ size = w * h; ++ data = malloc(size * sizeof(uint64_t)); + -+ while (i < bgh * bgw * 4) { -+ if (fread(buf, sizeof(*buf), LEN(buf), bgf) != LEN(buf)) -+ if (ferror(bgf)) -+ die("fread:"); -+ else -+ die("fread: Unexpected end of file"); ++ if (fread(data, sizeof(uint64_t), size, f) != size) ++ if (ferror(f)) { ++ fprintf(stderr, "fread:"); ++ return NULL; ++ } ++ else { ++ fprintf(stderr, "fread: Unexpected end of file"); ++ return NULL; ++ } + -+ image32[i++] = buf[4]; /* convert 16 bit RGBA to 8 bit BGRA */ -+ image32[i++] = buf[2]; -+ image32[i++] = buf[0]; -+ image32[i++] = buf[6]; -+ } ++ fclose(f); ++ ++ for (i = 0; i < size; i++) ++ data[i] = (data[i] & 0x00000000000000FF) << 16 | ++ (data[i] & 0x0000000000FF0000) >> 8 | ++ (data[i] & 0x000000FF00000000) >> 32; ++ ++ XImage *xi = XCreateImage(xw.dpy, DefaultVisual(xw.dpy, xw.scr), ++ DefaultDepth(xw.dpy, xw.scr), ZPixmap, 0, ++ (char *)data, w, h, 32, w * 8); ++ xi->bits_per_pixel = 64; ++ return xi; ++} ++ ++/* ++ * initialize background image ++ */ ++void ++bginit() ++{ ++ XGCValues gcvalues; ++ Drawable bgimg; ++ XImage *bgxi = loadff(bgfile); + -+ fclose(bgf); -+ bgxi = XCreateImage(xw.dpy, DefaultVisual(xw.dpy, xw.scr), -+ 24, ZPixmap, 0, image32, bgw, bgh, 32, 0); -+ xw.bgimg = XCreatePixmap(xw.dpy, xw.win, bgw, bgh, -+ DefaultDepth(xw.dpy, xw.scr)); -+ XPutImage(xw.dpy, xw.bgimg, dc.gc, bgxi, 0, 0, 0, 0, bgw, bgh); -+ XDestroyImage(bgxi); + memset(&gcvalues, 0, sizeof(gcvalues)); + xw.bggc = XCreateGC(xw.dpy, xw.win, 0, &gcvalues); -+ XSetTile(xw.dpy, xw.bggc, xw.bgimg); ++ if (!bgxi) return; ++ bgimg = XCreatePixmap(xw.dpy, xw.win, bgxi->width, bgxi->height, ++ DefaultDepth(xw.dpy, xw.scr)); ++ XPutImage(xw.dpy, bgimg, dc.gc, bgxi, 0, 0, 0, 0, bgxi->width, ++ bgxi->height); ++ XDestroyImage(bgxi); ++ XSetTile(xw.dpy, xw.bggc, bgimg); + XSetFillStyle(xw.dpy, xw.bggc, FillTiled); + if (pseudotransparency) { -+ XWindowAttributes xwa; -+ XGetWindowAttributes(xw.dpy, xw.win, &xwa); -+ win.x = xwa.x; -+ win.y = xwa.y; ++ updatexy(); ++ MODBIT(xw.attrs.event_mask, 1, PropertyChangeMask); ++ XChangeWindowAttributes(xw.dpy, xw.win, CWEventMask, &xw.attrs); + } +} + int xmakeglyphfontspecs(XftGlyphFontSpec *specs, const Glyph *glyphs, int len, int x, int y) { -@@ -1447,7 +1511,10 @@ xdrawglyphfontspecs(const XftGlyphFontSpec *specs, Glyph base, int len, int x, i +@@ -1447,7 +1556,10 @@ xdrawglyphfontspecs(const XftGlyphFontSpec *specs, Glyph base, int len, int x, i xclear(winx, winy + win.ch, winx + width, win.h); /* Clean up the region we want to draw to. */ @@ -155,29 +228,28 @@ index 210f184..22653ea 100644 /* Set the clip region because Xft is sometimes dirty. */ r.x = 0; -@@ -1855,8 +1922,19 @@ cmessage(XEvent *e) +@@ -1855,9 +1967,17 @@ cmessage(XEvent *e) void resize(XEvent *e) { - if (e->xconfigure.width == win.w && e->xconfigure.height == win.h) - return; +- + if (pseudotransparency) { + if (e->xconfigure.width == win.w && -+ e->xconfigure.height == win.h && -+ e->xconfigure.x == win.x && e->xconfigure.y == win.y) ++ e->xconfigure.height == win.h && ++ e->xconfigure.x == win.x && e->xconfigure.y == win.y) + return; -+ -+ win.x = e->xconfigure.x; -+ win.y = e->xconfigure.y; ++ updatexy(); + } else { + if (e->xconfigure.width == win.w && -+ e->xconfigure.height == win.h) ++ e->xconfigure.height == win.h) + return; + } - cresize(e->xconfigure.width, e->xconfigure.height); } -@@ -2041,6 +2119,7 @@ run: + +@@ -2041,6 +2161,7 @@ run: rows = MAX(rows, 1); tnew(cols, rows); xinit(cols, rows); @@ -186,5 +258,5 @@ index 210f184..22653ea 100644 selinit(); run(); -- -2.32.0 +2.35.1