Hide cursor while pacman is running

Use ASCII control codes to hide cursor at the pacman start and then
show the cursor when pacman finishes.

It helps to avoid annoying blinking when progress bars are re-drawn.

Cursor is reenabled if pacman expects user's input.

Signed-off-by: Anatol Pomozov <anatol.pomozov@gmail.com>
Signed-off-by: Allan McRae <allan@archlinux.org>
This commit is contained in:
Anatol Pomozov 2020-03-09 11:54:17 -07:00 committed by Allan McRae
parent ddd5b0a462
commit 87b74fcd82
4 changed files with 38 additions and 5 deletions

View file

@ -300,6 +300,7 @@ static void cleanup(int ret)
/* free memory */ /* free memory */
FREELIST(pm_targets); FREELIST(pm_targets);
console_cursor_show();
exit(ret); exit(ret);
} }
@ -1084,6 +1085,7 @@ int main(int argc, char *argv[])
int ret = 0; int ret = 0;
uid_t myuid = getuid(); uid_t myuid = getuid();
console_cursor_hide();
install_segv_handler(); install_segv_handler();
/* i18n init */ /* i18n init */

View file

@ -60,6 +60,8 @@ static void soft_interrupt_handler(int signum)
const char msg[] = "\nHangup signal received\n"; const char msg[] = "\nHangup signal received\n";
xwrite(STDERR_FILENO, msg, ARRAYSIZE(msg) - 1); xwrite(STDERR_FILENO, msg, ARRAYSIZE(msg) - 1);
} }
xwrite(STDOUT_FILENO, CURSOR_SHOW_ANSICODE,
sizeof(CURSOR_SHOW_ANSICODE) - 1);
if(alpm_trans_interrupt(config->handle) == 0) { if(alpm_trans_interrupt(config->handle) == 0) {
/* a transaction is being interrupted, don't exit pacman yet. */ /* a transaction is being interrupted, don't exit pacman yet. */
return; return;
@ -95,6 +97,8 @@ static void segv_handler(int signum)
const char msg[] = "\nerror: segmentation fault\n" const char msg[] = "\nerror: segmentation fault\n"
"Please submit a full bug report with --debug if appropriate.\n"; "Please submit a full bug report with --debug if appropriate.\n";
xwrite(STDERR_FILENO, msg, sizeof(msg) - 1); xwrite(STDERR_FILENO, msg, sizeof(msg) - 1);
xwrite(STDOUT_FILENO, CURSOR_SHOW_ANSICODE,
sizeof(CURSOR_SHOW_ANSICODE) - 1);
/* restore the default handler */ /* restore the default handler */
_reset_handler(signum); _reset_handler(signum);

View file

@ -1391,6 +1391,27 @@ static int multiselect_parse(char *array, int count, char *response)
return 0; return 0;
} }
void console_cursor_hide(void) {
if(isatty(fileno(stdout))) {
printf(CURSOR_HIDE_ANSICODE);
}
}
void console_cursor_show(void) {
if(isatty(fileno(stdout))) {
printf(CURSOR_SHOW_ANSICODE);
}
}
char *safe_fgets_stdin(char *s, int size)
{
char *result;
console_cursor_show();
result = safe_fgets(s, size, stdin);
console_cursor_hide();
return result;
}
int multiselect_question(char *array, int count) int multiselect_question(char *array, int count)
{ {
char *response, *lastchar; char *response, *lastchar;
@ -1427,7 +1448,7 @@ int multiselect_question(char *array, int count)
flush_term_input(fileno(stdin)); flush_term_input(fileno(stdin));
if(safe_fgets(response, response_len, stdin)) { if(safe_fgets_stdin(response, response_len)) {
const size_t response_incr = 64; const size_t response_incr = 64;
size_t len; size_t len;
/* handle buffer not being large enough to read full line case */ /* handle buffer not being large enough to read full line case */
@ -1443,8 +1464,8 @@ int multiselect_question(char *array, int count)
lastchar = response + response_len - 1; lastchar = response + response_len - 1;
/* sentinel byte */ /* sentinel byte */
*lastchar = 1; *lastchar = 1;
if(safe_fgets(response + response_len - response_incr - 1, if(safe_fgets_stdin(response + response_len - response_incr - 1,
response_incr + 1, stdin) == 0) { response_incr + 1) == 0) {
free(response); free(response);
return -1; return -1;
} }
@ -1494,7 +1515,7 @@ int select_question(int count)
flush_term_input(fileno(stdin)); flush_term_input(fileno(stdin));
if(safe_fgets(response, sizeof(response), stdin)) { if(safe_fgets_stdin(response, sizeof(response))) {
size_t len = strtrim(response); size_t len = strtrim(response);
if(len > 0) { if(len > 0) {
int n; int n;
@ -1582,7 +1603,7 @@ static int question(short preset, const char *format, va_list args)
flush_term_input(fd_in); flush_term_input(fd_in);
if(safe_fgets(response, sizeof(response), stdin)) { if(safe_fgets_stdin(response, sizeof(response))) {
size_t len = strtrim(response); size_t len = strtrim(response);
if(len == 0) { if(len == 0) {
return preset; return preset;

View file

@ -28,6 +28,9 @@
#include "util-common.h" #include "util-common.h"
#define CURSOR_HIDE_ANSICODE "\x1B[?25l"
#define CURSOR_SHOW_ANSICODE "\x1B[?25h"
#ifdef ENABLE_NLS #ifdef ENABLE_NLS
#include <libintl.h> /* here so it doesn't need to be included elsewhere */ #include <libintl.h> /* here so it doesn't need to be included elsewhere */
/* define _() as shortcut for gettext() */ /* define _() as shortcut for gettext() */
@ -77,6 +80,9 @@ int colon_printf(const char *format, ...) __attribute__((format(printf, 1, 2)));
int yesno(const char *format, ...) __attribute__((format(printf, 1, 2))); int yesno(const char *format, ...) __attribute__((format(printf, 1, 2)));
int noyes(const char *format, ...) __attribute__((format(printf, 1, 2))); int noyes(const char *format, ...) __attribute__((format(printf, 1, 2)));
char *arg_to_string(int argc, char *argv[]); char *arg_to_string(int argc, char *argv[]);
char *safe_fgets_stdin(char *s, int size);
void console_cursor_hide(void);
void console_cursor_show(void);
int pm_printf(alpm_loglevel_t level, const char *format, ...) __attribute__((format(printf,2,3))); int pm_printf(alpm_loglevel_t level, const char *format, ...) __attribute__((format(printf,2,3)));
int pm_asprintf(char **string, const char *format, ...) __attribute__((format(printf,2,3))); int pm_asprintf(char **string, const char *format, ...) __attribute__((format(printf,2,3)));