diff --git a/openspec/changes/archive/2026-11-08-arena-size/.openspec.yaml b/openspec/changes/archive/2026-11-08-arena-size/.openspec.yaml new file mode 100644 index 0000000..c0ad5ed --- /dev/null +++ b/openspec/changes/archive/2026-11-08-arena-size/.openspec.yaml @@ -0,0 +1,2 @@ +schema: spec-driven +created: 2026-11-08 diff --git a/openspec/changes/archive/2026-11-08-arena-size/design.md b/openspec/changes/archive/2026-11-08-arena-size/design.md new file mode 100644 index 0000000..cb5cdbf --- /dev/null +++ b/openspec/changes/archive/2026-11-08-arena-size/design.md @@ -0,0 +1,31 @@ +# Design + +## Context + +Output is already bound and a listener exists, but mode dimensions are ignored. See proposal.md. + +## Goals / Non-Goals + +**Goals:** +- Store output mode width/height. +- Compute default logical size = 0.8 * mode / scale. +- Keep grid resize/preserve behavior. + +**Non-Goals:** +- Fullscreen mode. +- Dynamic output hotplug handling beyond first output. + +## Decisions + +### D1: Output mode storage +- Store `output_width`, `output_height` from `wl_output.mode`. + +### D2: Default size computation +- After roundtrip, if output info available, set logical size; else fallback 1024x576. + +### D3: Fallback +- 1024x576 logical (~80% of 1280x720) when no output info. + +## Open Questions + +None. \ No newline at end of file diff --git a/openspec/changes/archive/2026-11-08-arena-size/proposal.md b/openspec/changes/archive/2026-11-08-arena-size/proposal.md new file mode 100644 index 0000000..36a755a --- /dev/null +++ b/openspec/changes/archive/2026-11-08-arena-size/proposal.md @@ -0,0 +1,27 @@ +# Proposal + +## Why + +The current default arena is 400×400 logical pixels (50×50 cells), too small for comfortable exploration. The arena should occupy about 80% of a FullHD screen, adapting to the actual output size and scale. + +## What Changes + +- Use `wl_output` mode dimensions to compute a default logical window size equal to 80% of the output, divided by the active scale. +- Keep the 8 px logical cell size; grid dimensions derive from the logical window size. +- Preserve resizable behavior and grid recalculation on resize. +- Provide a sensible fallback when output info is unavailable. + +## Capabilities + +### New Capabilities + +- `arena-sizing`: output-aware default arena size (~80% of screen) with fallback and resize handling. + +### Modified Capabilities + +None. + +## Impact + +- Affected code: `wlgol.c` (output mode handling, default size calculation, canvas/grid resize). +- No new dependencies. \ No newline at end of file diff --git a/openspec/changes/archive/2026-11-08-arena-size/specs/arena-sizing/spec.md b/openspec/changes/archive/2026-11-08-arena-size/specs/arena-sizing/spec.md new file mode 100644 index 0000000..30252e3 --- /dev/null +++ b/openspec/changes/archive/2026-11-08-arena-size/specs/arena-sizing/spec.md @@ -0,0 +1,42 @@ +# Spec Delta + +## Purpose + +Defines how the arena default size is derived from the output and how resizing affects the grid. + +## ADDED Requirements + +### Requirement: Default arena is about 80% of output +The system SHALL compute the default logical window size as 80% of the output mode dimensions divided by the active scale. + +#### Scenario: Output available +- **WHEN** output mode and scale are known at startup +- **THEN** the default logical window size is approximately 80% of the output + +### Requirement: Fallback when output unknown +The system SHALL use a fallback default size when output info is unavailable. + +#### Scenario: No output info +- **WHEN** output mode is not reported +- **THEN** a fallback logical size is used + +### Requirement: Cell size remains 8 logical pixels +The system SHALL keep an 8 logical pixel cell size. + +#### Scenario: Grid dimensions +- **WHEN** the logical window size is known +- **THEN** grid columns and rows are logical size divided by 8 + +### Requirement: Resizable window +The system SHALL allow the window to be resized by the user. + +#### Scenario: Resize +- **WHEN** the user resizes the window +- **THEN** the grid dimensions update accordingly + +### Requirement: Grid preserved on resize +The system SHALL preserve overlapping cells when the grid dimensions change. + +#### Scenario: Enlarge +- **WHEN** the window grows +- **THEN** existing cells within the old bounds remain \ No newline at end of file diff --git a/openspec/changes/archive/2026-11-08-arena-size/tasks.md b/openspec/changes/archive/2026-11-08-arena-size/tasks.md new file mode 100644 index 0000000..8f9c777 --- /dev/null +++ b/openspec/changes/archive/2026-11-08-arena-size/tasks.md @@ -0,0 +1,11 @@ +# Tasks + +## 1. Output handling + +- [x] 1.1 Store output mode dimensions in the output listener. +- [x] 1.2 Compute default logical window size as 80% of output divided by scale, with fallback. + +## 2. Verification + +- [x] 2.1 Build and run, verifying window is ~80% of screen. +- [x] 2.2 Resize window and verify grid updates. \ No newline at end of file diff --git a/openspec/specs/arena-sizing/spec.md b/openspec/specs/arena-sizing/spec.md new file mode 100644 index 0000000..a242a39 --- /dev/null +++ b/openspec/specs/arena-sizing/spec.md @@ -0,0 +1,41 @@ +# arena-sizing Specification + +## Purpose +Defines how the arena default size is derived from the output and how resizing affects the grid. + +## Requirements + +### Requirement: Default arena is about 80% of output +The system SHALL compute the default logical window size as 80% of the output mode dimensions divided by the active scale. + +#### Scenario: Output available +- **WHEN** output mode and scale are known at startup +- **THEN** the default logical window size is approximately 80% of the output + +### Requirement: Fallback when output unknown +The system SHALL use a fallback default size when output info is unavailable. + +#### Scenario: No output info +- **WHEN** output mode is not reported +- **THEN** a fallback logical size is used + +### Requirement: Cell size remains 8 logical pixels +The system SHALL keep an 8 logical pixel cell size. + +#### Scenario: Grid dimensions +- **WHEN** the logical window size is known +- **THEN** grid columns and rows are logical size divided by 8 + +### Requirement: Resizable window +The system SHALL allow the window to be resized by the user. + +#### Scenario: Resize +- **WHEN** the user resizes the window +- **THEN** the grid dimensions update accordingly + +### Requirement: Grid preserved on resize +The system SHALL preserve overlapping cells when the grid dimensions change. + +#### Scenario: Enlarge +- **WHEN** the window grows +- **THEN** existing cells within the old bounds remain diff --git a/wlgol.c b/wlgol.c index 3a02257..5707175 100644 --- a/wlgol.c +++ b/wlgol.c @@ -31,6 +31,8 @@ struct xdg_wm_base *xdg_shell; struct wl_seat *wl_seat; struct wl_output *wl_output = NULL; int output_scale_factor = 1; +int output_width = 0; +int output_height = 0; struct keyboard_data keyboard_data; struct pointer_data pointer_data; @@ -83,7 +85,13 @@ struct wp_fractional_scale_v1 *fractional_scale = NULL; // output listener static void output_geometry_handler(void *data, struct wl_output *output, int32_t x, int32_t y, int32_t phys_w, int32_t phys_h, int32_t subpixel, const char *make, const char *model, int32_t transform) { (void)data;(void)output;(void)x;(void)y;(void)phys_w;(void)phys_h;(void)subpixel;(void)make;(void)model;(void)transform; } -static void output_mode_handler(void *data, struct wl_output *output, uint32_t flags, int32_t width, int32_t height, int32_t refresh) { (void)data;(void)output;(void)flags;(void)width;(void)height;(void)refresh; } +static void output_mode_handler(void *data, struct wl_output *output, uint32_t flags, int32_t width, int32_t height, int32_t refresh) { + (void)data;(void)output;(void)flags;(void)refresh; + if (width > 0 && height > 0) { + output_width = width; + output_height = height; + } +} static void output_done_handler(void *data, struct wl_output *output) { (void)data;(void)output; } static void output_scale_handler(void *data, struct wl_output *output, int32_t factor) { (void)data;(void)output; @@ -426,12 +434,21 @@ int main(void) wl_pointer_add_listener(pointer_data.pointer, &pointer_listener, &pointer_data); canvas.fd = -1; + logical_width = 1024; + logical_height = 576; grid_init(&grid, logical_width / 8, logical_height / 8); grid.show_lines = 1; // wait for the surface to be configured wl_display_roundtrip(display); + if (output_width > 0 && output_height > 0 && current_scale > 0) { + logical_width = (int)(output_width * 0.8 / current_scale); + logical_height = (int)(output_height * 0.8 / current_scale); + } + if (logical_width < 8) logical_width = 8; + if (logical_height < 8) logical_height = 8; + /* initial scale may arrive via fractional/output after roundtrip */ if (fractional_manager && !fractional_scale) { /* already created above */