aboutsummaryrefslogtreecommitdiff
path: root/patches/ttym-persist-alert-2.0.diff
diff options
context:
space:
mode:
Diffstat (limited to 'patches/ttym-persist-alert-2.0.diff')
-rw-r--r--patches/ttym-persist-alert-2.0.diff111
1 files changed, 111 insertions, 0 deletions
diff --git a/patches/ttym-persist-alert-2.0.diff b/patches/ttym-persist-alert-2.0.diff
new file mode 100644
index 0000000..7e9d64b
--- /dev/null
+++ b/patches/ttym-persist-alert-2.0.diff
@@ -0,0 +1,111 @@
+diff -ruN a/config.def.h b/config.def.h
+--- a/config.def.h 2026-05-20 11:57:26.574344832 +0200
++++ b/config.def.h 2026-05-20 11:57:26.578344915 +0200
+@@ -3,3 +3,9 @@
+ /* progress bar glyphs (ASCII default) */
+ static const char *const BAR_FILL = ">";
+ static const char *const BAR_EMPTY = "-";
++
++/* persistent alert: keep ringing the bell until any key is pressed.
++ * Foreground-only; backgrounded runs always fall through.
++ * Override per-run with --no-persist.
++ */
++static const int ALERT_PERSIST = 1;
+diff -ruN a/ttym.c b/ttym.c
+--- a/ttym.c 2026-05-20 11:57:26.574344832 +0200
++++ b/ttym.c 2026-05-20 11:57:26.578344915 +0200
+@@ -23,6 +23,7 @@
+ typedef struct {
+ int quiet; /* -q: suppress completion bell */
+ int silent; /* -s: no bell, no extras */
++ int alert_persist; /* alert loop until keypress; --no-persist disables */
+ } Config;
+
+ static struct termios oldtios;
+@@ -226,6 +227,48 @@
+ fflush(stdout);
+ }
+
++/* ===== alert loop =====
++ * Bell + poll for keypress, ~1.5s per beat; 4-min safety cap.
++ */
++
++static int
++is_foreground(void)
++{
++ if (!isatty(STDIN_FILENO) || !isatty(STDOUT_FILENO)) return 0;
++ pid_t pgrp = tcgetpgrp(STDIN_FILENO);
++ if (pgrp < 0) return 0;
++ return pgrp == getpgrp();
++}
++
++static void
++alert_loop(void)
++{
++ fputs("\033[?25h\033[?7h", stdout);
++ int ticks = 0;
++ while (!interrupted) {
++ fputc('\a', stdout);
++ fflush(stdout);
++ sleep_ms(150);
++
++ int acked = 0;
++ for (int i = 0; i < 15 && !interrupted; i++) {
++ if (ttyfd < 0) { sleep_ms(100); continue; }
++ struct pollfd pfd = { .fd = ttyfd, .events = POLLIN };
++ int pr = poll(&pfd, 1, 100);
++ if (pr > 0 && (pfd.revents & POLLIN)) {
++ char ch;
++ ssize_t rd = read(ttyfd, &ch, 1);
++ if (rd >= 0) { acked = 1; break; }
++ } else if (pr < 0) {
++ sleep_ms(100);
++ }
++ }
++ if (acked) break;
++ if (++ticks > 160) break;
++ }
++ fflush(stdout);
++}
++
+ /* ===== usage =====
+ * Patches MUST update this in lockstep with new flags so -h always
+ * reflects the build.
+@@ -243,6 +286,7 @@
+ "FLAGS:\n"
+ " -q no sound\n"
+ " -s silent\n"
++" --no-persist skip alert-until-keypress loop\n"
+ " -- end of options\n"
+ " -h help\n"
+ "\n"
+@@ -375,6 +419,10 @@
+ fflush(stdout);
+ sleep_ms(50);
+ }
++ if (!cfg->silent && cfg->alert_persist && is_foreground()) {
++ interrupted = 0;
++ alert_loop();
++ }
+ }
+
+ (void)cfg;
+@@ -387,6 +435,7 @@
+ main(int argc, char **argv)
+ {
+ Config cfg = {0};
++ cfg.alert_persist = ALERT_PERSIST;
+
+ /* Pre-strip long-form flags before getopt. Stop at "--". */
+ int new_argc = 0;
+@@ -399,6 +448,10 @@
+ new_argv[new_argc++] = argv[i];
+ continue;
+ }
++ if (!past_dd && !strcmp(argv[i], "--no-persist")) {
++ cfg.alert_persist = 0;
++ continue;
++ }
+ new_argv[new_argc++] = argv[i];
+ }
+ new_argv[new_argc] = NULL;