Skip to content

Add device input and form-factor APIs (pointer detail, mouse buttons, wheel, stylus, foldables)#5309

Merged
liannacasper merged 9 commits into
masterfrom
feature/device-input-and-form-factors
Jun 30, 2026
Merged

Add device input and form-factor APIs (pointer detail, mouse buttons, wheel, stylus, foldables)#5309
liannacasper merged 9 commits into
masterfrom
feature/device-input-and-form-factors

Conversation

@shai-almog

Copy link
Copy Markdown
Collaborator

Summary

Adds the cross-platform device-input and form-factor APIs that Codename One was missing: rich pointer detail (mouse buttons, pen pressure/tilt, pointing-device type), a universal mouse-wheel/trackpad event, foldable device posture, and desktop-windowing / multi-display awareness. Everything is additive and backward compatible — every value has a safe default, so existing apps are unaffected and code written against the new APIs runs everywhere.

What's included

  • PointerEvent — immutable snapshot: button, button mask, pointer type (touch/mouse/stylus/eraser), pressure, tilt, contact size, modifiers, hover. Read it from ActionEvent.getPointerEvent() or poll CN/Display (getPointerButton, getPointerPressure, getPointerType, isStylusPointer, …).
  • 2/3-button mice + secondary click — button constants/mask and Component.addContextMenuListener (fires on right-click and long-press). Wired in JavaSE, Android (getButtonState), iOS.
  • Mouse wheel (universal)WheelEvent + Component.addMouseWheelListener (consume to suppress scroll), horizontal scroll, and a precise flag for trackpads. iOS trackpad / Magic Mouse / wheel are captured natively (UIPanGestureRecognizer) and routed through the same pointerWheelMoved pipeline, so WheelEvent is one scroll-gesture API across JavaSE/Android/iOS.
  • Stylus/pen — pressure, tilt, eraser via Component.addStylusListener; Android getToolType/getPressure/AXIS_TILT, iOS Apple Pencil force/altitudeAngle/azimuthAngle.
  • FoldablesDevicePosture (posture, hinge orientation, fold/occlusion bounds) + Display.addPostureListener. Android reads androidx.window through reflection, pulled in only when android.foldableSupport=true (zero weight otherwise). The JavaSE simulator can drive a simulated posture for testing.
  • Desktop windowing / displaysisDesktopMode (DeX/Stage Manager), getDisplayCount, isExternalDisplayConnected.

Design notes

  • Pointer metadata follows the existing isShiftKeyDown() precedent — current state on the implementation plus a dispatch-time snapshot — rather than threading through the hot EDT event queue.
  • Device-input listeners are dispatched from Form (the single chokepoint) so they work even for components like Button that override the pointer methods without calling super.

Docs

docs/developer-guide/Device-Input-And-Form-Factors.asciidoc (registered in the guide).

Tests / validation

  • maven/core-unittests: PointerEventTest, WheelEventTest, PointerMetadataTest, DevicePostureTest, DeviceInputListenersTest. Full suite green: 3676 tests, 0 failures.
  • Built locally: core + JavaSE; iOS port + app + arm64 Xcode link (native trackpad recognizer + Apple Pencil upcall compile and link); Android port (foldable reflection helper compiles); hellocodenameone app (interactive DeviceInputDemo + DeviceInputApiTest).

Note: the matching android.foldableSupport gradle-dependency block has been mirrored to the cloud build daemon's AndroidGradleBuilder; the iOS native changes reach the daemon via the published codenameone-ios artifact.

🤖 Generated with Claude Code

@github-actions

github-actions Bot commented Jun 29, 2026

Copy link
Copy Markdown
Contributor

Developer Guide build artifacts are available for download from this workflow run:

Developer Guide quality checks:

  • AsciiDoc linter: No issues found (report)
  • Vale: No alerts found (report)
  • Paragraph capitalization: No paragraph capitalization issues (report)
  • LanguageTool: No grammar matches (report)
  • Image references: No unused images detected (report)

@shai-almog

shai-almog commented Jun 29, 2026

Copy link
Copy Markdown
Collaborator Author

Compared 11 screenshots: 11 matched.
✅ JavaSE simulator integration screenshots matched stored baselines.

@github-actions

