Skip to content

feat: dynamic terminal resizing with scrollback#61

Open
Mauricio-Leyva wants to merge 2 commits intoviralcode:mainfrom
Mauricio-Leyva:dynamic-terminal
Open

feat: dynamic terminal resizing with scrollback#61
Mauricio-Leyva wants to merge 2 commits intoviralcode:mainfrom
Mauricio-Leyva:dynamic-terminal

Conversation

@Mauricio-Leyva
Copy link

Dynamic Terminal Resizing with full scrollback

  • Added dynamic calculation of rows/cols based on window size.

  • Rewrote term_resize() to properly reflow scrolling when shrinking/expanding window diagonals, matching native terminal behavior.

  • Fixed event loop to properly trigger needs_redraw on keyboard events so Arrow Up/Down scrollback works beautifully.

image image

Copilot AI review requested due to automatic review settings March 7, 2026 22:24
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds dynamic terminal resizing with full scrollback support to the Vib-OS GUI terminal emulator. When the terminal window is resized, the terminal buffer dynamically adjusts its character grid dimensions, and content that scrolls off the top is preserved in a ring-buffer scrollback that users can browse with arrow keys. The event loop is also updated to trigger redraws on keyboard events for responsive scrollback navigation.

Changes:

  • Added a ring-buffer scrollback system (TERM_SCROLLBACK_LINES = 200) with save/restore on scroll and resize, and arrow key–driven viewport scrolling in terminal.c.
  • Implemented term_resize() to dynamically recalculate rows/cols from pixel dimensions, with proper content migration (pulling from scrollback when growing, pushing to scrollback when shrinking).
  • Updated the event loop in main.c to set a needs_redraw flag on virtio keyboard events and disabled the init process launch (documented as not yet ready).

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 7 comments.

File Description
kernel/gui/terminal.c Core changes: scrollback ring buffer, term_save_to_scrollback, scrollback-aware rendering, arrow key scroll handling, term_resize, updated term_create with scrollback allocation and clamping.
kernel/gui/window.c Calls term_resize from draw_window so the terminal adapts to window size changes; added term_resize extern declaration.
kernel/core/main.c Resized default terminal window, added g_key_pressed flag for keyboard-triggered redraws, disabled init process with explanatory comment.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +1437 to +1440
if (nsbc) {
/* Fill with blank spaces */
for (size_t i = 0; i < ss; i++) {
nsbc[i] = ' '; nsbf[i] = 7; nsbb[i] = 0;
Copy link

Copilot AI Mar 7, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The null check only verifies nsbc, but if nsbf or nsbb failed to allocate (returned NULL), the code will dereference NULL pointers on lines 1440, 1450, and 1451 when writing to nsbf[i] and nsbb[i]. All three allocations should be null-checked before proceeding. If any of them fail, the allocated ones should be freed and the function should skip the scrollback migration (or bail out entirely).

Copilot uses AI. Check for mistakes.
Comment on lines +1295 to +1302
/* Allocate scrollback buffer */
size_t sb_size = TERM_SCROLLBACK_LINES * cols;
term->sb_chars = kmalloc(sb_size);
term->sb_fg = kmalloc(sb_size);
term->sb_bg = kmalloc(sb_size);
term->sb_count = 0;
term->sb_head = 0;
term->scroll_offset = 0;
Copy link

Copilot AI Mar 7, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

term_destroy() (line 1368) does not free the scrollback buffers sb_chars, sb_fg, and sb_bg that are now allocated in term_create(). This is a memory leak. The scrollback buffers should be freed in term_destroy() alongside the other buffers. Since those fields are added by this PR, the destroy function needs to be updated to match.

Copilot uses AI. Check for mistakes.
* the system to hang. TODO: implement proper syscall handlers before
* re-enabling init.
*/
printk(KERN_INFO "Skipping /sbin/init (GUI runs in kernel mode)\\n");
Copy link

Copilot AI Mar 7, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

\\n is a double-escaped newline that will output a literal \n string instead of a newline character. All other printk calls in this file use \n. This should be \n instead of \\n.

Copilot uses AI. Check for mistakes.
#define TERM_HISTORY_LEN 128
char history[32][128];
int history_count;
int history_browse; /* Index when browsing with arrow keys */
Copy link

Copilot AI Mar 7, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The history_browse field is added and initialized but never actually used anywhere. If the intent is to allow browsing command history with arrow keys (as suggested by the welcome message "Use Arrow Up/Down to scroll history"), note that the arrow keys currently control scrollback instead. Consider either implementing history browsing or removing this unused field to avoid confusion.

Suggested change
int history_browse; /* Index when browsing with arrow keys */

Copilot uses AI. Check for mistakes.
term_puts(term, "Type '\033[33mhelp\033[0m' for commands, "
"'\033[33mneofetch\033[0m' for system info.\n\n");
"'\033[33mneofetch\033[0m' for system info.\n");
term_puts(term, "Use \033[33mArrow Up/Down\033[0m to scroll history.\n\n");
Copy link

Copilot AI Mar 7, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The welcome message says "scroll history" but the arrow keys actually control scrollback (viewport scrolling), not command history browsing. This could confuse users who expect arrow up/down to recall previous commands (standard shell behavior). Consider changing the text to "Use Arrow Up/Down to scroll back" or similar wording that accurately describes the scrollback behavior.

Suggested change
term_puts(term, "Use \033[33mArrow Up/Down\033[0m to scroll history.\n\n");
term_puts(term, "Use \033[33mArrow Up/Down\033[0m to scroll back.\n\n");

Copilot uses AI. Check for mistakes.
Comment on lines +1462 to +1470
/* 2. Allocate new visible screen buffer */
size_t new_size = (size_t)new_cols * new_rows;
char *nc = kmalloc(new_size);
uint8_t *nfg = kmalloc(new_size);
uint8_t *nbg = kmalloc(new_size);
if (!nc || !nfg || !nbg) {
if (nc) kfree(nc); if (nfg) kfree(nfg); if (nbg) kfree(nbg);
return;
}
Copy link

Copilot AI Mar 7, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the visible buffer allocation fails here (lines 1467-1469), the function returns early. However, the scrollback buffer may have already been reallocated to new_cols stride in step 1 (lines 1431-1460), while t->cols still holds the old column count. Subsequent calls to term_save_to_scrollback and term_render will use t->cols as the stride into the scrollback buffer, causing out-of-bounds access or data corruption since the scrollback now has new_cols stride. You need to either update t->cols before returning, or roll back the scrollback reallocation on failure.

Copilot uses AI. Check for mistakes.
Comment on lines +1322 to +1327
if (term->sb_chars) {
for (size_t i = 0; i < sb_size; i++) {
term->sb_chars[i] = ' ';
term->sb_fg[i] = 7;
term->sb_bg[i] = 0;
}
Copy link

Copilot AI Mar 7, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The null check only verifies sb_chars before initialization, but if sb_fg or sb_bg failed to allocate, lines 1325 and 1326 will write to NULL pointers. Either check all three pointers, or add the scrollback buffers to the error check at line 1304 (e.g., if (!term->sb_chars || !term->sb_fg || !term->sb_bg) alongside the other checks).

Copilot uses AI. Check for mistakes.
@viralcode
Copy link
Owner

@Mauricio-Leyva did you test this and can you provide a video. i want you to test the last fix commit @9a8d008

@Mauricio-Leyva
Copy link
Author

Yes, I have tested the latest commit 9a8d008 and everything is working smoothly. Here is the video showing the terminal resizing and scrollback:

dynamic_terminal.mp4

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants