sites

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

st-visualbell2-basic-2018-10-16-30ec9a3.diff (5437B)


      1 From bcc850d57fb4cb6941008fb2808d4d0d373aa5f8 Mon Sep 17 00:00:00 2001
      2 From: "Avi Halachmi (:avih)" <avihpit@yahoo.com>
      3 Date: Mon, 15 Oct 2018 01:06:01 +0300
      4 Subject: [PATCH] [vbell2] add visual bell with two rendering modes
      5 
      6 - Inverse the whole terminal - "standard" visual-bell, a bit jarring.
      7 - Inverse outer (border) cells - much less jarring, yet plenty visible.
      8 
      9 Note: blink used a timeout of 1us after drawing, probably to
     10 re-calculate the timeout without being affected by draw speed. This was
     11 changed to 1ms for code simplicity, and should be inconsequential.
     12 ---
     13  config.def.h | 11 ++++++++
     14  st.c         |  1 -
     15  st.h         |  1 +
     16  x.c          | 77 +++++++++++++++++++++++++++++++++++++++-------------
     17  4 files changed, 70 insertions(+), 20 deletions(-)
     18 
     19 diff --git a/config.def.h b/config.def.h
     20 index 823e79f..0915ce5 100644
     21 --- a/config.def.h
     22 +++ b/config.def.h
     23 @@ -62,6 +62,17 @@ static unsigned int cursorthickness = 2;
     24   */
     25  static int bellvolume = 0;
     26  
     27 +/*
     28 + * visual-bell timeout (set to 0 to disable visual-bell).
     29 + */
     30 +static int vbelltimeout = 0;
     31 +/*
     32 + * visual bell mode when enabled:
     33 + *   1: Inverse whole screen
     34 + *   2: Inverse outer (border) cells
     35 + */
     36 +static int vbellmode = 1;
     37 +
     38  /* default TERM value */
     39  char *termname = "st-256color";
     40  
     41 diff --git a/st.c b/st.c
     42 index 46cf2da..1229479 100644
     43 --- a/st.c
     44 +++ b/st.c
     45 @@ -193,7 +193,6 @@ static void tsetscroll(int, int);
     46  static void tswapscreen(void);
     47  static void tsetmode(int, int, int *, int);
     48  static int twrite(const char *, int, int);
     49 -static void tfulldirt(void);
     50  static void tcontrolcode(uchar );
     51  static void tdectest(char );
     52  static void tdefutf8(char);
     53 diff --git a/st.h b/st.h
     54 index 38c61c4..619d716 100644
     55 --- a/st.h
     56 +++ b/st.h
     57 @@ -89,6 +89,7 @@ int tattrset(int);
     58  void tnew(int, int);
     59  void tresize(int, int);
     60  void tsetdirtattr(int);
     61 +void tfulldirt();
     62  void ttyhangup(void);
     63  int ttynew(char *, char *, char *, char **);
     64  size_t ttyread(void);
     65 diff --git a/x.c b/x.c
     66 index 00cb6b1..7e66c6d 100644
     67 --- a/x.c
     68 +++ b/x.c
     69 @@ -82,6 +82,8 @@ typedef struct {
     70  	int cw; /* char width  */
     71  	int mode; /* window state/mode flags */
     72  	int cursor; /* cursor style */
     73 +	int vbellset; /* 1 during visual bell, 0 otherwise */
     74 +	struct timespec lastvbell;
     75  } TermWindow;
     76  
     77  typedef struct {
     78 @@ -173,6 +175,9 @@ static void mousereport(XEvent *);
     79  static char *kmap(KeySym, uint);
     80  static int match(uint, uint);
     81  
     82 +static void vbellbegin();
     83 +static int isvbellcell(int x, int y);
     84 +
     85  static void run(void);
     86  static void usage(void);
     87  
     88 @@ -1528,6 +1533,8 @@ xdrawline(Line line, int x1, int y1, int x2)
     89  			continue;
     90  		if (selected(x, y1))
     91  			new.mode ^= ATTR_REVERSE;
     92 +		if (win.vbellset && isvbellcell(x, y1))
     93 +			new.mode ^= ATTR_REVERSE;
     94  		if (i > 0 && ATTRCMP(base, new)) {
     95  			xdrawglyphfontspecs(specs, base, i, ox, y1);
     96  			specs += i;
     97 @@ -1610,6 +1617,28 @@ xseturgency(int add)
     98  	XFree(h);
     99  }
    100  
    101 +int
    102 +isvbellcell(int x, int y)
    103 +{
    104 +	if (vbellmode == 1)
    105 +		return 1;
    106 +	if (vbellmode == 2)
    107 +		return y == 0 || y == win.th / win.ch - 1 ||
    108 +		       x == 0 || x == win.tw / win.cw - 1;
    109 +	return 0;
    110 +}
    111 +
    112 +void
    113 +vbellbegin() {
    114 +	clock_gettime(CLOCK_MONOTONIC, &win.lastvbell);
    115 +	if (win.vbellset) /* already visible, just extend win.lastvbell */
    116 +		return;
    117 +	win.vbellset = 1;
    118 +	tfulldirt();
    119 +	draw();
    120 +	XFlush(xw.dpy);
    121 +}
    122 +
    123  void
    124  xbell(void)
    125  {
    126 @@ -1617,6 +1646,8 @@ xbell(void)
    127  		xseturgency(1);
    128  	if (bellvolume)
    129  		XkbBell(xw.dpy, xw.win, bellvolume, (Atom)NULL);
    130 +	if (vbelltimeout)
    131 +		vbellbegin();
    132  }
    133  
    134  void
    135 @@ -1770,7 +1801,7 @@ run(void)
    136  	int xfd = XConnectionNumber(xw.dpy), xev, blinkset = 0, dodraw = 0;
    137  	int ttyfd;
    138  	struct timespec drawtimeout, *tv = NULL, now, last, lastblink;
    139 -	long deltatime;
    140 +	long deltatime, to_ms, remain;
    141  
    142  	/* Waiting for window mapping */
    143  	do {
    144 @@ -1822,11 +1853,28 @@ run(void)
    145  		tv = &drawtimeout;
    146  
    147  		dodraw = 0;
    148 -		if (blinktimeout && TIMEDIFF(now, lastblink) > blinktimeout) {
    149 -			tsetdirtattr(ATTR_BLINK);
    150 -			win.mode ^= MODE_BLINK;
    151 -			lastblink = now;
    152 -			dodraw = 1;
    153 +		to_ms = -1; /* timeout in ms, indefinite if negative */
    154 +		if (blinkset) {
    155 +			remain = blinktimeout - TIMEDIFF(now, lastblink);
    156 +			if (remain <= 0) {
    157 +				dodraw = 1;
    158 +				remain = 1; /* draw, wait 1ms, and re-calc */
    159 +				tsetdirtattr(ATTR_BLINK);
    160 +				win.mode ^= MODE_BLINK;
    161 +				lastblink = now;
    162 +			}
    163 +			to_ms = remain;
    164 +		}
    165 +		if (win.vbellset) {
    166 +			remain = vbelltimeout - TIMEDIFF(now, win.lastvbell);
    167 +			if (remain <= 0) {
    168 +				dodraw = 1;
    169 +				remain = -1; /* draw (clear), and that's it */
    170 +				tfulldirt();
    171 +				win.vbellset = 0;
    172 +			}
    173 +			if (remain >= 0 && (to_ms < 0 || remain < to_ms))
    174 +				to_ms = remain;
    175  		}
    176  		deltatime = TIMEDIFF(now, last);
    177  		if (deltatime > 1000 / (xev ? xfps : actionfps)) {
    178 @@ -1849,19 +1897,10 @@ run(void)
    179  			if (xev && !FD_ISSET(xfd, &rfd))
    180  				xev--;
    181  			if (!FD_ISSET(ttyfd, &rfd) && !FD_ISSET(xfd, &rfd)) {
    182 -				if (blinkset) {
    183 -					if (TIMEDIFF(now, lastblink) \
    184 -							> blinktimeout) {
    185 -						drawtimeout.tv_nsec = 1000;
    186 -					} else {
    187 -						drawtimeout.tv_nsec = (1E6 * \
    188 -							(blinktimeout - \
    189 -							TIMEDIFF(now,
    190 -								lastblink)));
    191 -					}
    192 -					drawtimeout.tv_sec = \
    193 -					    drawtimeout.tv_nsec / 1E9;
    194 -					drawtimeout.tv_nsec %= (long)1E9;
    195 +				if (to_ms >= 0) {
    196 +					static const long k = 1E3, m = 1E6;
    197 +					drawtimeout.tv_sec = to_ms / k;
    198 +					drawtimeout.tv_nsec = (to_ms % k) * m;
    199  				} else {
    200  					tv = NULL;
    201  				}
    202 -- 
    203 2.19.1
    204