Copy link
Copy Markdown
Contributor

Cloudflare Preview

@shai-almog

shai-almog commented Jun 29, 2026

Copy link
Copy Markdown
Collaborator Author

Compared 139 screenshots: 139 matched.

Native Android coverage

  • 📊 Line coverage: 9.18% (9152/99743 lines covered) [HTML preview] (artifact android-coverage-report, jacocoAndroidReport/html/index.html)
    • Other counters: instruction 8.07% (44885/556236), branch 3.73% (1888/50588), complexity 4.02% (2161/53777), method 6.26% (1754/28022), class 10.21% (406/3978)
    • Lowest covered classes
      • kotlin.collections.kotlin.collections.ArraysKt___ArraysKt – 0.00% (0/6327 lines covered)
      • kotlin.collections.unsigned.kotlin.collections.unsigned.UArraysKt___UArraysKt – 0.00% (0/2384 lines covered)
      • org.jacoco.agent.rt.internal_b6258fc.asm.org.jacoco.agent.rt.internal_b6258fc.asm.ClassReader – 0.00% (0/1519 lines covered)
      • kotlin.collections.kotlin.collections.CollectionsKt___CollectionsKt – 0.00% (0/1148 lines covered)
      • org.jacoco.agent.rt.internal_b6258fc.asm.org.jacoco.agent.rt.internal_b6258fc.asm.MethodWriter – 0.00% (0/923 lines covered)
      • kotlin.sequences.kotlin.sequences.SequencesKt___SequencesKt – 0.00% (0/730 lines covered)
      • com.google.common.cache.com.google.common.cache.LocalCache$Segment – 0.00% (0/726 lines covered)
      • kotlin.text.kotlin.text.StringsKt___StringsKt – 0.00% (0/623 lines covered)
      • org.jacoco.agent.rt.internal_b6258fc.asm.org.jacoco.agent.rt.internal_b6258fc.asm.Frame – 0.00% (0/564 lines covered)
      • kotlin.collections.kotlin.collections.ArraysKt___ArraysJvmKt – 0.00% (0/495 lines covered)

✅ Native Android screenshot tests passed.

Native Android coverage

  • 📊 Line coverage: 9.18% (9152/99743 lines covered) [HTML preview] (artifact android-coverage-report, jacocoAndroidReport/html/index.html)
    • Other counters: instruction 8.07% (44885/556236), branch 3.73% (1888/50588), complexity 4.02% (2161/53777), method 6.26% (1754/28022), class 10.21% (406/3978)
    • Lowest covered classes
      • kotlin.collections.kotlin.collections.ArraysKt___ArraysKt – 0.00% (0/6327 lines covered)
      • kotlin.collections.unsigned.kotlin.collections.unsigned.UArraysKt___UArraysKt – 0.00% (0/2384 lines covered)
      • org.jacoco.agent.rt.internal_b6258fc.asm.org.jacoco.agent.rt.internal_b6258fc.asm.ClassReader – 0.00% (0/1519 lines covered)
      • kotlin.collections.kotlin.collections.CollectionsKt___CollectionsKt – 0.00% (0/1148 lines covered)
      • org.jacoco.agent.rt.internal_b6258fc.asm.org.jacoco.agent.rt.internal_b6258fc.asm.MethodWriter – 0.00% (0/923 lines covered)
      • kotlin.sequences.kotlin.sequences.SequencesKt___SequencesKt – 0.00% (0/730 lines covered)
      • com.google.common.cache.com.google.common.cache.LocalCache$Segment – 0.00% (0/726 lines covered)
      • kotlin.text.kotlin.text.StringsKt___StringsKt – 0.00% (0/623 lines covered)
      • org.jacoco.agent.rt.internal_b6258fc.asm.org.jacoco.agent.rt.internal_b6258fc.asm.Frame – 0.00% (0/564 lines covered)
      • kotlin.collections.kotlin.collections.ArraysKt___ArraysJvmKt – 0.00% (0/495 lines covered)

Benchmark Results

Detailed Performance Metrics

