fix: kernel and desktop bug fixes

This commit is contained in:
2026-05-14 11:31:14 +02:00
parent a7ff1f0a72
commit bb12aeb9b9
11 changed files with 507 additions and 106 deletions
+44 -15
View File
@@ -72,8 +72,14 @@ void gui::desktop_close_window(DesktopState* ds, int idx) {
if (win->on_close) win->on_close(win);
// Free content buffer (skip for external windows — shared memory)
if (win->content && !win->external) {
if (win->external) {
// Drop our mapping of the shared pixel buffer so the page table doesn't
// keep leaking mappings each time the user closes an external window.
if (win->content != nullptr) {
montauk::win_unmap(win->ext_win_id);
win->content = nullptr;
}
} else if (win->content) {
montauk::free(win->content);
win->content = nullptr;
}
@@ -182,23 +188,46 @@ void gui::desktop_draw_window(DesktopState* ds, int idx) {
Rect cr = desktop_content_rect(win);
if (win->content) {
if (win->external && (cr.w != win->content_w || cr.h != win->content_h)) {
// Nearest-neighbor scale for external windows (fixed-size shared buffer)
// Nearest-neighbor scale for external windows (fixed-size shared buffer).
// Pre-clip the destination range so the inner loop avoids per-pixel
// framebuffer bounds checks. Avoid stack-allocated lookup tables —
// the desktop user stack is only 32 KiB and shared with TrueType.
int src_w = win->content_w;
int src_h = win->content_h;
int dst_w = cr.w;
int dst_h = cr.h;
uint32_t* buf = fb.buffer();
int pitch = fb.pitch();
for (int y = 0; y < dst_h; y++) {
int dy = cr.y + y;
if (dy < 0 || dy >= fb.height()) continue;
int sy = y * src_h / dst_h;
uint32_t* dst_row = (uint32_t*)((uint8_t*)buf + dy * pitch);
uint32_t* src_row = win->content + sy * src_w;
for (int x = 0; x < dst_w; x++) {
int dx = cr.x + x;
if (dx < 0 || dx >= fb.width()) continue;
dst_row[dx] = src_row[x * src_w / dst_w];
if (src_w <= 0 || src_h <= 0 || dst_w <= 0 || dst_h <= 0) {
// nothing to do
} else {
int fbw = fb.width();
int fbh = fb.height();
uint32_t* buf = fb.buffer();
int pitch = fb.pitch();
int x_start = 0;
int x_end = dst_w;
if (cr.x < 0) x_start = -cr.x;
if (cr.x + dst_w > fbw) x_end = fbw - cr.x;
if (x_start < 0) x_start = 0;
if (x_end > dst_w) x_end = dst_w;
int y_start = 0;
int y_end = dst_h;
if (cr.y < 0) y_start = -cr.y;
if (cr.y + dst_h > fbh) y_end = fbh - cr.y;
if (y_start < 0) y_start = 0;
if (y_end > dst_h) y_end = dst_h;
for (int y = y_start; y < y_end; y++) {
int dy = cr.y + y;
int sy = y * src_h / dst_h;
if (sy >= src_h) sy = src_h - 1;
uint32_t* dst_row = (uint32_t*)((uint8_t*)buf + dy * pitch);
uint32_t* src_row = win->content + sy * src_w;
for (int x = x_start; x < x_end; x++) {
int sx = x * src_w / dst_w;
if (sx >= src_w) sx = src_w - 1;
dst_row[cr.x + x] = src_row[sx];
}
}
}
} else {