Adds the foundation for building Apple Watch / Wear OS apps and proves the
model end-to-end in the hellocodenameone screenshot suite.
Form-factor API (core + ports):
- Display.isWatch()/getFormFactor() + CN facades + FORM_FACTOR_* constants,
following the isTablet()/isDesktop() pattern. Defaults false in
CodenameOneImplementation; overridden in iOS (native isRunningOnWatch),
Android (FEATURE_WATCH), and JavaSE (skin watch=true). New "watch" resource
override layer in each port's getPlatformOverrides().
watchOS rendering port (iOS native sources, all additive under
#if TARGET_OS_WATCH so the iOS slice is byte-for-byte unchanged):
- CN1CGGraphics: Core Graphics rasterizer backend (no GL/Metal on watchOS).
- CN1WatchRenderingView: CGBitmapContext surface conforming to CN1RenderingView.
- CN1WatchHost: timer-driven frame pump + crown/tap input bridge.
- FillRect/DrawRect/ClearRect/DrawLine wired to the CG backend (rollout in
WATCHOS_PORT.md). Validated on the watchOS simulator (Xcode 26.3).
Build pipeline (separate watch entry point + seamless double app):
- codename1.watchMain in codenameone_settings.properties declares a distinct
watch lifecycle (Apple Watch + Wear); a distinct entry enables more
aggressive tree-shaking. Flows via CN1BuildMojo as the watchMain build arg.
- WatchNativeBuilder (modeled on MacNativeBuilder) auto-enables when watchMain
is set and adds a watchOS app target (arm64_32, WKApplication, companion
embed or standalone) to the iOS Xcode project via the xcodeproj gem.
- watchNative.* build hints registered in BuildHintSchemaDefaults.
- JavaSE ships generated Apple Watch simulator skins (round, safe areas).
hellocodenameone (proves the APIs + model):
- AbstractGraphicsScreenshotTest renders 4 separate full-screen captures on a
watch (via CN.isWatch()) instead of a cramped 2x2 grid; BaseTest gains a
chained-capture helper. Verified in the JavaSE simulator with the Apple
Watch skin (396x484): graphics-{draw,fill}-arc-{direct,image}-aa-{off,on}.
- HelloCodenameOneWatch watchMain lifecycle + codename1.watchMain setting.
- Cn1ssDeviceRunner gains an optional -Dcn1ss.filter subset selector.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
What
Adds the foundation for building Apple Watch (watchOS) and Wear OS apps, and proves the new APIs + entry-point model end-to-end in the
hellocodenameonescreenshot suite.Form-factor API (core + ports)
Display.isWatch()/Display.getFormFactor()+CNfacades +FORM_FACTOR_*constants, mirroring theisTablet()/isDesktop()pattern. DefaultfalseinCodenameOneImplementation; overridden in iOS (nativeisRunningOnWatch), Android (FEATURE_WATCH), and JavaSE (skinwatch=true). New"watch"resource-override layer per port.watchOS rendering port (iOS native sources)
watchOS has no UIKit view hierarchy, no OpenGL ES, and no Metal — so the iOS port's GL/Metal render path can't run. All additive under
#if TARGET_OS_WATCH, leaving the iOS slice byte-for-byte unchanged:CN1CGGraphics— Core Graphics rasterizer backend.CN1WatchRenderingView—CGBitmapContextsurface conforming toCN1RenderingView.CN1WatchHost— timer-driven frame pump + Digital Crown / tap input bridge.FillRect/DrawRect/ClearRect/DrawLinewired to the CG backend; remaining ops + rollout tracked inWATCHOS_PORT.md. Validated on the watchOS 26.2 simulator (Xcode 26.3).Build pipeline — separate
watchMainentry + seamless double appcodename1.watchMainincodenameone_settings.propertiesdeclares a distinct watch lifecycle (used for both Apple Watch and Wear). It may equal the phone main, but a distinct entry point lets the watch slice tree-shake from its own root.WatchNativeBuilder(modeled onMacNativeBuilder) auto-enables whenwatchMainis set and adds a watchOS app target (arm64_32,WKApplication, companion-embed or standalone) to the iOS Xcode project — so the double app is produced as part of the regular iPhone build.watchNative.*build hints registered; JavaSE ships generated Apple Watch simulator skins.Proven in hellocodenameone
AbstractGraphicsScreenshotTestrenders 4 separate full-screen captures on a watch (viaCN.isWatch()) instead of a cramped 2×2 grid. Verified in the JavaSE simulator with the Apple Watch skin (396×484).HelloCodenameOneWatchwatchMainlifecycle +codename1.watchMainsetting.Cn1ssDeviceRunnergains an optional-Dcn1ss.filtersubset selector.Watch screenshots
See the inline comments below —
fill-arcanddraw-arceach rendered as 4 separate watch-shaped screenshots (one per AA/image variant) instead of one 2×2 grid tile.Answering the original questions
.ipa(companion) or ships standalone; Wear OS = a separate APK. One submission can carry phone + watch, but always two binaries.isWatch()+ skins? Yes — shipped, and the form-factor-aware test proves them.codename1.watchMain; the build emits the watch target automatically; per-component UI adapts viaCN.isWatch()/getFormFactor().🤖 Generated with Claude Code