Metric Duration
SIMD kernel backend scalar fallback (no native SIMD)
SIMD int-add (64K x300) java 340ms / native 132ms = 2.5x speedup
SIMD float-mul (64K x300) java 235ms / native 134ms = 1.7x speedup
SIMD kernel correctness PASS (native result == scalar reference)
Base64 payload size 8192 bytes
Base64 benchmark iterations 6000
Base64 SIMD byte path gated to scalar (CPU autovectorizes scalar; explicit SIMD not beneficial here)
Base64 CN1 encode 375.000 ms
Base64 CN1 decode 440.000 ms
Base64 native encode 1039.000 ms
Base64 encode ratio (CN1/native) 0.361x (63.9% faster)
Base64 native decode 915.000 ms
Base64 decode ratio (CN1/native) 0.481x (51.9% faster)
Image encode benchmark status skipped (SIMD unsupported)

@shai-almog

shai-almog commented Jun 29, 2026

Copy link
Copy Markdown
Collaborator Author

Compared 135 screenshots: 135 matched.
Native Windows port, REAL shipping pipeline: the hellocodenameone screenshot suite rendered by a binary CROSS-COMPILED on Linux (clang-cl + xwin, WebView2 linked) and RUN on a Windows x64 runner. Compared against the in-repo baseline in scripts/windows/screenshots.

Benchmark Results

Detailed Performance Metrics

Metric Duration
SIMD kernel backend SSE2 (x64) / NEON (arm64) native kernels
SIMD int-add (64K x300) java 65ms / native 3ms = 21.6x speedup
SIMD float-mul (64K x300) java 66ms / native 2ms = 33.0x speedup
SIMD kernel correctness PASS (native result == scalar reference)

@shai-almog

shai-almog commented Jun 29, 2026

Copy link
Copy Markdown
Collaborator Author

Compared 131 screenshots: 131 matched.
✅ JavaScript-port screenshot tests passed.

@shai-almog

shai-almog commented Jun 29, 2026

Copy link
Copy Markdown
Collaborator Author

Compared 137 screenshots: 137 matched.
Native Linux port (x64), GTK3/Cairo/Pango, ParparVM bytecode-to-C (no JVM): the hellocodenameone screenshot suite rendered by a native ELF built + run on the GitHub x64 runner. Baseline: scripts/linux/screenshots.

@shai-almog

shai-almog commented Jun 29, 2026

Copy link
Copy Markdown
Collaborator Author

Compared 137 screenshots: 137 matched.
Native Linux port (arm64), GTK3/Cairo/Pango, ParparVM bytecode-to-C (no JVM): the hellocodenameone screenshot suite rendered by a native ELF built + run on the GitHub arm64 runner. Baseline: scripts/linux/screenshots-arm.

@shai-almog

shai-almog commented Jun 29, 2026

Copy link
Copy Markdown
Collaborator Author

Compared 137 screenshots: 137 matched.
✅ Native Mac screenshot tests passed.

Benchmark Results

  • VM Translation Time: 0 seconds
  • Compilation Time: 183 seconds

Detailed Performance Metrics

Metric Duration
SIMD kernel backend SSE2 (x64) / NEON (arm64) native kernels
SIMD int-add (64K x300) java 100ms / native 5ms = 20.0x speedup
SIMD float-mul (64K x300) java 102ms / native 7ms = 14.5x speedup
SIMD kernel correctness PASS (native result == scalar reference)
Base64 payload size 8192 bytes
Base64 benchmark iterations 6000
Base64 SIMD byte path active (NEON-accelerated)
Base64 CN1 encode 438.000 ms
Base64 CN1 decode 329.000 ms
Base64 native encode 2200.000 ms
Base64 encode ratio (CN1/native) 0.199x (80.1% faster)
Base64 native decode 1224.000 ms
Base64 decode ratio (CN1/native) 0.269x (73.1% faster)
Base64 SIMD encode 103.000 ms
Base64 encode ratio (SIMD/CN1) 0.235x (76.5% faster)
Base64 SIMD decode 98.000 ms
Base64 decode ratio (SIMD/CN1) 0.298x (70.2% faster)
Base64 encode ratio (SIMD/native) 0.047x (95.3% faster)
Base64 decode ratio (SIMD/native) 0.080x (92.0% faster)
Image encode benchmark iterations 100
Image createMask (SIMD off) 70.000 ms
Image createMask (SIMD on) 57.000 ms
Image createMask ratio (SIMD on/off) 0.814x (18.6% faster)
Image applyMask (SIMD off) 710.000 ms
Image applyMask (SIMD on) 10739.000 ms
Image applyMask ratio (SIMD on/off) 15.125x (1412.5% slower)
Image modifyAlpha (SIMD off) 315.000 ms
Image modifyAlpha (SIMD on) 429.000 ms
Image modifyAlpha ratio (SIMD on/off) 1.362x (36.2% slower)
Image modifyAlpha removeColor (SIMD off) 554.000 ms
Image modifyAlpha removeColor (SIMD on) 712.000 ms
Image modifyAlpha removeColor ratio (SIMD on/off) 1.285x (28.5% slower)

