summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorpgen <p.gen.progs@gmail.com>2021-01-27 23:16:01 +0100
committerpgen <p.gen.progs@gmail.com>2021-01-27 23:37:10 +0100
commit2416f3fc5ba9a40cf5e7f5558d2d49b32638ad1e (patch)
tree83ab710493b56f9b40b6ea500bd5a032b9781356
parent207900387b508a785a39d18ac10effc981b0cc3c (diff)
Fix a weird display corruption
Display corruption occurred when the terminal was resized with a multi-line (-m) title and without enough space to fully display it. This fix may also work in some use cases where the display was also corrupted.
-rw-r--r--smenu.c58
1 files changed, 44 insertions, 14 deletions
diff --git a/smenu.c b/smenu.c
index 9038deb..3c204b3 100644
--- a/smenu.c
+++ b/smenu.c
@@ -3434,6 +3434,8 @@ disp_message(ll_t * message_lines_list, long message_max_width,
long size;
long offset;
wchar_t * w;
+ int n = 0; /* Counter used to display message lines. */
+ int cut = 0; /* Will be 1 if the message is shortened. */
sigset_t mask;
@@ -3444,6 +3446,21 @@ disp_message(ll_t * message_lines_list, long message_max_width,
if (message_lines_list == NULL)
return;
+ /* Recalculate the number of to-be-displayed lines in the messages */
+ /* if space is missing. */
+ /* """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" */
+ if (term->nlines < 3)
+ return;
+
+ win->message_lines = message_lines_list->len;
+ if (win->message_lines > term->nlines - 2)
+ {
+ win->message_lines = term->nlines - 2;
+ win->max_lines = term->nlines - win->message_lines - 1;
+ cut = 1;
+ }
+ win->message_lines++;
+
/* Deactivate the periodic timer to prevent the interruptions to corrupt */
/* screen by altering the timing of the decoding of the terminfo */
/* capabilities. */
@@ -3457,7 +3474,7 @@ disp_message(ll_t * message_lines_list, long message_max_width,
/* Follow the message lines list and display each line. */
/* """""""""""""""""""""""""""""""""""""""""""""""""""" */
- while (node != NULL && win->message_lines < term->nlines - 2)
+ for (n = 1; n < win->message_lines; n++)
{
long i;
@@ -3489,7 +3506,7 @@ disp_message(ll_t * message_lines_list, long message_max_width,
/* Print the line without the ending \n. */
/* ''''''''''''''''''''''''''''''''''''' */
- if (win->message_lines >= term->nlines - 3)
+ if (n > 1 && cut && n == win->message_lines - 1)
{
if (langinfo->utf8)
fputs(msg_arr_down, stdout);
@@ -3518,14 +3535,12 @@ disp_message(ll_t * message_lines_list, long message_max_width,
}
node = node->next;
- win->message_lines++;
}
/* Add an empty line without attribute to separate the menu title */
/* and the menu content. */
/* """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" */
puts("");
- win->message_lines++;
free(buf);
@@ -3817,7 +3832,8 @@ sig_handler(int s)
/* Terminal resize. */
/* """""""""""""""" */
case SIGWINCH:
- got_winch = 1;
+ got_winch = 1;
+ got_winch_alrm = 0;
break;
/* Alarm triggered, This signal is used by the search mechanism to */
@@ -9184,10 +9200,16 @@ main(int argc, char * argv[])
long i; /* generic index in this block */
int nlines, ncolumns;
int line, column;
+ int original_message_lines;
got_winch_alrm = 0; /* Reset the flag signaling the need for a refresh. */
winch_timer = -1; /* Disarm the timer used for this refresh. */
+ if (message_lines_list != NULL && message_lines_list->len > 0)
+ original_message_lines = message_lines_list->len + 1;
+ else
+ original_message_lines = 0;
+
get_terminal_size(&nlines, &ncolumns, &term);
/* Update term with the new number of lines and columns */
@@ -9197,26 +9219,34 @@ main(int argc, char * argv[])
term.ncolumns = ncolumns;
/* Reset the number of lines if the terminal has enough lines. */
+ /* message_lines_list->len+1 is used here instead of */
+ /* win.message_lines because win.message_lines may have been */
+ /* altered by a previous scrolling and not yet recalculated. */
/* """"""""""""""""""""""""""""""""""""""""""""""""""""""""""" */
- if (term.nlines <= win.message_lines)
+ if (term.nlines <= original_message_lines)
{
win.message_lines = term.nlines - 1;
win.max_lines = 1;
}
- else if (win.max_lines < term.nlines - win.message_lines)
+ else
{
- if (win.asked_max_lines == 0)
- win.max_lines = term.nlines - win.message_lines;
- else
+ win.message_lines = original_message_lines;
+
+ if (win.max_lines < term.nlines - win.message_lines)
{
- if (win.asked_max_lines > term.nlines - win.message_lines)
+ if (win.asked_max_lines == 0)
win.max_lines = term.nlines - win.message_lines;
else
- win.max_lines = win.asked_max_lines;
+ {
+ if (win.asked_max_lines > term.nlines - win.message_lines)
+ win.max_lines = term.nlines - win.message_lines;
+ else
+ win.max_lines = win.asked_max_lines;
+ }
}
+ else
+ win.max_lines = term.nlines - win.message_lines;
}
- else
- win.max_lines = term.nlines - win.message_lines;
/* Erase the visible part of the displayed window. */
/* """"""""""""""""""""""""""""""""""""""""""""""" */