From: Michael Tremer Date: Fri, 23 Apr 2021 08:14:20 +0000 (+0000) Subject: progressbar: Respond to resize events X-Git-Tag: 0.9.28~1285^2~266 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=8ead3f6b7cc7075956a344188ca532ec56e2e1dd;p=pakfire.git progressbar: Respond to resize events Signed-off-by: Michael Tremer --- diff --git a/src/libpakfire/progressbar.c b/src/libpakfire/progressbar.c index 9c1bbddc9..fe27629c2 100644 --- a/src/libpakfire/progressbar.c +++ b/src/libpakfire/progressbar.c @@ -19,6 +19,7 @@ #############################################################################*/ #include +#include #include #include #include @@ -48,6 +49,7 @@ struct pakfire_progressbar_widget { struct pakfire_progressbar { int nrefs; + FILE* f; enum pakfire_progressbar_status { PAKFIRE_PROGRESSBAR_INIT = 0, @@ -61,13 +63,6 @@ struct pakfire_progressbar { unsigned long value_redraw; unsigned long update_interval; - // Store terminal settings globally - struct pakfire_terminal { - FILE* f; - int rows; - int cols; - } terminal; - struct timespec time_start; struct timespec time_redraw; @@ -76,28 +71,32 @@ struct pakfire_progressbar { unsigned int num_widgets; }; -static int pakfire_progressbar_update_terminal_size(struct pakfire_progressbar* p) { - int fd = fileno(p->terminal.f); +// Store terminal settings globally +static struct pakfire_terminal { + int rows; + int cols; +} terminal; + +static void pakfire_progressbar_update_terminal_size(int signum) { + const int fd = STDOUT_FILENO; - // Set a default of 80x20 - p->terminal.cols = 80; - p->terminal.rows = 20; + // Set defaults + terminal.rows = 80; + terminal.cols = 20; // Check if output file is a TTY int r = isatty(fd); if (r != 1) - return 0; + return; struct winsize w; r = ioctl(fd, TIOCGWINSZ, &w); if (r) - return r; + return; // Save result - p->terminal.rows = w.ws_row; - p->terminal.cols = w.ws_col; - - return 0; + terminal.rows = w.ws_row; + terminal.cols = w.ws_col; } static void pakfire_progressbar_widget_free(struct pakfire_progressbar_widget* widget) { @@ -139,12 +138,10 @@ PAKFIRE_EXPORT int pakfire_progressbar_create( f = stdout; // Store output - p->terminal.f = f; + p->f = stdout; - // Determine terminal size - int r = pakfire_progressbar_update_terminal_size(p); - if (r) - goto ERROR; + // Register signal handler to update terminal size + signal(SIGWINCH, pakfire_progressbar_update_terminal_size); // Setup widgets STAILQ_INIT(&p->widgets); @@ -152,11 +149,6 @@ PAKFIRE_EXPORT int pakfire_progressbar_create( // Done *progressbar = p; return 0; - -ERROR: - pakfire_progressbar_free(p); - - return r; } PAKFIRE_EXPORT struct pakfire_progressbar* pakfire_progressbar_ref(struct pakfire_progressbar* p) { @@ -229,7 +221,7 @@ PAKFIRE_EXPORT int pakfire_progressbar_finish(struct pakfire_progressbar* p) { return r; // Finish line - r = fputs("\n", p->terminal.f); + r = fputs("\n", p->f); if (r <= 0 || r == EOF) return 1; @@ -265,8 +257,12 @@ PAKFIRE_EXPORT void pakfire_progressbar_set_max( // Redraw immediately p->value_redraw = 0; + // Update terminal size if not set + if (!terminal.cols) + pakfire_progressbar_update_terminal_size(SIGWINCH); + // Calculate update interval - p->update_interval = p->value_max / p->terminal.cols; + p->update_interval = p->value_max / terminal.cols; } static int pakfire_progressbar_add_widget(struct pakfire_progressbar* p, @@ -335,7 +331,11 @@ static int pakfire_progressbar_redraw(struct pakfire_progressbar* p) { if (!pakfire_progressbar_needs_redraw(p)) return 0; - unsigned int cols_left = p->terminal.cols - p->num_widgets - 2; + // Update terminal size if not set + if (!terminal.cols) + pakfire_progressbar_update_terminal_size(SIGWINCH); + + unsigned int cols_left = terminal.cols - p->num_widgets - 2; int i = 0; // Create an array with the result of all print functions @@ -382,7 +382,7 @@ static int pakfire_progressbar_redraw(struct pakfire_progressbar* p) { } // Reset the line - fputs("\r", p->terminal.f); + fputs("\r", p->f); // Print all elements for (unsigned int i = 0; i < p->num_widgets; i++) { @@ -390,8 +390,8 @@ static int pakfire_progressbar_redraw(struct pakfire_progressbar* p) { if (!elements[i]) continue; - fputs(" ", p->terminal.f); - fputs(elements[i], p->terminal.f); + fputs(" ", p->f); + fputs(elements[i], p->f); } return 0;