@github-actions

github-actions Bot commented Jun 29, 2026

Copy link
Copy Markdown
Contributor

✅ Continuous Quality Report

Test & Coverage

Static Analysis

  • SpotBugs [Report archive]
    • ByteCodeTranslator: 0 findings (no issues)
    • android: 0 findings (no issues)
    • codenameone-maven-plugin: 0 findings (no issues)
    • core-unittests: 0 findings (no issues)
    • ios: 0 findings (no issues)
  • PMD: 0 findings (no issues) [Report archive]
  • Checkstyle: 0 findings (no issues) [Report archive]

Generated automatically by the PR CI workflow.

@shai-almog

shai-almog commented Jun 29, 2026

Copy link
Copy Markdown
Collaborator Author

Compared 134 screenshots: 134 matched.
✅ Native iOS screenshot tests passed.

Benchmark Results

  • VM Translation Time: 0 seconds
  • Compilation Time: 302 seconds

Build and Run Timing

Metric Duration
Simulator Boot 90000 ms
Simulator Boot (Run) 0 ms
App Install 13000 ms
App Launch 1000 ms
Test Execution 400000 ms

Detailed Performance Metrics

Metric Duration
SIMD kernel backend SSE2 (x64) / NEON (arm64) native kernels
SIMD int-add (64K x300) java 101ms / native 3ms = 33.6x speedup
SIMD float-mul (64K x300) java 83ms / native 4ms = 20.7x speedup
SIMD kernel correctness PASS (native result == scalar reference)
Base64 payload size 8192 bytes
Base64 benchmark iterations 6000
Base64 SIMD byte path active (NEON-accelerated)
Base64 CN1 encode 363.000 ms
Base64 CN1 decode 271.000 ms
Base64 native encode 687.000 ms
Base64 encode ratio (CN1/native) 0.528x (47.2% faster)
Base64 native decode 293.000 ms
Base64 decode ratio (CN1/native) 0.925x (7.5% faster)
Base64 SIMD encode 57.000 ms
Base64 encode ratio (SIMD/CN1) 0.157x (84.3% faster)
Base64 SIMD decode 50.000 ms
Base64 decode ratio (SIMD/CN1) 0.185x (81.5% faster)
Base64 encode ratio (SIMD/native) 0.083x (91.7% faster)
Base64 decode ratio (SIMD/native) 0.171x (82.9% faster)
Image encode benchmark iterations 100
Image createMask (SIMD off) 17.000 ms
Image createMask (SIMD on) 2.000 ms
Image createMask ratio (SIMD on/off) 0.118x (88.2% faster)
Image applyMask (SIMD off) 52.000 ms
Image applyMask (SIMD on) 38.000 ms
Image applyMask ratio (SIMD on/off) 0.731x (26.9% faster)
Image modifyAlpha (SIMD off) 50.000 ms
Image modifyAlpha (SIMD on) 35.000 ms
Image modifyAlpha ratio (SIMD on/off) 0.700x (30.0% faster)
Image modifyAlpha removeColor (SIMD off) 64.000 ms
Image modifyAlpha removeColor (SIMD on) 29.000 ms
Image modifyAlpha removeColor ratio (SIMD on/off) 0.453x (54.7% faster)

@shai-almog

shai-almog commented Jun 29, 2026

Copy link
Copy Markdown
Collaborator Author

Compared 138 screenshots: 138 matched.
✅ Native iOS Metal screenshot tests passed.

Benchmark Results

  • VM Translation Time: 0 seconds
  • Compilation Time: 396 seconds

