Develop/v9.5#61
Conversation
Add lv_bindings_js.h as a single entry point for lvgl, quickjs, and private.h instead of repeating extern C blocks across native render headers.
There was a problem hiding this comment.
9 issues found and verified against the latest diff
Note: This PR contains a large number of files. cubic only reviews up to 100 files per PR, so some files may not have been reviewed. cubic prioritizes the most important files to review.
On a pro plan you can use ultrareview for larger PRs.
Re-trigger cubic
5825b1c to
cc703ee
Compare
- Expose NativeRender.RenderUtil.captureDisplay(path) when LV_USE_SNAPSHOT is enabled - Capture the active screen with lv_snapshot_take (TRUE_COLOR_ALPHA) and write a 32-bit PNG via lodepng - Convert snapshot pixels with framebuffer32_to_rgba before encoding - Register the QuickJS binding from render bootstrap (NativeScreenshotInit) - Document API, simulator vs device availability, and usage in doc/jsapi/captureDisplay.md - Add screenshot HAL sources and link them from CMakeLists.txt
- Add utils/assets.ts with loadLocalAsset (import.meta.dirname + tjs.readFile) and fetchAssetBinary for remote assets. - Image, GIF, and style/post.ts use shared helpers instead of path/fs/fetch and __dirname, which break in the txiki module runtime. - Pass fetch arrayBuffer results directly; txiki has no Node.js Buffer. - Demo widgets: use module-relative ./assets/ paths.
Enable static typing for the runtime bridge exposed via globalThis[Symbol.for("lvgljs")],
so React render code can reference native widget constructors and methods without casts.
Bridge module (src/render/react/core/bridge.ts):
- LvgljsNativeComponent base with style, dataset, nativeSetStyle, addEventListener, getBoundingClientRect
- Layered subclasses: ChildContainer, Alignable, Scrollable, Widget, BackgroundWidget, List
- Per-widget declare classes (Arc, Button, View, Text, Image, Switch, Checkbox, Textarea, Keyboard, Dropdownlist, ProgressBar, Roller, Slider, Line, Calendar, GIF, TabView, Chart, Mask, Window)
- Registry static ctor map and LvgljsBridge / GetBridge() accessor (230 lines)
Global ambient types (src/render/react/lvgljs.d.ts):
- tjs.readFile() declaration for legacy txiki.js API used by asset loaders
- StylePropValueCSS, StylePropValue, StylePropBatch, StylePropTransition for batch style channel
Public exports (src/render/react/index.ts):
- Re-export all bridge symbols via export * from "./core/bridge"
TypeScript configuration (tsconfig.json):
- target ES2020, module ESNext, moduleResolution Bundler, noEmit true
- include narrowed to src/render/react/**/*.ts for focused typecheck scope
Do not add nativeSetStyle, as it's will be changed when style refactoring, and not used yet.
Complete the bridge migration by replacing inline globalThis symbol lookups
across the React render layer with the centralized GetBridge() helper, so
bridge.ts remains the sole untyped global accessor and callers get typed access.
Component modules (src/render/react/components/*/comp.ts, 22 files):
- Arc, Button, Calendar, Canvas, Chart, Checkbox, Dropdownlist, GIF, Image,
Input, Keyboard, Line, Mask, ProgressBar, Roller, Slider, Switch, Tabs,
Text, Textarea, View, Window
- Each imports GetBridge from ../../core/bridge instead of
globalThis[Symbol.for('lvgljs')]
Core modules (src/render/react/core/):
- animate/index.js - NativeRender.Animate via GetBridge()
- dimensions/index.js - NativeRender.dimensions via GetBridge()
- theme/index.js - NativeRender.theme via GetBridge()
- Each imports GetBridge from ../bridge
Problem:
- createInstance in component configs calls instance.setProps(newProps, {})
- TypeScript reported TS2345: {} is not assignable to Props when Props
includes required fields (title, src, items, placeholder, etc.)
Solution:
- Use Partial<Props> for oldProps in prop setter helpers and setProps()
- Reflects mount semantics: no prior props on first setProps call
- commitUpdate still passes full oldProps from the reconciler (assignable to Partial)
Files changed:
- Calendar/config.ts — commitUpdate and setProps oldProps: Partial<CalendarProps>
- Dropdownlist/comp.ts — setListProps, setProps
- GIF/comp.ts — setGIFProps, setProps
- Image/comp.ts — setImageProps, setProps
- Input/comp.ts — setInputProps, setProps
- Keyboard/comp.ts — setKeyboardProps, setProps
- Line/comp.ts — setLineProps (typed), setProps
- ProgressBar/comp.ts — setProgressBarProps, setProps
- Roller/comp.ts — setRollerProps, setProps
- Slider/comp.ts — setSliderProps, setProps
- Tabs/comp.ts — setTabsProps, setProps
- Text/comp.ts — setTextProps, setProps
- Textarea/comp.ts — setTextareaProps, setProps
- Window/comp.ts — setWindowProps, setProps
Leaf widgets do not accept React children, so delegating appendChild, removeChild, and related reconciler hooks to super or parent helpers can run unintended native tree logic. Align these components with the existing no-op pattern used by Text, Image, ProgressBar, and other leaf comps. Child-management no-ops (appendChild, removeChild): - src/render/react/components/Arc/comp.ts - src/render/react/components/Calendar/comp.ts - src/render/react/components/Chart/comp.ts - src/render/react/components/Line/comp.ts - src/render/react/components/Slider/comp.ts Child-management no-ops (insertBefore, appendInitialChild, appendChild, removeChild): - src/render/react/components/Checkbox/comp.ts - src/render/react/components/Switch/comp.ts Layer and scroll no-ops (moveToFront, moveToBackground, scrollIntoView): - src/render/react/components/Mask/comp.ts
Proxy get handlers pass string | symbol to includes; widen the array type so style proxies compile without TS2345.
- ProgressBar/comp.ts: compare range updates against oldProps.range instead of nonexistent oldProps.arr - Roller/comp.ts: import OnChangeEvent from common/index for onChange prop typing - Switch/comp.ts: compare checked state against oldProps.checked instead of oldProps.value - core/style/index.ts: return true from Proxy set trap to satisfy ProxyHandler<boolean> - core/style/pipe/grid.ts: coerce fr-unit regex capture to Number before isNaN checks - core/style/pipe/text.ts: parse font-size strings to number before arithmetic and clamping - core/style/pipe/trans.ts: use separate matches variable for transform regex; split translate parts without reassigning val
test\image\2 used: 'background-color': 'gray' Signed-off-by: Yonggang Luo <luoyonggang@gmail.com>
c44a584 to
af027f2
Compare
…ooling - Add .github/workflows/build.yml: gen:all:check in linux-device job (no SDL), Linux simulator under xvfb, macOS, and merged screenshot artifacts - Add scripts/run-tests.js, gui-test-runner.js, and cli-test-runner.js for GUI/CLI test discovery, xfail handling, and optional PNG capture in CI - Add shared normalize_* Python scripts for ASCII-safe commit messages and repo text on Windows (normalize_common, normalize_commit_msg, normalize_markdown) - Replace package-lock.json with yarn.lock; add codegen.py, gen:all/check, and typecheck scripts; parallelize build.js esbuild jobs - Extend .gitignore for screenshot output and build artifacts - Extend test/runtime/fetch/1 with fetchBinaryWithArrayBuffer (xfail); use httpbun.com for more stable fetch tests - Generate a side-by-side HTML report at _screenshots/html/index.html after each diff run, with baseline, actual, and diff thumbnails - Add scripts/lib/screenshot-diff-html.js and _screenshots/html path - Support --html, --no-html, and SCREENSHOT_DIFF_HTML to control output - Write diff PNGs for equal images too (black overlay when pixels match)
Several JS-callable component methods guarded with a smaller argc than the highest argv[] index they read. Since these functions are registered with declared length 0, QuickJS does not pad argv, so passing too few arguments caused out-of-bounds reads of the argument array. Align each argc check with the highest argv index accessed.
Signed-off-by: Yonggang Luo <luoyonggang@gmail.com>
…_template.h from lvgl directory root
Set TEST_CAPTURE during --capture and freeze animation, random data, and interval-driven updates so PNG comparison is consistent on Linux, macOS, and device builds.
Add CLI runtime tests that gate comp_map size after Mask/Calendar toggles and native View create/close/GC paths, per Component Memory Leak Fix Plan. Tests - test/runtime/calendar-leak/ (widgets-style Mask + Calendar x1000) - test/runtime/binding-leak/ (native View close, GC, parent/child, events) - test/runtime/lib/probe.ts (getCompMapSize, runGc, assert helpers) Build and probe API - src/render/native/core/refresh/refresh.cpp: RenderUtil.getCompMapSize() - src/render/react/index.ts: updateTestTree() for reconciler leak probes The test is for lvgl#19
handleEvent unregisters native listeners when event props are cleared, but only addEventListener was bound on component prototypes. Wire removeEventListener so prop updates tear down LVGL callbacks correctly. Native bridge: - component.hpp: add WRAPPED_JS_RemoveEventListener macro - *_wrap.cpp: register removeEventListener on all 21 component protos - comp.cpp: detach LVGL callback only when registeEvents becomes empty
Null comp after delete so a second close() or finalizer path does not double-free the same BasicComponent. Native - component.hpp: WRAPPED_JS_CLOSE_COMPONENT guards s->comp
React unmount leaked comp_map entries and JS shells; instanceMap used bracket syntax on a Map. Reconciler now tracks host children, closes children before parents, and calls close() on detach. Reconciler (src/render/react/core/reconciler/index.js) - instanceMap: .set() / .get() / .delete(); detachInstance with _detached guard - _hostChildren tracking; recursive child detach before parent close - removeChild, removeChildFromContainer, detachDeletedInstance call detachInstance - Teardown order owned by JS (children close before parent); comments document contract Native (src/render/native/core/basic/comp.cpp) - removeChild: bookkeeping only (parent_instance); no reparent to window root - destructor: style reset, lv_obj_remove_event_cb, lv_obj_del on close() path
Child unmount is owned by reconciler detachInstance (untrackHostChildren, unRegistEvent, close). Native and per-component removeChild were dead or bookkeeping-only; strip them so teardown has a single path. Native - src/render/native/core/basic/comp.cpp, comp.hpp: drop BasicComponent::removeChild - src/render/native/components/component.hpp: remove WRAPPED_REMOVE_CHILD macro - src/render/native/components/*_wrap.cpp: drop removeChild proto (button, list, mask, switch, tabview, view, window) React - src/render/react/core/reconciler/index.js: removeChild calls detachInstance only - src/render/react/core/bridge.ts: document reconciler-owned child removal - src/render/react/components/config.ts: drop removeChild from LvgljsComponentConfig - src/render/react/components/*/comp.ts, */config.ts: remove no-op removeChild stubs
….5.0 Since LVGL v9, the drivers are integrated in the main LVGL library and the drivers submodule is no longer needed.
Driver integration: Replace the lv_drivers-based SDL integration with LVGL v9 built-in drivers. Find SDL2 before adding the lvgl subdirectory and link it directly to the lvgl target. LVGL config: Move deps/lv_conf.h to a top-level lv_conf.h that routes to deps/lv_conf_sim.h or deps/lv_conf_device.h via IS_SIM / IS_DEVICE. Cleanup: Remove the legacy lv_drv_conf.h and deps/lvgl.h wrapper headers.
Copy deps/lvgl/lv_conf_template.h unchanged as the starting point before re-applying v8 project overrides.
Restore project-specific settings from the v8 backups onto the v9.5.0 template baseline, including IS_SIM/IS_DEVICE guards and per-profile defines.
enable LV_USE_SDL in simulator lv_conf for LVGL 9 Restore the simulator SDL driver flag required by the LVGL 9 SDL HAL (lv_sdl_window_create and related indev helpers). Enable LV_USE_ARABIC_PERSIAN_CHARS that sync with Sim
Replace stored lv_theme_t with theme_saved_t and read defaults via lv_theme_get_color_primary(), lv_theme_get_color_secondary(), and lv_theme_get_font_normal() from the active screen.
…(won't be wrong) Replace direct struct field access with lv_display_*, lv_event_get_*, lv_obj_get_user_data, and lv_screen_active helpers across native bindings.
- Wrap runtime images in lv_image_dsc_t with depth-aware NATIVE_WITH_ALPHA stride and header magic - update the PNG decoder to lv_image_decoder_*, and remove obsolete lv_img_set_size_mode from the GIF widget. - Use dsc.data from the wrapped lv_image_dsc_t and lv_style_set_arc_image_src after the image API rework. fix PNG channel order and Image binary buffer for correct rendering Swap RGB channels in 32-bit PNG decode to match LVGL BGRA layout
…vgl 8.2" This reverts commit 241038b.
Update lv_conf_gen and its manifest so yarn gen:all can parse LVGL 9.5 headers again after the v9 directory and style API reshuffle. Manifest and generator: - Point lv_part_t/lv_state_t at core/lv_obj_style.h instead of lv_obj.h - Move flex/grid/widget/event/gradient/text headers to layouts/* and widgets/* paths; read lv_style props from enum _lv_style_id_t - Drop separate flex/grid extern style-prop sections (built into v9 enum) - Read style setter kinds from misc/lv_style_gen.c only Mapping inputs: - Rename v8 style symbols in cpp_lv_symbol_mapping.json and transition_lvgl_compare.json (IMAGE_*, SHADOW_OFFSET_*, ANIM_DURATION, TRANSFORM_ROTATION/SCALE_X, etc.) - Remove background-dither-mode and animate-speed entries that no longer exist in LVGL 9 Regenerated outputs and tests: - Refresh lv_conf.cpp/ts, lv_types.ts, style_prop.ts, and anim_path.cpp - Resync lv_conf.stub.ts to v9 prop ids and flex-flow bit values - Treat radial gradient as valid in v9; keep unknown-direction coverage via a nonexistent keyword in background.spec.ts
Replace uniform img-scale with img-scaleX/Y backed by lv_image_set_scale_x/y, add scaleX/scaleY style keys for object transforms, and route Image/GIF transforms through img-* props. Regenerate lv_conf/style_prop outputs and update TransStyle tests for the new mapping.
Align coord, percentage, and grid track helpers with the C headers so auto sizing and lv_pct encoding match native LVGL behavior.
Replace removed lv_drivers SDL integration with built-in lv_sdl_* APIs, update image descriptors for v9, and capture screenshots via lv_snapshot with stride-aware framebuffer conversion. Update to the new driver api Re-work the HAL code to the new LVGL driver api. hal.hpp sharing things lv_linux_fbdev_create and lv_evdev_create can return null when hardware is missing; avoid null dereference on startup. Native (src/engine/hal/device/device.cpp) - null checks with stderr log and early return
LVGL 9 requires a flag argument when registering custom style properties; lvjs_style_register_prop now forwards LV_STYLE_PROP_FLAG_NONE so the build succeeds on v9.5.
The fixed 30ms uv_timer beat against LV_DEF_REFR_PERIOD (33ms) and caused uneven frame spacing. Reschedule the one-shot timer from lv_timer_handler(). Engine - src/engine/engine.cpp: schedule_lv_timer() uses handler return delay - src/engine/engine.cpp: fallback to LV_DEF_REFR_PERIOD when no timer ready - src/engine/engine.cpp: replace fixed uv_timer_start(30, 30) with adaptive pump
LVGL 9 removed several chart APIs that the native layer still called, breaking the build and distorting zoomed charts at runtime. Port the Chart component to the v9 widget model while keeping the existing JS surface unchanged. Axis ticks and labels: - Replace lv_chart_set_axis_tick() with standalone lv_scale widgets per axis (left/right/top/bottom). - Replace LV_EVENT_DRAW_PART_BEGIN tick-label callback with lv_scale_set_text_src(), keeping label strings alive in Chart. - Map v8 major/minor tick counts onto lv_scale total_tick_count and major_tick_every. - Sync axis ranges to both lv_chart_set_axis_range() and lv_scale_set_range(). Series data: - Stop accessing opaque lv_chart_series_t internals; write through lv_chart_get_series_y_array() / _x_array() and call lv_chart_refresh(). - Fix setRightAxisData to bind series to SECONDARY_Y (was PRIMARY_Y). - Implement setTopAxisData / setBottomAxisData and re-enable their JS bindings in chart_wrap.cpp. Zoom (scaleX / scaleY styles): - lv_chart_set_zoom_x/y() no longer exists; emulate v8 content zoom with a scrollable viewport wrapper sized to the styled dimensions while the inner chart is enlarged by the 256-based factor. - Scales along the zoomed axis scroll with the chart content; scales on the other axis stay fixed at the viewport edge. - Add BasicComponent::alignInstance() so align/align_to target the viewport wrapper instead of the oversized inner chart. Verified: full test harness passes (56/56), chart screenshot tests pass.
Restore setTopAxisData and setBottomAxisData for LVGL 9.5 charts so PRIMARY_X and SECONDARY_X series follow the same axis_data pattern as left and right axes. Native bridge: - chart.cpp: implement setTopAxisData and setBottomAxisData with series rebuild, per-series colors, fillSeriesY, and lv_chart_refresh - chart_wrap.cpp: add ParseAxisDataArg helper and expose setTopAxisData/setBottomAxisData on the JS prototype
|
Confirmed that this PR works well. I want to contribute some patches. |
Yeap, I fixed most issue, Maybe there is little chart diverge, others should be most fixed( including memory leak) |
|
@lygstate IMO this PR looks good. Is there any plan to be merged into the master branch? Master branch needs(?) the latest LVGL 9.5 version. |
i am not the miantainer, also charts needs some fix, wanting maintainer to response. Another way is maintaining a fork instead |
|
@derekstavis Could your review this PR? |
Summary by cubic
Upgrade to LVGL 9.5 with a new simulator/device HAL, cross‑platform CI, and deterministic screenshot tests with packaged baselines and HTML diff reports. Adds Windows simulator support (MSVC), a
BUILD_LVGL_SIMULATORCMake option, ports Chart to v9, introduces a codegen pipeline and a batched style system, improves JS builds/tests, and exposes a PNG screenshot API on the simulator.New Features
NativeRender.RenderUtil.captureDisplay(path)to save PNGs; docs indoc/jsapi/captureDisplay.md.vcpkg),BUILD_LVGL_SIMULATORCMake option, and Windows setup docs.GetBridge()accessor; shared asset loaders for thetxikiruntime; parallelesbuildbundling; yarn scripts for build, typecheck, specs, and tests. Adds GUI/CLI test harness with expected‑failure support and leak probes.pausedprop for tests.Migration
deps/lvglto v9.5; dropdeps/lv_drivers; route config via top‑levellv_conf.htodeps/lv_conf_sim.h/deps/lv_conf_device.h. Port HAL to LVGL v9 built‑in SDL/display APIs; device builds target Linux; use the simulator on Windows. Engine timer now reschedules fromlv_timer_handler()for smoother frames.lv_bindings_js.h; apply styles via aUint32Arraybatch with generated enums and easing indices.deps/txikito v26.5.0; align QuickJS bindings (single‑argJS_IsArray), update CI/build scripts, and harden MSVC builds.close()and reconciler detach updates.Written for commit 1bb1d12. Summary will update on new commits.