1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
|
diff -ruN a/config.def.h b/config.def.h
--- a/config.def.h 2026-05-20 12:14:52.639963552 +0200
+++ b/config.def.h 2026-05-20 12:14:52.639963552 +0200
@@ -9,3 +9,8 @@
* Override per-run with --no-persist.
*/
static const int ALERT_PERSIST = 1;
+
+/* reverse-video flash during the alert loop.
+ * Override per-run with --flash on|off.
+ */
+static const int FLASH = 1;
diff -ruN a/ttym.c b/ttym.c
--- a/ttym.c 2026-05-20 12:14:52.639963552 +0200
+++ b/ttym.c 2026-05-20 12:17:37.203364538 +0200
@@ -11,6 +11,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <strings.h>
#include <sys/ioctl.h>
#include <termios.h>
#include <time.h>
@@ -24,6 +25,7 @@
int quiet; /* -q: suppress completion bell */
int silent; /* -s: no bell, no extras */
int alert_persist; /* alert loop until keypress; --no-persist disables */
+ int flash; /* reverse-video flash during alert loop */
} Config;
static struct termios oldtios;
@@ -81,6 +83,13 @@
interrupted = 1;
}
+static int
+parse_bool_str(const char *v)
+{
+ return !strcasecmp(v, "true") || !strcasecmp(v, "yes") ||
+ !strcmp(v, "1") || !strcasecmp(v, "on");
+}
+
static void
restore_tty(void)
{
@@ -88,7 +97,7 @@
tcsetattr(ttyfd, TCSANOW, &oldtios);
rawset = 0;
if (out_tty)
- fputs("\033[?7h\033[?25h", stdout); /* re-enable wrap, show cursor */
+ fputs("\033[?5l\033[?7h\033[?25h", stdout); /* clear reverse, re-enable wrap, show cursor */
fputc('\n', stdout);
fflush(stdout);
}
@@ -241,14 +250,17 @@
}
static void
-alert_loop(void)
+alert_loop(int flash)
{
fputs("\033[?25h\033[?7h", stdout);
int ticks = 0;
while (!interrupted) {
fputc('\a', stdout);
+ if (flash) fputs("\033[?5h", stdout);
fflush(stdout);
sleep_ms(150);
+ if (flash) fputs("\033[?5l", stdout);
+ fflush(stdout);
int acked = 0;
for (int i = 0; i < 15 && !interrupted; i++) {
@@ -287,6 +299,7 @@
" -q no sound\n"
" -s silent\n"
" --no-persist skip alert-until-keypress loop\n"
+" --flash on|off terminal flash during alert loop\n"
" -- end of options\n"
" -h help\n"
"\n"
@@ -421,7 +434,7 @@
}
if (!cfg->silent && cfg->alert_persist && is_foreground()) {
interrupted = 0;
- alert_loop();
+ alert_loop(cfg->flash);
}
}
@@ -436,6 +449,7 @@
{
Config cfg = {0};
cfg.alert_persist = ALERT_PERSIST;
+ cfg.flash = FLASH;
/* Pre-strip long-form flags before getopt. Stop at "--". */
int new_argc = 0;
@@ -452,6 +466,14 @@
cfg.alert_persist = 0;
continue;
}
+ if (!past_dd && !strncmp(argv[i], "--flash=", 8)) {
+ cfg.flash = parse_bool_str(argv[i] + 8);
+ continue;
+ }
+ if (!past_dd && !strcmp(argv[i], "--flash") && i + 1 < argc) {
+ cfg.flash = parse_bool_str(argv[++i]);
+ continue;
+ }
new_argv[new_argc++] = argv[i];
}
new_argv[new_argc] = NULL;
|