Build and Run Timing

Metric Duration
Simulator Boot 96000 ms
Simulator Boot (Run) 1000 ms
App Install 17000 ms
App Launch 3000 ms
Test Execution 380000 ms

Detailed Performance Metrics

Metric Duration
SIMD kernel backend SSE2 (x64) / NEON (arm64) native kernels
SIMD int-add (64K x300) java 88ms / native 5ms = 17.6x speedup
SIMD float-mul (64K x300) java 67ms / native 5ms = 13.4x speedup
SIMD kernel correctness PASS (native result == scalar reference)
Base64 payload size 8192 bytes
Base64 benchmark iterations 6000
Base64 SIMD byte path active (NEON-accelerated)
Base64 CN1 encode 1038.000 ms
Base64 CN1 decode 289.000 ms
Base64 native encode 574.000 ms
Base64 encode ratio (CN1/native) 1.808x (80.8% slower)
Base64 native decode 644.000 ms
Base64 decode ratio (CN1/native) 0.449x (55.1% faster)
Base64 SIMD encode 73.000 ms
Base64 encode ratio (SIMD/CN1) 0.070x (93.0% faster)
Base64 SIMD decode 84.000 ms
Base64 decode ratio (SIMD/CN1) 0.291x (70.9% faster)
Base64 encode ratio (SIMD/native) 0.127x (87.3% faster)
Base64 decode ratio (SIMD/native) 0.130x (87.0% faster)
Image encode benchmark iterations 100
Image createMask (SIMD off) 28.000 ms
Image createMask (SIMD on) 3.000 ms
Image createMask ratio (SIMD on/off) 0.107x (89.3% faster)
Image applyMask (SIMD off) 83.000 ms
Image applyMask (SIMD on) 59.000 ms
Image applyMask ratio (SIMD on/off) 0.711x (28.9% faster)
Image modifyAlpha (SIMD off) 138.000 ms
Image modifyAlpha (SIMD on) 217.000 ms
Image modifyAlpha ratio (SIMD on/off) 1.572x (57.2% slower)
Image modifyAlpha removeColor (SIMD off) 327.000 ms
Image modifyAlpha removeColor (SIMD on) 136.000 ms
Image modifyAlpha removeColor ratio (SIMD on/off) 0.416x (58.4% faster)

@shai-almog

shai-almog commented Jun 29, 2026

Copy link
Copy Markdown
Collaborator Author

Compared 136 screenshots: 136 matched.
✅ Native Apple TV (tvOS, Metal) screenshot tests passed.

@shai-almog shai-almog force-pushed the feature/device-input-and-form-factors branch from f60c478 to 0c52958 Compare June 29, 2026 19:03
@github-actions

github-actions Bot commented Jun 29, 2026

Copy link
Copy Markdown
Contributor

✅ ByteCodeTranslator Quality Report

Test & Coverage

  • Tests: 390 total, 0 failed, 14 skipped

Benchmark Results

  • Execution Time: 13775 ms

  • Hotspots (Top 20 sampled methods):

    • 29.98% java.util.ArrayList.indexOf (363 samples)
    • 6.61% com.codename1.tools.translator.BytecodeMethod.addToConstantPool (80 samples)
    • 4.95% com.codename1.tools.translator.BytecodeMethod.equals (60 samples)
    • 3.06% java.lang.StringBuilder.append (37 samples)
    • 2.15% org.objectweb.asm.tree.analysis.Analyzer.analyze (26 samples)
    • 1.82% com.codename1.tools.translator.Parser.generateClassAndMethodIndexHeader (22 samples)
    • 1.73% org.objectweb.asm.tree.analysis.Analyzer.findSubroutine (21 samples)
    • 1.65% java.lang.System.identityHashCode (20 samples)
    • 1.65% com.codename1.tools.translator.Parser.classIndex (20 samples)
    • 1.65% com.codename1.tools.translator.BytecodeMethod.optimize (20 samples)
    • 1.32% java.util.TreeMap.getEntry (16 samples)
    • 1.24% sun.nio.ch.FileDispatcherImpl.write0 (15 samples)
    • 1.24% org.objectweb.asm.ClassReader.readCode (15 samples)
    • 1.16% java.lang.String.equals (14 samples)
    • 1.16% com.codename1.tools.translator.BytecodeMethod.appendCMethodPrefix (14 samples)
    • 1.16% java.util.HashMap.hash (14 samples)
    • 0.99% java.lang.StringCoding.encode (12 samples)
    • 0.91% java.lang.Object.hashCode (11 samples)
    • 0.83% com.codename1.tools.translator.NativeSymbolIndex.<init> (10 samples)
    • 0.83% com.codename1.tools.translator.ByteCodeClass.markDependencies (10 samples)
  • ⚠️ Coverage report not generated.

