diff options
| author | salmonik <salmonik@tuta.io> | 2026-08-19 18:46:35 +0200 |
|---|---|---|
| committer | salmonik <salmonik@tuta.io> | 2026-08-19 18:46:35 +0200 |
| commit | 09a44f15678f27dd3d07f90e9ed0e71cf0e771ff (patch) | |
| tree | e9942dd03df3eb16b5b261cb6b0e129390593ef6 /rsnix/src/vt.rs | |
| parent | vt → per-instance Terminal rendering into a pixel buffer (diff) | |
| download | rs-dos-09a44f15678f27dd3d07f90e9ed0e71cf0e771ff.tar.gz rs-dos-09a44f15678f27dd3d07f90e9ed0e71cf0e771ff.zip | |
wm: integrate home terminal as window 0 + fix console focus after close
- wm rewrite: chrome flag per window, create_home_window for the
console (window 0, chrome-less, bottom-pinned, never closed),
composite_rect fills desktop background then blits windows bottom-to-top,
draw_window_intersect handles chrome-less windows, hit_test returns
Content for chrome-less, destroy/move_window no-op for id 0.
- vt: add window_params() so main.rs can wire the Terminal to wm window 0.
- main.rs: create home terminal window 0 and attach Terminal after wm::init().
- Focus fix: focus(0) now stores CONSOLE sentinel (not raw 0) so
focused() returns None when the home terminal has focus. Without this,
closing a GUI window left FOCUSED=0, which tty::poll_key() interpreted
as 'a GUI app has focus', spinning forever and swallowing all keyboard
input.
Diffstat (limited to 'rsnix/src/vt.rs')
| -rw-r--r-- | rsnix/src/vt.rs | 15 |
1 files changed, 14 insertions, 1 deletions
diff --git a/rsnix/src/vt.rs b/rsnix/src/vt.rs index 90264f6..12e2cdc 100644 --- a/rsnix/src/vt.rs +++ b/rsnix/src/vt.rs | |||
| @@ -80,6 +80,7 @@ pub struct Terminal { | |||
| 80 | cur: usize, | 80 | cur: usize, |
| 81 | pending_scrolls: usize, | 81 | pending_scrolls: usize, |
| 82 | last_sync_tick: u64, | 82 | last_sync_tick: u64, |
| 83 | dirty_all: bool, | ||
| 83 | buffer: Vec<u32>, | 84 | buffer: Vec<u32>, |
| 84 | w: usize, | 85 | w: usize, |
| 85 | h: usize, | 86 | h: usize, |
| @@ -128,6 +129,7 @@ impl Terminal { | |||
| 128 | cur: 0, | 129 | cur: 0, |
| 129 | pending_scrolls: 0, | 130 | pending_scrolls: 0, |
| 130 | last_sync_tick: 0, | 131 | last_sync_tick: 0, |
| 132 | dirty_all: true, | ||
| 131 | buffer: vec![0; w * h], | 133 | buffer: vec![0; w * h], |
| 132 | w, | 134 | w, |
| 133 | h, | 135 | h, |
| @@ -140,6 +142,11 @@ impl Terminal { | |||
| 140 | self.window_id = Some(id); | 142 | self.window_id = Some(id); |
| 141 | } | 143 | } |
| 142 | 144 | ||
| 145 | /// Buffer pointer and pixel dimensions (for the WM to composite). | ||
| 146 | pub fn window_params(&self) -> (*const u32, usize, usize) { | ||
| 147 | (self.buffer.as_ptr(), self.w, self.h) | ||
| 148 | } | ||
| 149 | |||
| 143 | pub fn ready(&self) -> bool { | 150 | pub fn ready(&self) -> bool { |
| 144 | self.rows != 0 | 151 | self.rows != 0 |
| 145 | } | 152 | } |
| @@ -193,6 +200,7 @@ impl Terminal { | |||
| 193 | } | 200 | } |
| 194 | self.pending_scrolls = 0; | 201 | self.pending_scrolls = 0; |
| 195 | self.last_sync_tick = crate::interrupts::TICKS.load(core::sync::atomic::Ordering::Relaxed); | 202 | self.last_sync_tick = crate::interrupts::TICKS.load(core::sync::atomic::Ordering::Relaxed); |
| 203 | self.dirty_all = true; | ||
| 196 | self.flush(); | 204 | self.flush(); |
| 197 | } | 205 | } |
| 198 | 206 | ||
| @@ -509,7 +517,12 @@ impl Terminal { | |||
| 509 | let n = rows * cols; | 517 | let n = rows * cols; |
| 510 | let cursor_visible = self.cursor_visible; | 518 | let cursor_visible = self.cursor_visible; |
| 511 | let (cr, cc) = (self.cursor_r, self.cursor_c); | 519 | let (cr, cc) = (self.cursor_r, self.cursor_c); |
| 512 | let mut dirty: Option<(usize, usize, usize, usize)> = None; | 520 | let mut dirty = if self.dirty_all { |
| 521 | self.dirty_all = false; | ||
| 522 | Some((0, 0, self.w, self.h)) | ||
| 523 | } else { | ||
| 524 | None | ||
| 525 | }; | ||
| 513 | 526 | ||
| 514 | // Diff cells vs rendered, re-blitting changed cells into the buffer. | 527 | // Diff cells vs rendered, re-blitting changed cells into the buffer. |
| 515 | for i in 0..n { | 528 | for i in 0..n { |
