feat(display): windows: full-screen, F1 cycles, OS bar (names, front, user); canvas-only (display-owned buffers, 4 max, reused); launchers OPEN (pm per app, terminal own), window caps minted by display; FORGET on launcher death via init courier; raster crate (font, chunked text); F-keys in input; terminal+snake on canvas; REDRAW gone

This commit is contained in:
2026-10-28 02:48:39 +01:00
parent d04dcfffa1
commit 864f039bc7
45 changed files with 1382 additions and 824 deletions

View File

@@ -83,7 +83,7 @@ optional one is simply not granted.
| Capability | What the app gets |
|---|---|
| `display` | the display server: the screen, and the keyboard while in focus |
| `display` | a window of its own, named from its manifest: its pixels, and the keyboard while it is in front |
| `storage` | the user's `data/<id>/`, read-write (its own folder only) |
## Decisions
@@ -143,10 +143,9 @@ permission manager:
The user withdraws a capability: the decision changes and the next launch
gets less. A running app that held it is **stopped**: all its access dies
at once. (Endpoint capabilities like `display` are copies the permission
manager cannot take back from one app alone yet; once servers issue
per-client badges, as storage does, revoking a single capability from a
running app will not need to stop it.)
at once. (Capabilities like `display` could now be taken back alone, as
storage's grants and the display's windows are issued per app; stopping
the app is still what revoking does.)
### Not yet

View File

@@ -163,13 +163,34 @@ every holder (storage revokes its own copy, so the kernel deletes the
rest), closes their files and unmaps their buffers. Badge 0 (init) is the
whole disk; a badge storage did not issue, or took back, is `DENIED`.
The display server alone holds the screen (`types::display::window`,
client `libkos::display`). It draws the OS bar along the top: every
window's name, the one in front highlighted, and who is signed in (init
says, `SET_USER`). Below it, the window in front fills the screen; one is
in front at a time, a new one comes to the front, and F1 brings the next.
A window is opened (`OPEN`, with the name the bar shows) only through a
launcher's copy of the display endpoint, one init gave a system program:
the terminal opens its own, the permission manager one for each app
granted `display`, named from its manifest. The reply carries a window
capability the display mints itself (badge bit `BADGE`), which can do
nothing but use that window: map its pixel buffer (`BUFFER`), say what
changed (`PRESENT`), take its input (`SUBSCRIBE`, `POLL`), close it. So an
app can neither open more windows nor name its own, nor draw outside its
window. The buffers are the display's: one per slot, at most four, made
once and reused (blank) for each new window, so its memory has a fixed
ceiling; closing a window takes every copy of its buffer back. A window's
opener is remembered: when init sees a program that uses the display go,
it says so (`FORGET`, through its printer thread so it never waits on the
display), and that program's windows close.
Input reaches apps through the display server, the input server's only
client. It subscribes to the input server with a notification, drains it
when signalled, and passes events on to the app in focus: the last one to
subscribe (`types::display::input`). Apps out of focus get nothing.
when signalled, keeps F1, and queues the rest for the window in front,
signalling the notification it subscribed with. Windows behind get
nothing.
The terminal server takes focus and draws text with the display server's
font. Its output side is the log protocol (`types::log`), so a program whose
The terminal server draws its text into its own window (`raster`, which
holds the font). Its output side is the log protocol (`types::log`), so a program whose
log endpoint is the terminal prints there with `println!`: standard output
is whatever text endpoint a program was given. `READ` (`types::terminal`)
blocks until a line is typed and returns it in chunks, the last ending in
@@ -177,8 +198,7 @@ blocks until a line is typed and returns it in chunks, the last ending in
kept for the next one, except Ctrl+C, which signals the notification the
latest `ON_INTERRUPT` caller gave. Only a terminal copy whose badge has
`CONTROL` may register: init mints one for the shell alone, and the copy
the shell passes on to apps is its plain one. `REDRAW` repaints the screen and takes
input focus back.
the shell passes on to apps is its plain one.
The desktop is the shell, given the terminal, the permission manager,
the user's `home/` (its `/`) and signing out. Everything the owner runs is an app (docs/apps.md): a
@@ -187,8 +207,7 @@ client `libkos::apps`) to run it, passing the terminal as its output and a
read-only grant to the current folder (`cd`, `pwd`). The permission manager
adds what the app's manifest asks for and the owner allowed (the display,
its own data folder), runs it, and hands back the process; the shell waits
for its death (Ctrl+C kills it), releases the grant, and has the terminal
redraw if the app had the display. `install`, `apps`, `allow` and `revoke`
for its death (Ctrl+C kills it) and releases the grant. `install`, `apps`, `allow` and `revoke`
manage apps.
Only init holds `ProcessCreate`. Everyone else runs programs through init's