win32: native-control backend (child HWNDs over the framebuffer) - #89
Merged
Conversation
Add internal/win32/native_windows.go, the Windows peer of the Cocoa native-control backend, so toolkit.Native descriptors become real Win32 child controls parented to the framebuffer window. Each frame the app describes the controls it wants (a Surface's Controls provider or WalkNative over a widget tree); the backend reconciles a map[Key]*liveControl -- creating new children, repositioning and value-updating existing ones, destroying gone ones. The value binding is immediate-mode-safe exactly as in Cocoa: a value is pushed into a control only when it differs from what the control last reported, so the person's caret and selection are never disturbed. Control kinds: NativeButton -> BUTTON (BS_PUSHBUTTON) NativeLabel -> STATIC NativeEntry -> EDIT (WS_BORDER|ES_AUTOHSCROLL) NativeSecureEntry -> EDIT (ES_PASSWORD) NativeCheckbox -> BUTTON (BS_AUTOCHECKBOX) NativeRadio -> BUTTON (BS_AUTORADIOBUTTON) NativeSwitch -> BUTTON (BS_AUTOCHECKBOX; no native toggle pre-WinUI) NativeSlider -> msctls_trackbar32 (InitCommonControlsEx, float<->int) NativePopUp -> COMBOBOX (CBS_DROPDOWNLIST, CB_ADDSTRING items) Notifications flow the idiomatic way: children send the parent WM_COMMAND (BN_CLICKED / EN_CHANGE / CBN_SELCHANGE) and the trackbar sends WM_HSCROLL; wndProc routes both to onCommand/onHScroll, which look the control up by HWND and report through the liveControl's app callbacks. The parent gains WS_CLIPCHILDREN so the StretchDIBits blit never paints over a child. syncNative is seeded in Run and reconciled each frame via paintFrame. Rects arrive in framebuffer coordinates and are scaled to physical client pixels by frameScale (identity in the native/physical-framebuffer model). Tests: native_windows_test.go mirrors the Cocoa gatherNative provider-vs- walk unit test (runs on the windows lane); nativelive_windows_test.go is the WINDOW_WIN32_INTEGRATION-gated on-device proof. Cross-builds clean for windows/amd64 and windows/arm64; gofmt and go vet clean; the Linux 100% coverage gate is unaffected (the new files are windows-tagged).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The Windows peer of the cocoa native-control backend (window v0.59.0).
toolkit.NativeControldescriptors become real Win32 child HWNDs parented to the framebuffer window — the structural analog of NSView subviews. Mirrors the cocoaliveControl/syncNative/applySpec/makeControlstructure and the immediate-mode-safe value-diff binding exactly.Controls (all nine kinds)
Notifications (native → app)
The idiomatic parent-notification path: children send the parent WM_COMMAND (BN_CLICKED / EN_CHANGE / CBN_SELCHANGE), the trackbar WM_HSCROLL.
wndProcroutes these toonCommand/onHScroll, which look the control up by HWND and report through the liveControl's app callbacks, then repaint.syncNativeis hooked at the same per-frame points cocoa uses; the parent gains WS_CLIPCHILDREN so the StretchDIBits blit never paints over a child.Verification
Cross-builds clean for windows/amd64 + windows/arm64;
go vet+gofmtclean; no host regression; the Linux 100% coverage gate oninternal/win32is unaffected (new files are windows-tagged). A puregatherNativeunit test (windows lane) mirrors cocoa's; a gated on-device test (WINDOW_WIN32_INTEGRATION) is the runtime proof.Honest caveat: verified by cross-compilation and structural parity with the proven cocoa backend — not executed on real Windows in this environment. Runtime behaviour (control creation, WM_COMMAND delivery, trackbar scroll, combo selection) awaits the on-device test.