From 3c5363dd7a50219d76f8be3c1e3282cd420a0447 Mon Sep 17 00:00:00 2001 From: salmonik Date: Fri, 6 Feb 2026 22:17:01 +0100 Subject: apply visualbell2 patches - basic and enhanced --- config.def.h | 19 +++++++++++++++++++ config.h | 19 +++++++++++++++++++ x.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 92 insertions(+) diff --git a/config.def.h b/config.def.h index 375c248..e358fba 100644 --- a/config.def.h +++ b/config.def.h @@ -73,6 +73,25 @@ static unsigned int cursorthickness = 2; */ static int bellvolume = 0; +/* visual-bell timeout in ms (0 to disable visual-bell) */ +static int vbelltimeout = 150; + +/* choose predefined visual-bell cells to inverse, or define your own logic */ +#define VBCELL x==0 || x==right || y==0 || y==bottom /* border */ +// #define VBCELL 1 /* all cells - whole screen */ +// #define VBCELL y==bottom && x>right-2 /* bottom-right */ + +static int vbellmode = 1; +/* vbellmode: 0: invert cells. 1: draw a circle with these parameters: + * - base and outline colors (colorname index - see below) + * - radius: relative to window width, or if negative: relative to cell-width + * - position: relative to window width/height (0 and 1 are at the edges) */ +static int vbellcolor = 3; +static int vbellcolor_outline = 1; +static float vbellradius = 0.03; +static float vbellx = 0.5; +static float vbelly = 0.5; + /* default TERM value */ char *termname = "st-256color"; diff --git a/config.h b/config.h index a860986..b47e954 100644 --- a/config.h +++ b/config.h @@ -73,6 +73,25 @@ static unsigned int cursorthickness = 2; */ static int bellvolume = 0; +/* visual-bell timeout in ms (0 to disable visual-bell) */ +static int vbelltimeout = 150; + +/* choose predefined visual-bell cells to inverse, or define your own logic */ +#define VBCELL x==0 || x==right || y==0 || y==bottom /* border */ +// #define VBCELL 1 /* all cells - whole screen */ +// #define VBCELL y==bottom && x>right-2 /* bottom-right */ + +static int vbellmode = 1; +/* vbellmode: 0: invert cells. 1: draw a circle with these parameters: + * - base and outline colors (colorname index - see below) + * - radius: relative to window width, or if negative: relative to cell-width + * - position: relative to window width/height (0 and 1 are at the edges) */ +static int vbellcolor = 3; +static int vbellcolor_outline = 1; +static float vbellradius = 0.03; +static float vbellx = 0.5; +static float vbelly = 0.5; + /* default TERM value */ char *termname = "st-256color"; diff --git a/x.c b/x.c index 1f2becf..8c9a74e 100644 --- a/x.c +++ b/x.c @@ -1674,6 +1674,43 @@ xsettitle(char *p) XFree(prop.value); } + +static int vbellset = 0; /* 1 during visual bell, 0 otherwise */ +static struct timespec lastvbell = {0}; + +static int +isvbellcell(int x, int y) +{ + int right = win.tw / win.cw - 1, bottom = win.th / win.ch - 1; + return vbellmode == 0 && (VBCELL); /* logic defined at config.h */ +} + +static void +vbellbegin() { + clock_gettime(CLOCK_MONOTONIC, &lastvbell); + if (vbellset) + return; + vbellset = 1; + redraw(); + XFlush(xw.dpy); +} + +static void +xfillcircle(int x, int y, int r, uint color_ix) +{ + XSetForeground(xw.dpy, dc.gc, dc.col[color_ix].pixel); + XFillArc(xw.dpy, xw.buf, dc.gc, x - r, y - r, r * 2, r * 2, 0, 360*64); +} + +static void +xdrawvbell() { + int r = round(vbellradius * (vbellradius > 0 ? win.w : -win.cw)); + int x = borderpx + r + vbellx * (win.tw - 2 * r); + int y = borderpx + r + vbelly * (win.th - 2 * r); + xfillcircle(x, y, r, vbellcolor_outline); + xfillcircle(x, y, r / 1.2, vbellcolor); /* 1.2 - an artistic choice */ +} + int xstartdraw(void) { @@ -1695,6 +1732,8 @@ xdrawline(Line line, int x1, int y1, int x2) continue; if (selected(x, y1)) new.mode ^= ATTR_REVERSE; + if (vbellset && isvbellcell(x, y1)) + new.mode ^= ATTR_REVERSE; if (i > 0 && ATTRCMP(base, new)) { xdrawglyphfontspecs(specs, base, i, ox, y1); specs += i; @@ -1714,6 +1753,9 @@ xdrawline(Line line, int x1, int y1, int x2) void xfinishdraw(void) { + if (vbellset && vbellmode == 1) + xdrawvbell(); + XCopyArea(xw.dpy, xw.buf, xw.win, dc.gc, 0, 0, win.w, win.h, 0, 0); XSetForeground(xw.dpy, dc.gc, @@ -1798,6 +1840,8 @@ xbell(void) xseturgency(1); if (bellvolume) XkbBell(xw.dpy, xw.win, bellvolume, (Atom)NULL); + if (vbelltimeout) + vbellbegin(); } void @@ -2062,6 +2106,16 @@ run(void) } } + if (vbellset) { + double remain = vbelltimeout - TIMEDIFF(now, lastvbell); + if (remain <= 0) { + vbellset = 0; + redraw(); + } else if (timeout < 0 || remain < timeout) { + timeout = remain; + } + } + draw(); XFlush(xw.dpy); drawing = 0; -- cgit v1.2.3