diff options
| author | salmonik <raisersoft@proton.me> | 2026-02-06 22:17:01 +0100 |
|---|---|---|
| committer | salmonik <raisersoft@proton.me> | 2026-02-06 22:17:01 +0100 |
| commit | 3c5363dd7a50219d76f8be3c1e3282cd420a0447 (patch) | |
| tree | 98283b53b998c0ede2911f570dc342c95f77d181 | |
| parent | bold is not bright patch (diff) | |
| download | st-3c5363dd7a50219d76f8be3c1e3282cd420a0447.tar.gz st-3c5363dd7a50219d76f8be3c1e3282cd420a0447.zip | |
apply visualbell2 patches - basic and enhanced
| -rw-r--r-- | config.def.h | 19 | ||||
| -rw-r--r-- | config.h | 19 | ||||
| -rw-r--r-- | x.c | 54 |
3 files changed, 92 insertions, 0 deletions
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; | |||
| 73 | */ | 73 | */ |
| 74 | static int bellvolume = 0; | 74 | static int bellvolume = 0; |
| 75 | 75 | ||
| 76 | /* visual-bell timeout in ms (0 to disable visual-bell) */ | ||
| 77 | static int vbelltimeout = 150; | ||
| 78 | |||
| 79 | /* choose predefined visual-bell cells to inverse, or define your own logic */ | ||
| 80 | #define VBCELL x==0 || x==right || y==0 || y==bottom /* border */ | ||
| 81 | // #define VBCELL 1 /* all cells - whole screen */ | ||
| 82 | // #define VBCELL y==bottom && x>right-2 /* bottom-right */ | ||
| 83 | |||
| 84 | static int vbellmode = 1; | ||
| 85 | /* vbellmode: 0: invert cells. 1: draw a circle with these parameters: | ||
| 86 | * - base and outline colors (colorname index - see below) | ||
| 87 | * - radius: relative to window width, or if negative: relative to cell-width | ||
| 88 | * - position: relative to window width/height (0 and 1 are at the edges) */ | ||
| 89 | static int vbellcolor = 3; | ||
| 90 | static int vbellcolor_outline = 1; | ||
| 91 | static float vbellradius = 0.03; | ||
| 92 | static float vbellx = 0.5; | ||
| 93 | static float vbelly = 0.5; | ||
| 94 | |||
| 76 | /* default TERM value */ | 95 | /* default TERM value */ |
| 77 | char *termname = "st-256color"; | 96 | char *termname = "st-256color"; |
| 78 | 97 | ||
| @@ -73,6 +73,25 @@ static unsigned int cursorthickness = 2; | |||
| 73 | */ | 73 | */ |
| 74 | static int bellvolume = 0; | 74 | static int bellvolume = 0; |
| 75 | 75 | ||
| 76 | /* visual-bell timeout in ms (0 to disable visual-bell) */ | ||
| 77 | static int vbelltimeout = 150; | ||
| 78 | |||
| 79 | /* choose predefined visual-bell cells to inverse, or define your own logic */ | ||
| 80 | #define VBCELL x==0 || x==right || y==0 || y==bottom /* border */ | ||
| 81 | // #define VBCELL 1 /* all cells - whole screen */ | ||
| 82 | // #define VBCELL y==bottom && x>right-2 /* bottom-right */ | ||
| 83 | |||
| 84 | static int vbellmode = 1; | ||
| 85 | /* vbellmode: 0: invert cells. 1: draw a circle with these parameters: | ||
| 86 | * - base and outline colors (colorname index - see below) | ||
| 87 | * - radius: relative to window width, or if negative: relative to cell-width | ||
| 88 | * - position: relative to window width/height (0 and 1 are at the edges) */ | ||
| 89 | static int vbellcolor = 3; | ||
| 90 | static int vbellcolor_outline = 1; | ||
| 91 | static float vbellradius = 0.03; | ||
| 92 | static float vbellx = 0.5; | ||
| 93 | static float vbelly = 0.5; | ||
| 94 | |||
| 76 | /* default TERM value */ | 95 | /* default TERM value */ |
| 77 | char *termname = "st-256color"; | 96 | char *termname = "st-256color"; |
| 78 | 97 | ||
| @@ -1674,6 +1674,43 @@ xsettitle(char *p) | |||
| 1674 | XFree(prop.value); | 1674 | XFree(prop.value); |
| 1675 | } | 1675 | } |
| 1676 | 1676 | ||
| 1677 | |||
| 1678 | static int vbellset = 0; /* 1 during visual bell, 0 otherwise */ | ||
| 1679 | static struct timespec lastvbell = {0}; | ||
| 1680 | |||
| 1681 | static int | ||
| 1682 | isvbellcell(int x, int y) | ||
| 1683 | { | ||
| 1684 | int right = win.tw / win.cw - 1, bottom = win.th / win.ch - 1; | ||
| 1685 | return vbellmode == 0 && (VBCELL); /* logic defined at config.h */ | ||
| 1686 | } | ||
| 1687 | |||
| 1688 | static void | ||
| 1689 | vbellbegin() { | ||
| 1690 | clock_gettime(CLOCK_MONOTONIC, &lastvbell); | ||
| 1691 | if (vbellset) | ||
| 1692 | return; | ||
| 1693 | vbellset = 1; | ||
| 1694 | redraw(); | ||
| 1695 | XFlush(xw.dpy); | ||
| 1696 | } | ||
| 1697 | |||
| 1698 | static void | ||
| 1699 | xfillcircle(int x, int y, int r, uint color_ix) | ||
| 1700 | { | ||
| 1701 | XSetForeground(xw.dpy, dc.gc, dc.col[color_ix].pixel); | ||
| 1702 | XFillArc(xw.dpy, xw.buf, dc.gc, x - r, y - r, r * 2, r * 2, 0, 360*64); | ||
| 1703 | } | ||
| 1704 | |||
| 1705 | static void | ||
| 1706 | xdrawvbell() { | ||
| 1707 | int r = round(vbellradius * (vbellradius > 0 ? win.w : -win.cw)); | ||
| 1708 | int x = borderpx + r + vbellx * (win.tw - 2 * r); | ||
| 1709 | int y = borderpx + r + vbelly * (win.th - 2 * r); | ||
| 1710 | xfillcircle(x, y, r, vbellcolor_outline); | ||
| 1711 | xfillcircle(x, y, r / 1.2, vbellcolor); /* 1.2 - an artistic choice */ | ||
| 1712 | } | ||
| 1713 | |||
| 1677 | int | 1714 | int |
| 1678 | xstartdraw(void) | 1715 | xstartdraw(void) |
| 1679 | { | 1716 | { |
| @@ -1695,6 +1732,8 @@ xdrawline(Line line, int x1, int y1, int x2) | |||
| 1695 | continue; | 1732 | continue; |
| 1696 | if (selected(x, y1)) | 1733 | if (selected(x, y1)) |
| 1697 | new.mode ^= ATTR_REVERSE; | 1734 | new.mode ^= ATTR_REVERSE; |
| 1735 | if (vbellset && isvbellcell(x, y1)) | ||
| 1736 | new.mode ^= ATTR_REVERSE; | ||
| 1698 | if (i > 0 && ATTRCMP(base, new)) { | 1737 | if (i > 0 && ATTRCMP(base, new)) { |
| 1699 | xdrawglyphfontspecs(specs, base, i, ox, y1); | 1738 | xdrawglyphfontspecs(specs, base, i, ox, y1); |
| 1700 | specs += i; | 1739 | specs += i; |
| @@ -1714,6 +1753,9 @@ xdrawline(Line line, int x1, int y1, int x2) | |||
| 1714 | void | 1753 | void |
| 1715 | xfinishdraw(void) | 1754 | xfinishdraw(void) |
| 1716 | { | 1755 | { |
| 1756 | if (vbellset && vbellmode == 1) | ||
| 1757 | xdrawvbell(); | ||
| 1758 | |||
| 1717 | XCopyArea(xw.dpy, xw.buf, xw.win, dc.gc, 0, 0, win.w, | 1759 | XCopyArea(xw.dpy, xw.buf, xw.win, dc.gc, 0, 0, win.w, |
| 1718 | win.h, 0, 0); | 1760 | win.h, 0, 0); |
| 1719 | XSetForeground(xw.dpy, dc.gc, | 1761 | XSetForeground(xw.dpy, dc.gc, |
| @@ -1798,6 +1840,8 @@ xbell(void) | |||
| 1798 | xseturgency(1); | 1840 | xseturgency(1); |
| 1799 | if (bellvolume) | 1841 | if (bellvolume) |
| 1800 | XkbBell(xw.dpy, xw.win, bellvolume, (Atom)NULL); | 1842 | XkbBell(xw.dpy, xw.win, bellvolume, (Atom)NULL); |
| 1843 | if (vbelltimeout) | ||
| 1844 | vbellbegin(); | ||
| 1801 | } | 1845 | } |
| 1802 | 1846 | ||
| 1803 | void | 1847 | void |
| @@ -2062,6 +2106,16 @@ run(void) | |||
| 2062 | } | 2106 | } |
| 2063 | } | 2107 | } |
| 2064 | 2108 | ||
| 2109 | if (vbellset) { | ||
| 2110 | double remain = vbelltimeout - TIMEDIFF(now, lastvbell); | ||
| 2111 | if (remain <= 0) { | ||
| 2112 | vbellset = 0; | ||
| 2113 | redraw(); | ||
| 2114 | } else if (timeout < 0 || remain < timeout) { | ||
| 2115 | timeout = remain; | ||
| 2116 | } | ||
| 2117 | } | ||
| 2118 | |||
| 2065 | draw(); | 2119 | draw(); |
| 2066 | XFlush(xw.dpy); | 2120 | XFlush(xw.dpy); |
| 2067 | drawing = 0; | 2121 | drawing = 0; |