Static Analysis

  • ✅ SpotBugs: no findings (report was not generated by the build).
  • ⚠️ PMD report not generated.
  • ⚠️ Checkstyle report not generated.

Generated automatically by the PR CI workflow.

@shai-almog

shai-almog commented Jun 29, 2026

Copy link
Copy Markdown
Collaborator Author

Compared 135 screenshots: 135 matched.
Native Windows port (x64 / Intel-AMD): full hellocodenameone screenshot suite rendered offscreen with Direct2D/DirectWrite, plus the real benchmarks (base64 native/CN1/SIMD, image createMask/applyMask/modifyAlpha/PNG/JPEG, SSE2 SIMD kernels). Compared against the in-repo baseline in scripts/windows/screenshots.

Benchmark Results

Detailed Performance Metrics

Metric Duration
SIMD kernel backend SSE2 (x64) / NEON (arm64) native kernels
SIMD int-add (64K x300) java 71ms / native 2ms = 35.5x speedup
SIMD float-mul (64K x300) java 56ms / native 2ms = 28.0x speedup
SIMD kernel correctness PASS (native result == scalar reference)

@shai-almog

shai-almog commented Jun 29, 2026

Copy link
Copy Markdown
Collaborator Author

Compared 135 screenshots: 135 matched.
Native Windows port (arm64 / Apple Silicon - Arm): full hellocodenameone screenshot suite rendered offscreen with Direct2D/DirectWrite, plus the real benchmarks (base64 native/CN1/SIMD, image createMask/applyMask/modifyAlpha/PNG/JPEG, NEON SIMD kernels). Compared against the in-repo baseline in scripts/windows/screenshots.

Benchmark Results

Detailed Performance Metrics

Metric Duration
SIMD kernel backend SSE2 (x64) / NEON (arm64) native kernels
SIMD int-add (64K x300) java 62ms / native 3ms = 20.6x speedup
SIMD float-mul (64K x300) java 61ms / native 4ms = 15.2x speedup
SIMD kernel correctness PASS (native result == scalar reference)

@shai-almog

shai-almog commented Jun 29, 2026

Copy link
Copy Markdown
Collaborator Author

Compared 214 screenshots: 214 matched.
✅ Native Apple Watch (watchOS, Core Graphics) screenshot tests passed.

shai-almog and others added 7 commits June 30, 2026 03:54
… wheel, stylus, foldables)

Adds cross-platform APIs for device-specific input and form factors that were
previously missing, all additive and backward compatible with safe defaults:

- PointerEvent: rich pointer snapshot (button, pointer type, pressure, tilt,
  contact size, modifiers, hover) via ActionEvent.getPointerEvent() and polling
  accessors on CN/Display.
- Multi-button mice: button constants/mask plus Component.addContextMenuListener
  (right click and long press). Wired in JavaSE/Android/iOS.
- Mouse wheel: WheelEvent and Component.addMouseWheelListener; horizontal and
  precise/trackpad deltas. iOS trackpad/Magic Mouse/wheel routed through the same
  pipeline so WheelEvent is one universal scroll-gesture API.
- Stylus/pen: pressure, tilt and eraser via Component.addStylusListener; Android
  getToolType/getPressure/AXIS_TILT and iOS Apple Pencil force/altitude/azimuth.
- Foldables: DevicePosture (posture, hinge orientation, fold bounds) and
  Display.addPostureListener. Android reads androidx.window through reflection,
  added only when android.foldableSupport=true. The JavaSE simulator can drive a
  simulated posture.
- Desktop windowing / external displays: isDesktopMode, getDisplayCount,
  isExternalDisplayConnected.

