Native Windows port: wheel scrolling, shell launch services, native file picker#5209
Open
shai-almog wants to merge 6 commits into
Open
Native Windows port: wheel scrolling, shell launch services, native file picker#5209shai-almog wants to merge 6 commits into
shai-almog wants to merge 6 commits into
Conversation
Closes the most actionable gaps in Ports/WindowsPort/status.md. Mouse wheel (gap 1b) is now a proper shared API instead of a per-port hack: CodenameOneImplementation.pointerWheelMoved(x, y, scrollX, scrollY) owns the synthetic press/drag/release scroll gesture (spread over four EDT cycles, with the component under the cursor temporarily made non-focusable) and the scrollWheeling / isScrollWheeling() state. The JavaSE port, which carried the original inline implementation, is refactored onto it so every desktop port maps the wheel identically. The Windows WndProc pushes WM_MOUSEWHEEL / WM_MOUSEHWHEEL into the input ring (new CN1_EVENT_MOUSE_WHEEL/_HWHEEL) and drainInput converts the delta to a DPI-scaled distance. Shell launch services (gap 4): a native shellOpen() (ShellExecuteW) backs honest desktop implementations of execute(url), dial() (tel:), sendSMS() (sms:, so getSMSSupport() reports SMS_INTERACTIVE) and sendMessage() (mailto:). Nothing is fabricated -- an absent handler reports failure. Native file picker (gap 4): GetOpenFileNameW (comdlg32) run modally on the window-owning pump thread via a blocking WM_CN1_FILEDIALOG SendMessage, filtered by media type. openGallery / openImageGallery now use the real OS picker and return a file:// path FileSystemStorage opens, instead of the in-app FileTree fallback. comdlg32 + shell32 added to the Windows link set. status.md updated: these gaps move to "done"; the remaining hardware/OS-account capabilities (camera, sensors, location, contacts, push, biometric, audio recording, SIMD) stay honestly unsupported. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
WIN32_LEAN_AND_MEAN keeps shellapi.h out of windows.h and shlobj.h does not pull it in under clang-cl, so ShellExecuteW was an implicit declaration and the clean-target build failed (call to undeclared function / int->HINSTANCE). Add the explicit include. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Contributor
Cloudflare Preview
|
Contributor
✅ ByteCodeTranslator Quality ReportTest & Coverage
Benchmark Results
Static Analysis
Generated automatically by the PR CI workflow. |
Collaborator
Author
|
Compared 128 screenshots: 128 matched. Native Android coverage
✅ Native Android screenshot tests passed. Native Android coverage
Benchmark ResultsDetailed Performance Metrics
|
Collaborator
Author
Native Windows portCompared 124 screenshots: 123 matched, 1 updated. |
Collaborator
Author
|
Compared 11 screenshots: 11 matched. |
PMD's MissingOverride rule is enforced on core; the four anonymous Runnable run() methods added for the shared wheel-scroll gesture need the annotation. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Collaborator
Author
|
Compared 128 screenshots: 128 matched. Benchmark Results
Detailed Performance Metrics
|
Contributor
✅ Continuous Quality ReportTest & Coverage
Static Analysis
Generated automatically by the PR CI workflow. |
Collaborator
Author
|
Compared 121 screenshots: 121 matched. |
Collaborator
Author
|
Compared 124 screenshots: 124 matched. Benchmark Results
Build and Run Timing
Detailed Performance Metrics
|
Collaborator
Author
|
Compared 128 screenshots: 128 matched. Benchmark Results
Build and Run Timing
Detailed Performance Metrics
|
Implements native SIMD for the Windows port (status.md gap 2), the x86/ARM analog of IOSSimd. WindowsSimd overrides the hot-path vector ops with SSE2 (x64) / NEON (arm64) intrinsics in cn1_windows_simd.c; Simd's @concrete gains win=com.codename1.impl.windows.WindowsSimd and WindowsImplementation.createSimd() returns it, so Simd.get().isSupported() is true on Windows. Each kernel vectorizes the bulk with a scalar tail (unaligned load/store, so no aligned allocator); ops SSE2 lacks (int32 mul/min/max/dot) stay scalar on x64 but vectorize on arm64, and any op not overridden inherits the correct portable Simd scalar loop. Covered: int add/sub/mul/min/max/and/or/xor/sum/dot, float add/sub/mul/min/max/ sum/dot, byte add/sub(saturating)/and/or/xor, plus fused replaceTopByteFromUnsignedBytes / blendByMaskTestNonzero. SimdApiTest (already in the Windows suite) gates correctness; new SimdBenchmarkTest times native vs an inline Java scalar loop over a 64K workload, verifies the native result matches, and logs CN1SS:SIMD:BENCH ... speedup=Nx so CI shows the benefit. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Implements getSecureStorage() (status.md gap 4) so the networking layer can read API keys / tokens at rest. WindowsSecureStorage encrypts each value with the Windows Data Protection API (CryptProtectData, bound to the current user's logon) via native dpapiProtect/dpapiUnprotect and persists the ciphertext through CN1 Storage -- the desktop analog of the iOS keychain / Android EncryptedSharedPreferences non-prompting store. The biometric-prompting overloads map to the same store (DPAPI is itself the user-account auth boundary). crypt32 added to the link set. SecureStorageTest round-trips set/get/remove in the suite (self-skips where unsupported, e.g. JS). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Implements scheduleLocalNotification/cancelLocalNotification (status.md gap 4), mirroring the JavaSE desktop semantic: while the app runs a Timer fires the notification at its scheduled time (with REPEAT_* support) and Shell_NotifyIcon shows a tray balloon; clicking it routes the id (WM_CN1_TRAY -> drainInput poll) to the app's LocalNotificationCallback. Native tray/balloon lives in cn1_windows_notify.c, marshaled to the window-owning pump thread via WM_CN1_NOTIFY. Background scheduling fires only while the process runs (no OS scheduler survives app exit on desktop) -- a documented limitation. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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.

