Skip to content

Fix win32 widget sizing, slider events, scroll view#123

Open
pmarreck wants to merge 2 commits intocapy-ui:masterfrom
pmarreck:pr/win32-bug-fixes
Open

Fix win32 widget sizing, slider events, scroll view#123
pmarreck wants to merge 2 commits intocapy-ui:masterfrom
pmarreck:pr/win32-bug-fixes

Conversation

@pmarreck
Copy link

Summary

Three win32 backend bug fixes. Depends on #122 (Zig 0.15.2 migration) — please merge that first.

1. Dynamic getPreferredSize (was hardcoded 100×50)

The win32 Events.getPreferredSize() returned a hardcoded Size(100, 50) for all widgets. This caused layout issues when the layout engine used preferred sizes.

Fix: Added measureWindowText() helper that uses GDI text measurement (GetDCSelectObject(font)GetTextExtentPoint32WReleaseDC), and per-widget getPreferredSize_impl overrides:

Widget Sizing logic
Label text + 4px/2px padding, min 20×16
Button text + 16px/10px chrome, min 75×23
CheckBox text + SM_CXMENUCHECK indicator + 8px, min 40×20
TextField text + 8px padding, min 150×23
TextArea text + 8px padding, min 200×100
Slider fixed 200×25
Dropdown text + 30px arrow, min 100×23

2. Slider WM_HSCROLL not dispatching property changes

The trackbar control sends WM_HSCROLL to its parent window with lParam pointing to the trackbar HWND. The handler was treating all WM_HSCROLL messages as scrollbar events, so slider value changes were lost.

Fix: Check lParam: when non-zero, dispatch through the child trackbar's propertyChangeHandler (converting the integer position back to float using stepSize). When zero, handle as scrollbar event (existing code).

3. ScrollView child clipping

When a child's preferred size was smaller than the scroll view's visible area, the child was sized smaller than the viewport, leaving dead space.

Fix: Clamp child dimensions to @max(preferred, visible_area), matching NSScrollView/GtkScrolledWindow behavior.

Test plan

  • Compiles cleanly on x86_64-windows-gnu (all 22 examples)
  • Manual testing on Windows (slider interaction, scroll views, widget layout)

This migrates the entire codebase from Zig 0.14.1 to Zig 0.15.2.

Key API changes:
- Remove `usingnamespace` (removed from the language) — all mixins
  now use explicit re-export of each declaration
- `ArrayList.init(allocator)` → `.empty` + pass allocator to each
  method call (deinit, append, appendSlice, etc.)
- `callconv(.C)` → `callconv(.c)` (lowercase enum literals)
- `std.os.windows.WINAPI` → `std.builtin.CallingConvention.winapi`
- `std.fmt.allocPrintZ` → `std.fmt.allocPrintSentinel`
- `std.atomic.Atomic` → `std.atomic.Value`
- `std.sort.sort` → `std.mem.sort`
- `std.time.sleep` → `std.Thread.sleep`
- `SinglyLinkedList` became intrusive (compat wrapper added in data.zig)
- `BoundedArray` removed (compat replacement in containers.zig)
- `anyframe` removed (async.zig stubbed)
- `std.Uri.path` API changes (toRaw signature)
- format function signatures changed
- zigimg StreamSource → ReadStream API

Also updates:
- vendor/zigwin32 for 0.15.2 compatibility
- build.zig / build_capy.zig for 0.15.2 build API
- build.zig.zon dependency hashes (zig-objc, zigimg)
- flake.nix / flake.lock for Zig 0.15.2 toolchain

All 28 examples compile successfully on both x86_64-windows-gnu
(cross-compile) and native macOS (aarch64-macos).
Three win32 backend bug fixes:

1. **Dynamic getPreferredSize**: Widgets now measure their actual text
   content via GDI (GetTextExtentPoint32W) instead of returning a
   hardcoded 100×50 fallback. Added measureWindowText() helper and
   per-widget getPreferredSize_impl for Label, Button, CheckBox,
   TextField, TextArea, Slider, and Dropdown.

2. **Slider WM_HSCROLL property change**: The trackbar control sends
   WM_HSCROLL to its parent with lParam pointing to the trackbar HWND.
   Previously this was handled as a scrollbar event, losing the slider
   value change notification. Now dispatches through propertyChangeHandler
   when lParam != 0 (trackbar child) vs lParam == 0 (scrollbar).

3. **ScrollView child sizing**: Child components are now clamped to at
   least the visible area dimensions, matching NSScrollView/GtkScrolledWindow
   behavior. Previously a child with a small preferred size would be
   clipped smaller than the viewport.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant