diff options
| author | Dylan Araps <dylan.araps@gmail.com> | 2026-02-28 09:35:10 +0200 |
|---|---|---|
| committer | Dylan Araps <dylan.araps@gmail.com> | 2026-02-28 09:35:10 +0200 |
| commit | f700440f9ca9be7dd6e5615b3a84c1c9e1ca18c2 (patch) | |
| tree | 6941e2d48c3b2c5f3c2a2f9b0c730a6d75d0b199 /lib | |
| parent | fc339fa3cb9c03fdebd300f7018b23931a3eb7bd (diff) | |
dfm: also wake on winch
This adds responsive resize whilst still allowing dfm to do nothing at idle.
Nifty.
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/term.h | 52 |
1 files changed, 36 insertions, 16 deletions
@@ -23,6 +23,7 @@ #define DYLAN_TERM_H #include <assert.h> +#include <errno.h> #include <fcntl.h> #include <signal.h> #include <termios.h> @@ -36,8 +37,9 @@ #include "vt.h" enum { - TERM_LOADED = 1 << 0, - TERM_RESIZE = 1 << 1, + TERM_LOADED = 1 << 0, + TERM_WAIT_WCH = 1 << 1, + TERM_WAIT_KEY = 1 << 2, }; static struct term { @@ -45,6 +47,7 @@ static struct term { int fd; int null; volatile sig_atomic_t flag; + volatile sig_atomic_t resize; volatile sig_atomic_t dead; } *TERM; @@ -60,12 +63,6 @@ term_dead(const struct term *t) return t->dead; } -static inline int -term_resize(const struct term *t) -{ - return t->flag & TERM_RESIZE; -} - static inline void term_restore_on_signal(int s) { @@ -105,7 +102,7 @@ static inline void term_signal_sigwinch(int s) { (void) s; - if (TERM) TERM->flag |= TERM_RESIZE; + if (TERM) TERM->resize = 1; } static inline void @@ -123,6 +120,7 @@ term_signal_setup(void) { sigaction(SIGBUS, &sa, NULL); sigaction(SIGFPE, &sa, NULL); sigaction(SIGILL, &sa, NULL); + sa.sa_flags = 0; sa.sa_handler = term_signal_sigwinch; sigaction(SIGWINCH, &sa, NULL); } @@ -130,13 +128,15 @@ term_signal_setup(void) { static inline int term_size_update(struct term *t, u16 *row, u16 *col) { - struct winsize ws; - if (ioctl(t->fd, TIOCGWINSZ, &ws) < 0) - return -1; - t->flag &= ~TERM_RESIZE; - *row = ws.ws_row; - *col = ws.ws_col; - return 0; + for (;;) { + t->resize = 0; + struct winsize ws; + if (ioctl(t->fd, TIOCGWINSZ, &ws) < 0) + return -1; + *row = ws.ws_row; + *col = ws.ws_col; + if (!t->resize) return 0; + } } static inline int @@ -192,6 +192,26 @@ term_reap(void) for (int st; waitpid(-1, &st, WNOHANG) > 0; ); } +static inline int +term_wait(struct term *t) +{ + for (;;) { + if (t->resize) return TERM_WAIT_WCH; + fd_set rfds; + FD_ZERO(&rfds); + FD_SET(t->fd, &rfds); + int r = select(t->fd + 1, &rfds, NULL, NULL, NULL); + if (r < 0) { + if (errno != EINTR) return 0; + if (t->resize) return TERM_WAIT_WCH; + continue; + } + if (FD_ISSET(t->fd, &rfds)) + return TERM_WAIT_KEY; + return 0; + } +} + static inline void term_destroy(const struct term *t) { |