-
-
Notifications
You must be signed in to change notification settings - Fork 5
GUI Subsystem
A double-buffered window compositor over a VBE linear framebuffer. Up to 32 windows across 4 workspaces, with a taskbar, Start menu, drag-reorderable desktop icons, keyboard window management, and a "Nightfall" purple theme driven from a single palette header.
See also: Desktop Applications, Selene Browser, Image Decoders, Drivers, Boot Process
Bochs VBE extensions set the mode; the linear framebuffer lives at 0xE0000000. Default is 1024×768×32, changeable at runtime with setres <w> <h> or mode <w> <h> <bpp>.
fb.c provides the primitives: fb_put_pixel, fb_fill_rect, fb_blit, fb_draw_char, rounded-rectangle helpers, and a clip region (which is what makes rounded window corners possible without drawing outside the frame).
fb_enable_backbuffer() redirects fb_addr to a RAM back buffer the size of the screen. Drawing is then invisible until fb_present() blits the whole thing to the hardware framebuffer in one shot — which is what eliminates flicker. The login screen deliberately calls fb_use_lfb_direct() to draw straight to the LFB instead.
Everything in the compositor is laid out on a 1024×768 design grid and scaled to the live framebuffer. Deriving coordinates from fb_get_width() in drawing code applies the scale twice — a bug that has been fixed more than once.
The IBM VGA 8×16 ROM font, 256 glyphs, rendered by font_draw_string.
Windows are kept in z-order, each assigned to a workspace. The window list is capped at MAX_WINDOWS (32).
- Title bar with a gradient, drop shadow, and rounded top corners
- Minimise / maximise / close buttons
- Focused windows take the brand accent colour
- Drag to move, edge-drag to resize
| Shortcut | Action |
|---|---|
| Alt+Tab | Cycle focus in a stable, repeatable order |
| Alt+F4 | Close the focused window |
| Alt+←/→ | Snap to the left or right half (pressing the same side again un-snaps) |
| Alt+↑ | Maximise, or climb the snap ladder |
| Alt+↓ | Restore, or descend the snap ladder |
Snapping is a two-axis grid — a horizontal side plus a vertical zone — so Alt+←then Alt+↑ gives a quarter tile. Snapped and maximised geometry is defined by the screen, so it is re-derived when the resolution changes rather than snapping back to stale coordinates.
- Icons wrap into a grid that reflows on a resolution change, so shrinking the screen never strands one off the edge. Each app has its own drawn emblem, and icons can be drag-reordered.
- Taskbar with window buttons, a clock, workspace indicators, and a user badge — clicking it opens a menu to change your profile picture or log out (returning to the login screen without a reboot).
- Start menu and a right-click desktop context menu, both sharing one visual style.
-
4 workspaces (
WORKSPACE_COUNT).
When nothing is happening the compositor sleep(5)s instead of busy-polling, handing the CPU to background jobs. Any input skips the sleep, so the worst-case response is 5 ms. While a foreground ring-3 job runs, the compositor recomposites at roughly 16 fps, which is what lets full-screen TUIs like top and edit render live inside the terminal window.
A ring-3 program that calls fbpresent() owns the whole screen for as long as it keeps calling it; the compositor yields and returns shortly after the program stops. This is the path DOOM uses — see Syscalls.
Every GUI colour is a named role, not a literal, so the desktop can be re-themed from one file:
#define THEME_ACCENT fb_rgb(130, 90, 210) /* brand purple, "Morado" */
#define THEME_ACCENT_DIM fb_rgb( 92, 64, 150)
#define THEME_ON_ACCENT fb_rgb(255, 255, 255)They are macros rather than a const struct because fb_rgb() is a runtime function — this keeps the header a pure compile-time constant set with no initialisation order to worry about, and leaves room for a runtime theme later without touching a single call site.
Important
New GUI colours belong here as a role, not as a fresh fb_rgb(…) literal at the call site. Before theme.h existed, every colour was scattered across compositor.c and each *_win.c, and re-theming meant hunting call sites.
| Role | RGB | Used for |
|---|---|---|
THEME_ACCENT |
130, 90, 210 | Brand purple, "Morado" |
THEME_ACCENT_DIM |
92, 64, 150 | Pressed / darker accent |
THEME_ON_ACCENT |
255, 255, 255 | Text and icons on an accent fill |
THEME_WINDOW_BG |
45, 45, 50 | Window and menu body |
THEME_PANEL |
30, 30, 35 | Insets, list backgrounds |
THEME_PANEL_HEADER |
40, 45, 55 | Panel headers |
THEME_BORDER |
100, 100, 100 | 1 px window/menu border |
THEME_ROW_DIV |
55, 55, 60 | Row separators |
THEME_TITLE_ACTIVE |
= THEME_ACCENT
|
Focused title bar |
THEME_TITLE_INACTIVE |
80, 85, 95 | Unfocused title bar |
THEME_TITLE_TEXT |
255, 255, 255 | Title-bar text |
THEME_FRAME_HI |
180, 180, 180 | Frame top and left, unfocused |
THEME_FRAME_LO |
80, 80, 80 | Frame bottom and right, unfocused |
THEME_BUTTON |
60, 70, 80 | Button fill |
THEME_TASKBAR_BG |
40, 45, 55 | Taskbar background |
THEME_TASKBAR_FG |
220, 220, 220 | Taskbar text |
THEME_TASKBAR_HL |
= THEME_ACCENT
|
Active menu, focused window button |
THEME_INDICATOR_ON |
240, 240, 245 | Current workspace |
THEME_INDICATOR_OFF |
80, 80, 80 | Other workspaces |
THEME_SELECTION |
= THEME_ACCENT
|
Selected item |
THEME_TEXT |
230, 230, 240 | Body text |
THEME_TEXT_DIM |
175, 175, 185 | Secondary text |
The GUI terminal is an 80×24 character grid with 2000 lines of scrollback.
| Feature | Detail |
|---|---|
| Scrollback | PgUp/PgDn, mouse wheel, and a scrollbar |
| History | Command recall |
| Tab completion | Builtins, .elf programs, and filesystem paths |
| Working directory | Per-window |
| Colour | ANSI SGR (ESC[…m) — ls --color, the editor status bar |
Full-screen TUIs need cursor addressing, so the terminal implements a CSI parser:
| Sequence | Effect |
|---|---|
ESC[row;colH |
Cursor position |
ESC[H / ESC[f
|
Home |
ESC[2J |
Clear screen |
ESC[K |
Clear to end of line |
ESC[…m |
SGR colour and attributes |
On the first CSI sequence the terminal switches from scrollback to screen mode: the line buffer becomes a fixed grid and the editing point renders as an inverted block cursor. It reverts when the command exits.
Ctrl-A…Ctrl-Z arrive as control bytes 0x01…0x1A for editor bindings, with Ctrl-C still raising SIGINT and Ctrl-Z raising SIGTSTP against the foreground process.
A kernel panic draws a visual stop screen with the faulting RIP, CS, ring and error code, rather than freezing silently. Before this, a double fault triple-faulted and rebooted instantly — the IST stacks had never worked, because the TSS struct carried three leftover 32-bit dwords that shifted every IST pointer four bytes early.
Ten desktop icons: Files, Terminal, Editor, Viewer, Settings, Paint, Sounds, Calc, Games, Selene, plus About and Shutdown from the Start menu. Each is a *_win.c file in kernel/.
They have their own page: Desktop Applications.
- Desktop Applications - the applications built on this
- HOWTO Add a GUI application - the application contract, step by step
-
Kernel Data Structures -
window_tfield by field - Drivers - VBE, keyboard and mouse
-
Bochs VBE extensions - the display interface behind
vbe.c - ECMA-48 control functions - the CSI/SGR sequences implemented by the terminal
NyxOS v6.4.363 · GPL v2 · GitHub · uselessalter on Discord · nyxos@inbox.lv
NyxOS Wiki
Getting started
Kernel
Storage & network
Graphics & apps
Userspace
HOWTO
- HOWTO-Add-a-system-call
- HOWTO-Write-a-userspace-program
- HOWTO-Add-a-shell-command
- HOWTO-Add-a-GUI-application
Reference
- Syscall-Reference
- Command-Reference
- Hardware-Reference
- Format-Reference
- Kernel-Data-Structures
- Source-Tree-Reference
Project