From 125e6177853c28fa5e75e9d3287d6329aebe3181 Mon Sep 17 00:00:00 2001 From: Jim Huang Date: Sat, 25 Apr 2026 22:25:08 +0800 Subject: [PATCH] Let no-WM window to match backend dimensions The fbdev backend was creating a screen using the caller-supplied dimensions (640x480 from main.c) instead of the actual framebuffer resolution, causing coordinate space mismatch and clipped rendering on smaller displays like the STM32F429 Discovery QVGA (320x240). In no-WM mode, the single window now unconditionally covers the entire screen rather than merely clamping to it. The screen dimensions are authoritative and come from the backend -- hardware resolution for fbdev, window size for SDL, etc. --- backend/fbdev.c | 15 ++++++++++++--- src/window.c | 20 ++++++++++---------- 2 files changed, 22 insertions(+), 13 deletions(-) diff --git a/backend/fbdev.c b/backend/fbdev.c index ff92274..ad5050a 100644 --- a/backend/fbdev.c +++ b/backend/fbdev.c @@ -235,7 +235,7 @@ static bool twin_fbdev_work(void *closure) return true; } -twin_context_t *twin_fbdev_init(int width, int height) +twin_context_t *twin_fbdev_init(int width maybe_unused, int height maybe_unused) { char *fbdev_path = getenv(FBDEV_NAME); if (!fbdev_path) { @@ -283,6 +283,15 @@ twin_context_t *twin_fbdev_init(int width, int height) goto bail_vt_fd; } + /* Use actual framebuffer resolution instead of caller-supplied dimensions. + * The physical display size is authoritative -- the caller's width/height + * are only hints suitable for resizable backends like SDL. + * Read directly from fb_var which was already validated by + * twin_fbdev_apply_config() above -- no redundant ioctl needed. + */ + int fb_width = tx->fb_var.xres; + int fb_height = tx->fb_var.yres; + const twin_put_span_t fbdev_put_spans[] = { _twin_fbdev_put_span16, _twin_fbdev_put_span24, @@ -290,8 +299,8 @@ twin_context_t *twin_fbdev_init(int width, int height) }; /* Create TWIN screen */ ctx->screen = twin_screen_create( - width, height, NULL, fbdev_put_spans[tx->fb_var.bits_per_pixel / 8 - 2], - ctx); + fb_width, fb_height, NULL, + fbdev_put_spans[tx->fb_var.bits_per_pixel / 8 - 2], ctx); if (!ctx->screen) { log_error("Failed to create screen"); goto bail_fb_unmap; diff --git a/src/window.c b/src/window.c index 8e31aa9..69c9bac 100644 --- a/src/window.c +++ b/src/window.c @@ -63,17 +63,19 @@ twin_window_t *twin_window_create(twin_screen_t *screen, width += left + right; height += top + bottom; #else - /* No-WM: ignore position, clamp to screen, no decorations */ + /* No-WM: the single window always covers the entire screen + * regardless of what the application requested. The screen + * dimensions are authoritative -- they come from the backend + * (hardware resolution for fbdev, window size for SDL, etc.). + */ left = 0; top = 0; right = 0; bottom = 0; x = 0; y = 0; - if (width > screen->width) - width = screen->width; - if (height > screen->height) - height = screen->height; + width = screen->width; + height = screen->height; #endif window->client.left = left; @@ -156,14 +158,12 @@ void twin_window_configure(twin_window_t *window, #if defined(CONFIG_WINDOW_MANAGER) _twin_window_style_size(style, &border); #else - /* No-WM: ignore position, clamp to screen, zero margins */ + /* No-WM: always match the screen provided by the backend. */ border.left = border.right = border.top = border.bottom = 0; x = 0; y = 0; - if (width > window->screen->width) - width = window->screen->width; - if (height > window->screen->height) - height = window->screen->height; + width = window->screen->width; + height = window->screen->height; #endif twin_pixmap_disable_update(window->pixmap);