in src/terminal/terminal.c [1208:1318]
static void __guac_terminal_resize(guac_terminal* term, int width, int height) {
/* If height is decreasing, shift display up */
if (height < term->term_height) {
int shift_amount;
/* Get number of rows actually occupying terminal space */
int used_height = guac_terminal_effective_buffer_length(term);
if (used_height > term->term_height)
used_height = term->term_height;
shift_amount = used_height - height;
/* If the new terminal bottom covers N rows, shift up N rows */
if (shift_amount > 0) {
guac_terminal_display_copy_rows(term->display,
shift_amount, term->display->height - 1, -shift_amount);
/* Update buffer top and cursor row based on shift */
guac_terminal_buffer_scroll_up(term->current_buffer, shift_amount);
term->cursor_row -= shift_amount;
if (term->visible_cursor_row != -1)
term->visible_cursor_row -= shift_amount;
/* Redraw characters within old region */
__guac_terminal_redraw_rect(term, height - shift_amount, 0, height-1, width-1);
}
}
/* Resize display */
guac_terminal_display_flush(term->display);
guac_terminal_display_resize(term->display, width, height);
/* Redraw any characters on right if widening */
if (width > term->term_width)
__guac_terminal_redraw_rect(term, 0, term->term_width-1, height-1, width-1);
/* If height is increasing, shift display down */
if (height > term->term_height) {
/* If undisplayed rows exist in the buffer, shift them into view */
int available_scroll = guac_terminal_get_available_scroll(term);
if (available_scroll > 0) {
/* If the new terminal bottom reveals N rows, shift down N rows */
int shift_amount = height - term->term_height;
/* The maximum amount we can shift is the number of undisplayed rows */
if (shift_amount > available_scroll)
shift_amount = available_scroll;
/* Update buffer top and cursor row based on shift */
guac_terminal_buffer_scroll_down(term->current_buffer, shift_amount);
term->cursor_row += shift_amount;
if (term->visible_cursor_row != -1)
term->visible_cursor_row += shift_amount;
/* If scrolled enough, use scroll to fulfill entire resize */
if (term->scroll_offset >= shift_amount) {
term->scroll_offset -= shift_amount;
guac_terminal_scrollbar_set_value(term->scrollbar, -term->scroll_offset);
/* Draw characters from scroll at bottom */
__guac_terminal_redraw_rect(term, term->term_height, 0, term->term_height + shift_amount - 1, width-1);
}
/* Otherwise, fulfill with as much scroll as possible */
else {
/* Draw characters from scroll at bottom */
__guac_terminal_redraw_rect(term, term->term_height, 0, term->term_height + term->scroll_offset - 1, width-1);
/* Update shift_amount and scroll based on new rows */
shift_amount -= term->scroll_offset;
term->scroll_offset = 0;
guac_terminal_scrollbar_set_value(term->scrollbar, -term->scroll_offset);
/* If anything remains, move screen as necessary */
if (shift_amount > 0) {
guac_terminal_display_copy_rows(term->display,
0, term->display->height - shift_amount - 1, shift_amount);
/* Draw characters at top from scroll */
__guac_terminal_redraw_rect(term, 0, 0, shift_amount - 1, width-1);
}
}
} /* end if undisplayed rows exist */
}
/* Keep cursor on screen */
if (term->cursor_row < 0) term->cursor_row = 0;
if (term->cursor_row >= height) term->cursor_row = height-1;
if (term->cursor_col < 0) term->cursor_col = 0;
if (term->cursor_col >= width) term->cursor_col = width-1;
/* Commit new dimensions */
term->term_width = width;
term->term_height = height;
}