Pointer metadata follows the existing isShiftKeyDown() precedent (current state on
the implementation plus a dispatch-time snapshot) rather than threading through
the EDT event queue. Device-input listeners are dispatched from the Form so they
work uniformly even for components that override the pointer methods.

Docs: docs/developer-guide/Device-Input-And-Form-Factors.asciidoc.
Tests: PointerEventTest, WheelEventTest, PointerMetadataTest, DevicePostureTest,
DeviceInputListenersTest in maven/core-unittests (full suite green, 3676 tests).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ess, LanguageTool terms)

Fix the 10 Vale alerts (contractions, wordiness, quote punctuation) in the new
Device-Input-And-Form-Factors chapter and accept-list the technical terms
foldable(s), bitmask and DeX for LanguageTool. Vale now reports 0 alerts locally.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Use eager final initialization for the DevicePosture singleton instead of
unsynchronized lazy init. SpotBugs runs only on the JDK 8 build-test job, so
this surfaced only there. Verified locally: spotbugs BugInstance size is 0.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…iedName)

Add @OverRide to PointerEvent.toString() and the postureChanged Runnable; import
PointerEvent in Display and Form and use the short name; use the already-imported
ActionListener short name in CN. The PMD check runs as part of the JDK 8
build-test job. Verified locally: generate-quality-report.py reports no forbidden
PMD violations and the device-input unit tests pass.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…cOS trackpad gestures, watch/tv input

- Simulator: add a Simulate -> Foldable menu (enable, posture, fold orientation, hinge angle)
  so foldable posture is exercised from the UI, not an internal API. Reworked the developer
  guide to point at the menu and drop implementation details.
- Core: add a rotation (twist) gesture callback Component.rotation(float) parallel to pinch, plus
  Display.fireMagnifyGesture / fireRotationGesture dispatch for native gesture recognizers.
- JavaScriptPort: capture mouse button + pointer type metadata; route the wheel through
  WheelEvent so the browser uses the same universal scroll-gesture API.
- Win32 + Linux ports: report pointer type MOUSE on pointer events (the native event protocol
  does not yet carry mouse buttons; that needs a native protocol extension).
- macOS / Mac Catalyst: add UIPinchGestureRecognizer (magnify) and UIRotationGestureRecognizer
  (rotate) trackpad gestures, scoped to Catalyst so they do not double-apply the existing iOS
  multi-touch pinch. Verified the pointer-metadata / scroll path is correct for Catalyst.
- Apple Watch: route the Digital Crown through the universal wheel pipeline (WheelEvent + scroll)
  instead of a synthetic press/drag/release.
- Apple TV: map the Siri Remote (arrows, select, menu, play/pause) through the key system.

Tests: add a gesture-dispatch test; full device-input suite green (25 tests). iOS port + app +
arm64 Xcode link verified. The android.foldableSupport AndroidGradleBuilder change is mirrored to
the cloud build daemon (codenameone/BuildDaemon#144).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The cn1-local-workspace profile (active when the website CI builds the JavaScript
initializr with -Dcn1.localWorkspace=true) was pinned to the released 7.0.255 core
despite its comment saying it builds against repo HEAD, so the repo's JavaScript port
source was compiled against the released core. That broke the moment the JS port used
a new core API (PointerEvent). Align it with the repo snapshot version and with the
cn1playground / skindesigner local-workspace profiles, which already use 8.0-SNAPSHOT.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…e code

The new pointer/gesture native code referenced UIKit types that do not exist
on every Apple platform, breaking the tvOS and watchOS targets:

