Skip to content

Commit

Permalink
menu.c: Improve menu resize handling.
Browse files Browse the repository at this point in the history
* Properly redraw menu when relevant resizes occur.
* Don't emit invalid selection error on menu resize.
* Also redraw menu if terminal becomes wider.
* Ignore terminal resizes during shutdown, to prevent
  locking assertions.
  • Loading branch information
InterLinked1 committed Mar 13, 2024
1 parent df7721f commit b5bbf8f
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 10 deletions.
31 changes: 23 additions & 8 deletions bbs/menu.c
Original file line number Diff line number Diff line change
Expand Up @@ -492,6 +492,10 @@ static int bbs_menu_run(struct bbs_node *node, const char *menuname, const char
char submenuitemname[MAX_MENUITEM_NAME_LENGTH];
int neederror = 0;
int forcedrawmenu = 0;
unsigned int origrows, origcols;

origrows = node->rows;
origcols = node->cols;

/* Ensure we're within the stack limit */
if (++stack > BBS_MAX_MENUSTACK) {
Expand Down Expand Up @@ -647,15 +651,26 @@ static int bbs_menu_run(struct bbs_node *node, const char *menuname, const char
RWLIST_RDLOCK(&menus);
continue;
} else if (!strchr(options, opt)) {
bbs_debug(3, "Node %d chose option '%c', but this is not a valid option for menu '%s'\n", node->id, opt, menuname);
/* Leave opt != 0 so that we don't display the menu again */
if (optreq) {
/* If we were doing skip menu navigation, DO display the menu again since we didn't see it before. */
opt = 0; /* This will clear the screen, so no point in printing an error message here, really... */
neederror = 1; /* Display the error message once we redraw the screen */
if (node->cols != origcols || node->rows != origrows) {
/* Menu needs a redraw, the input we got was spoofed
* on the PTY master to make us wake up and redraw it.
* Don't emit a warning about invalid selection. */
origcols = node->cols;
origrows = node->rows;
opt = 0;
forcedrawmenu = 1;
bbs_debug(3, "Completely redrawing menu due to change in screen size\n");
} else {
bbs_node_clear_line(node);
bbs_node_writef(node, "\r%sInvalid option!%s", COLOR(COLOR_RED), COLOR_RESET);
bbs_debug(3, "Node %d chose option '%c', but this is not a valid option for menu '%s'\n", node->id, opt, menuname);
/* Leave opt != 0 so that we don't display the menu again */
if (optreq) {
/* If we were doing skip menu navigation, DO display the menu again since we didn't see it before. */
opt = 0; /* This will clear the screen, so no point in printing an error message here, really... */
neederror = 1; /* Display the error message once we redraw the screen */
} else {
bbs_node_clear_line(node);
bbs_node_writef(node, "\r%sInvalid option!%s", COLOR(COLOR_RED), COLOR_RESET);
}
}
optreq = NULL; /* If were doing skip menu navigation, stop now since we hit a dead end. */
RWLIST_RDLOCK(&menus);
Expand Down
9 changes: 9 additions & 0 deletions bbs/node.c
Original file line number Diff line number Diff line change
Expand Up @@ -1032,6 +1032,11 @@ int bbs_node_update_winsize(struct bbs_node *node, int cols, int rows)
pid_t child;
unsigned int oldcols = node->cols, oldrows = node->rows;

if (bbs_is_shutting_down()) {
bbs_debug(3, "Declining to update node dimensions due to active shutdown\n");
return -1;
}

if (rows >= 0 && cols >= 0) {
bbs_debug(3, "Node %d's terminal now has %d cols and %d rows\n", node->id, cols, rows);
/* If this were a program that had forked and had children, then we might send a SIGWINCH.
Expand Down Expand Up @@ -1118,7 +1123,11 @@ int bbs_node_update_winsize(struct bbs_node *node, int cols, int rows)
* If it shrunk vertically, the only way we can redraw the menu to show the options
* better would be if there are more columns now.
*/
#ifdef CONSERVATIVE_RESIZE
if (node->cols < oldcols || (node->rows < oldrows && node->cols > oldcols)) {
#else
if (node->cols != oldcols) {
#endif
char c = MENU_REFRESH_KEY;
bbs_debug(5, "Screen size has changed (%dx%d -> %dx%d) such that a menu redraw is warranted\n", oldcols, oldrows, cols, rows);
/* Don't even need an alertpipe - we know that we're in bbs_node_tread in the menu, spoof a special control char as input. */
Expand Down
3 changes: 1 addition & 2 deletions nets/net_ssh.c
Original file line number Diff line number Diff line change
Expand Up @@ -505,9 +505,8 @@ static int pty_resize(ssh_session session, ssh_channel channel, int cols, int ro

/* Resist the urge to directly send a SIGWINCH signal here.
* bbs_node_update_winsize will do that if needed. */
if (cdata->node) {
if (cdata->node && !bbs_node_update_winsize(cdata->node, cols, rows)) {
/* Unlike the Telnet module, we can easily update this out of band... nice! */
bbs_node_update_winsize(cdata->node, cols, rows);
return SSH_OK;
}
return SSH_ERROR;
Expand Down

0 comments on commit b5bbf8f

Please sign in to comment.