Works through the actionable gaps tracked in
Ports/WindowsPort/status.mdfor the new native Win32/Direct2D port.Mouse wheel scrolling — gap 1b (now a shared core API)
Rather than the per-port synthetic-event hack, the wheel→scroll mapping now lives once in core:
CodenameOneImplementation.pointerWheelMoved(x, y, scrollX, scrollY)replays the wheel as a press → drag → release gesture spread over four EDT cycles (so CN1's own tensile/deceleration animates it), temporarily makes the component under the cursor non-focusable so the synthetic press isn't a click, and owns thescrollWheeling/isScrollWheeling()state.WndProcpushesWM_MOUSEWHEEL/WM_MOUSEHWHEELinto the input ring (newCN1_EVENT_MOUSE_WHEEL/_HWHEEL);drainInputconverts the delta to a DPI-scaled distance and calls the shared method.Shell launch services — gap 4
A native
shellOpen()(ShellExecuteW) backs honest desktop implementations ofexecute(url),dial()(tel:),sendSMS()(sms:?body=, sogetSMSSupport()reportsSMS_INTERACTIVE) andsendMessage()(mailto:?subject=&body=). Nothing is fabricated — an absent handler reports failure.Native file picker — gap 4
GetOpenFileNameW(comdlg32) run modally on the window-owning pump thread via a blockingWM_CN1_FILEDIALOGSendMessage, filtered by media type.openGallery/openImageGallerynow use the real OS picker and return afile://pathFileSystemStorageopens, instead of the in-appFileTreefallback.comdlg32+shell32added to the Windows link set.Honesty preserved
status.mdis updated to move these gaps to "done" while keeping the remaining hardware/OS-account capabilities (camera, sensors, location, contacts, push, biometric, audio recording, SIMD) honestly unsupported — they return null/no-op/false rather than fabricating data, per the port's guiding rule.Validation
core,javaseandwindowsMaven modules compile cleanly (the sharedpointerWheelMovedAPI links across modules).ShellExecuteW,GetOpenFileNameW) / input-ring wiring; the gallery/file-dialog path is not exercised headlessly, so it cannot affect the screenshot suite, and falls back gracefully.windows-cross-compile(Linux PE link) +parparvm-tests-windows(clean-target build/run + screenshot suite) are the gates.🤖 Generated with Claude Code