- UIPinchGestureRecognizer / UIRotationGestureRecognizer are unavailable on
  tvOS. The cn1HandlePinch:/cn1HandleRotation: method signatures exposed those
  types unconditionally (only the bodies sat behind #if TARGET_OS_MACCATALYST),
  so the tvOS target failed to compile. Wrap the whole handler methods in the
  Mac Catalyst guard; their only callers are already Catalyst-only.
- UITouch is unavailable on watchOS. The cn1CapturePointerMetadata declaration
  and definition (UITouch* parameter) were at file scope, breaking the watchOS
  target. Guard both with #if !TARGET_OS_WATCH; every caller is already inside
  a !TARGET_OS_WATCH region.

Verified locally: HelloCodenameOneTV (appletvsimulator), HelloCodenameOneWatch
(watchsimulator) and HelloCodenameOne (iphonesimulator) all BUILD SUCCEEDED.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@shai-almog shai-almog force-pushed the feature/device-input-and-form-factors branch from c36bbb8 to 75a323a Compare June 30, 2026 00:54
shai-almog and others added 2 commits June 30, 2026 10:53
… richer JS button detail

Earlier the Windows and Linux ports only forwarded the left mouse button and
hard-coded every pointer event to BUTTON_PRIMARY / TYPE_MOUSE, and isTouchDevice()
returned a constant false. This wires the device-input APIs through to the real
native input on both desktop ports.

Protocol: the pointer event's otherwise-unused key field now carries a button
bitmask (mirrors PointerEvent.MASK_*) plus high-bit touch/pen flags, decoded by
the Java drain into setPointerEventMetadata. No event-struct change.

Windows (cn1_windows_window.cpp):
- Handle WM_RBUTTONDOWN/UP, WM_MBUTTONDOWN/UP, WM_XBUTTONDOWN/UP (right, middle,
  back, forward); previously only the left button existed.
- WM_MOUSEMOVE drags carry the held-button mask from the MK_* flags.
- Mouse capture is held while any button is down, released on the last up.
- Touch / pen promoted to mouse messages are tagged via GetMessageExtraInfo so
  the event reports TYPE_TOUCH / TYPE_STYLUS.
- isTouchDevice() via GetSystemMetrics(SM_DIGITIZER), guarded for older SDKs.

Linux (cn1_linux_window.c):
- Forward GdkEventButton.button (was dropped); drag works for any button via the
  GdkEvent state mask (was left-button only).
- Real GDK_TOUCH_* handler drives the pointer with TYPE_TOUCH; touchscreen-sourced
  button/motion events are dropped to avoid double dispatch.
- isTouchDevice() enumerates the default seat for a GDK_SOURCE_TOUCHSCREEN device.

JavaScript (HTML5Implementation.java):
- applyMouseMetadata handles DOM buttons 3/4 (back/forward), uses the DOM buttons
  bitmask for the held-button mask during a drag, and forwards keyboard modifiers.
- Replace the deprecated new Character()/new Integer() char/string width cache
  boxing with autoboxing.

Docs updated for desktop/browser button support and touch-laptop TYPE_TOUCH/STYLUS.

Verified: maven/windows and maven/linux Java compile against freshly built core.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Routes desktop trackpad / touch gesture recognizers to the same
Display.fireMagnifyGesture / fireRotationGesture hooks the macOS trackpad and the
mobile two-finger pinch already drive, so a Component pinch(float) / rotation(float)
override now fires on Windows and Linux too.

Protocol: two new event types (CN1_EVENT_PINCH / CN1_EVENT_ROTATE) carry the
incremental scale multiplier / radians as a fixed-point int (1/10000 units) in the
key field; the Java drain divides and dispatches.

Windows (cn1_windows_window.cpp): handle WM_GESTURE GID_ZOOM and GID_ROTATE via
GetGestureInfo, forwarding the incremental scale (from the finger distance) and
incremental radians (from GID_ROTATE_ANGLE_FROM_ARGUMENT). Guarded with
#ifdef WM_GESTURE so the port still builds against an older SDK target. (A Windows
precision touchpad usually reports a pinch as control plus wheel instead, which
already flows through the universal WheelEvent API.)

Linux (cn1_linux_window.c): handle GDK_TOUCHPAD_PINCH (libinput touchpad gestures)
through the generic event signal with GDK_TOUCHPAD_GESTURE_MASK. scale is
cumulative from the gesture begin so the incremental multiplier is forwarded;
angle_delta is already a per-event delta in degrees, forwarded as incremental
radians. This gives full touchpad pinch and rotate on Linux.

Docs updated for the desktop trackpad gesture coverage. Verified: maven/windows and
maven/linux Java compile against freshly built core.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@liannacasper liannacasper merged commit 83aac7b into master Jun 30, 2026
69 of 70 checks passed
@liannacasper liannacasper deleted the feature/device-input-and-form-factors branch June 30, 2026 11:30
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.

2 participants