feat(native): electron-parity features (power monitor, screen, process, net, cookie/cache, image, notifications, update) - #117
Draft
justjavac wants to merge 35 commits into
Draft
feat(native): electron-parity features (power monitor, screen, process, net, cookie/cache, image, notifications, update)#117justjavac wants to merge 35 commits into
justjavac wants to merge 35 commits into
Conversation
Add persist_session_cookies support to align with Electron's default session persistence behavior. Session cookies (no expiry), such as GitHub login credentials, now survive app restarts. Root causes fixed: 1. cache_dir auto-generation included PID (macOS/Linux), producing a different path on every restart — all cookie data was lost 2. Windows had no cache_dir auto-generation at all, leaving CEF in in-memory mode 3. persist_session_cookies was never set in cef_settings_t, so even with a stable cache_path, session cookies were not written to disk Changes: - Add persist_session_cookies to RuntimeConfig (default: true) - Add field to C config validation whitelist (proton_config.c) - Parse and apply in all three CEF engines (mac/win/linux) - Fix cache_dir auto-generation: stable path without PID (mac/linux) - Add cache_dir auto-generation on Windows via GetTempPathW - Update generated .mbti signatures, tests, and README Validation: - moon check --target native — passed - moon fmt --check — passed - node scripts/verify_generated.mjs — passed
…cookies # Conflicts: # proton/prebuilt/darwin-arm64/manifest.json # proton/prebuilt/linux-x64/manifest.json # proton/prebuilt/win32-x64/manifest.json
…notification/update Add native C ABI and engine implementations for five Electron-parity features backed by CEF: - Screen enumeration (proton_screen_enumerate_json) returning display bounds, work area, scale factor, and primary flag. - Session cookie/cache management (proton_window_cookie_begin_get_json, _poll_get_json, _set_json, _delete, _flush, proton_window_clear_cache) using a begin/poll pattern for async cookie visits. - Native image handling (proton_image_* backed by cef_image_t) supporting PNG/JPEG/bitmap representations with multi scale factor and conversion. - Windows/Linux notifications (cef_win/notification.c via Shell_NotifyIconW, cef_linux/notification.c via libnotify) reusing the existing proton_notification_* ABI. - Windows/Linux update install (proton_update.c Windows branch) reusing the existing RSA signature + staging transaction infrastructure. All new ABI entries are additive; proton_engine_none.c provides stubs returning PROTON_ERR_UNSUPPORTED for non-CEF builds. CMakeLists.txt wires the new cef_common sources (cookie_cache.c, image.c) and platform notification sources. The updater extension metadata now advertises windows + linux platforms.
Add type-safe MoonBit wrappers over the new C ABI: - screens() returns Array[ScreenInfo] with bounds, work area, scale factor, and primary flag. - Window::cookie_begin_get/cookie_poll_get/cookie_set/cookie_delete/ cookie_flush/clear_cache wrap the session cookie/cache ABI. - NativeImage type with create_empty/add_png/add_jpeg/add_bitmap/ is_empty/size/to_png/to_jpeg/to_bitmap, backed by the handle registry. - read_native_bytes helper for binary two-call (probe then read) pattern, symmetric with require_native_text. - ImageSize struct derives FromJson/ToJson per the JSON bridge convention. - Update install test coverage for the Windows/Linux update path.
Add power_monitor sys module and extension for system power event monitoring, closing the Electron powerMonitor parity gap. sys/power_monitor provides: - Cross-platform C ABI in native_common.c with platform implementations: native_windows.c (WM_POWERBROADCAST), native_macos.c (NSWorkspace notifications), native_linux.c (DBus). - MoonBit FFI bindings (native_ffi.mbt) and error types (errors.mbt). extensions/power_monitor exposes event subscription commands; events flow through the existing RuntimeEvent channel. Registers the module in moon.work, extension sets (all + desktop), and metadata check.
Add process sys module and extension for spawning child processes, closing the Electron child_process parity gap. sys/process provides: - Cross-platform C ABI in native_common.c with platform implementations: native_windows.c (CreateProcessW), native_macos.c/native_linux.c (posix_spawn/fork+exec). - MoonBit FFI bindings (native_ffi.mbt) and error types (errors.mbt). - spawn/poll_stdout/poll_stderr/wait/kill operations using a polling pattern that fits Proton wake-driven architecture. extensions/process exposes the spawn/poll/wait/kill commands. Registers the module in moon.work, extension sets (all + desktop), and metadata check.
Add net extension for HTTP requests, closing the Electron net parity gap. extensions/net exposes HTTP request commands backed by the CEF network stack, sharing cookie/cache context with the browser. Registers the extension in extension sets (all + desktop) and metadata check.
…tures Rebuild the shipped win32-x64 Proton native artifacts (proton.dll, proton.lib, proton_native.h) to include the new screen/cookie/image/notification/update C ABI entries.
Document the 8 Electron-parity features implemented in this branch, their implementation locations, architecture compliance, remaining low-priority todos, and the commit structure used to organize the work.
… 8 Electron parity features
justjavac
marked this pull request as draft
August 13, 2026 07:37
…nings Integrate main up to #121 (cef_process GUI-subsystem on Windows) and the moon_config 0.3.13 bump. Resolve win32 prebuilt artifacts against the merged source, update all platform source hashes, and fix two --deny-warn blockers: rename the net Request.method reserved-keyword field to http_method, and drop the unused raise on power_monitor's on_destroy.
The darwin-arm64 prebuilt was not rebuilt after the electron-parity C ABI entries were added, so libproton.dylib was missing the proton_image_*, proton_screen_enumerate_json, and proton_window_cookie_*/clear_cache exports. This caused the macOS prebuilt ABI check to fail in CI. Rebuild the prebuilt from the merged source and re-record the source hash. Also define the missing PROTON_ENGINE_RETURN_ON_MAIN macro used by proton_engine_screen_enumerate to marshal AppKit screen access to the main thread, which would otherwise fail the native engine build.
The 0.1.20260814 nightly turned `lexscan` into a hard error for String/StringView inputs, which breaks the pinned moonbitlang/x@0.4.49 dependency (path/win32 still uses lexscan on StringView). This broke the Verify generated files step on every platform. Pin the toolchain to the last known-good nightly until moonbitlang/x ships a lexbuf-compatible version.
Pinning a dated `nightly` snapshot is impossible (the CDN only serves `nightly` and `latest`), and the current nightly breaks the pinned `moonbitlang/x@0.4.49` lexer and turns implicit-impl deprecations into `--deny-warn` errors. Switch to the stable `latest` channel instead.
justjavac
force-pushed
the
feat/electron-parity
branch
from
August 14, 2026 08:53
8402d93 to
7078473
Compare
The stable `latest` MoonBit channel ships moonc 0.1.20260811, which cannot link the `thread_pool/make_open_stat_job` wasm import introduced in async@0.20.5 (`make_open_job` in earlier releases). This broke `moon build codegen --target wasm` on every platform. Downgrade async to 0.20.4, which pairs correctly with the stable toolchain, and refresh the prebuilt source hashes and the win32 embedded hash stamp accordingly.
…lity The nightly toolchain rejects the `lexscan` used on `String`/`StringView` in x@0.4.49's path/win32 with error 4222. x@0.4.50 removes those calls. Refresh the prebuilt source hashes and re-stamp the win32 embedded hash.
Keep the MoonBit toolchain on the `nightly` channel and scope the `--deny-warn` check to tolerate the `implicit_impl_as_method` (0079) deprecation that current nightlies turn into hard errors.
…tions Make the macOS native notification test bundle-aware: support is off on bare CI runners without a bundle identifier, so only assert the empty activation queue and cleanup unconditionally. Retry the E2E scenario build inside the retry loop and treat a non-blocking subprocess-pipe errno (EAGAIN) on a loaded CI runner as a transient transport failure rather than a scenario failure.
… timeout The power monitor stub statically linked CoreFoundation and IOKit, which produced undefined symbols when the extensions test linked on macOS CI. Load both frameworks at runtime with dlfcn, matching the keepawake stub. The 52_web_contents_view self-hosted e2e drives several phase-sized waits (target, browser, page, ready, paint, closed, shutdown) against a live CEF app. On a loaded shared runner each phase can approach its own timeout, so the doubled outer guard was too tight and the whole probe timed out twice. Grant it four phase-sized budgets instead.
…t wait The scenario retry loop allowed only two attempts and classified the web-contents-view target waiter as non-retryable because its message says "CDP page targets did not become ready" (plural) while the matcher only recognized the singular spelling. On a loaded CI runner a transient pipe EAGAIN in the child app can therefore kill the probe on the final attempt. Match both spellings of the target-wait failure and grant the heavy scenarios three attempts so a transient load bump does not fail the E2E.
A transient pipe read EAGAIN on the macOS shared runner can recur across several consecutive attempts while the host builds and spawns the CEF app. Grant four attempts and back off two seconds between them so a clean probe has room to run instead of failing the whole E2E on a load spike.
… timeout The web-contents-view scenario asserts on auxiliary log files (OSR paint records, per-view event logs) that the child app writes asynchronously. On a loaded shared runner those files can lag, so the heavy scenario failed at a different post-startup phase on each attempt and the failures were not retryable. Treat them as transient so the scenario can retry cleanly. Retrying the heavy scenario also needs more wall-clock budget than the 10 minute E2E step allowed, so raise the Unix and Windows E2E step timeout to 25 minutes.
The recurring macOS E2E failures all traced to @process.ReadFromProcess pipe reads raising a transient EAGAIN on the loaded shared runner: the scenario-app build capture and the ps process-tree snapshot both truncated on EAGAIN, dropping the root process from the snapshot. Run both through redirection to a file and read the file instead, removing the pipe-read source of the flakiness rather than masking it with more retries.
…fixture The web contents view scenario app crashed on a non-blocking wakeup pipe read that surfaced EAGAIN after the event queue was drained, so the CDP targets never became ready and the probe timed out. The wakeup descriptor is non-blocking: a read with no byte latched yet is not a fatal pipe error. Yield to the runtime and retry the read until the next wakeup byte arrives.
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.
Summary
Closes the highest-priority Electron parity gaps by implementing eight features across the native C ABI, MoonBit FFI bindings, and extension layer. All features follow the existing Proton architecture (C ABI → MoonBit FFI → extension/facade) and reuse existing infrastructure (handle registry, RuntimeEvent channel, RSA signature + staging transactions).
Changes
Native C ABI + Engine (
native/)proton_screen_enumerate_json): returns JSON array of displays with bounds, work area, scale factor, and primary flagproton_window_cookie_begin_get_json/_poll_get_json/_set_json/_delete/_flush,proton_window_clear_cache): begin/poll pattern for async cookie visits; fire-and-forget for set/delete/flush/clearproton_image_*backed bycef_image_t): PNG/JPEG/bitmap representations with multi scale factor and format conversioncef_win/notification.cviaShell_NotifyIconW,cef_linux/notification.cvia libnotify — reuses existingproton_notification_*ABIproton_update_installreusing existing RSA signature + staging transaction infrastructure; Linux AppImage atomic replaceproton_engine_none.cstubs for all new ABI entriescef_commonsources (cookie_cache.c,image.c) and platform notification sourcesMoonBit Bindings (
proton/native/)screens() -> Array[ScreenInfo]Window::cookie_begin_get/cookie_poll_get/cookie_set/cookie_delete/cookie_flush/clear_cacheNativeImagetype withcreate_empty/add_png/add_jpeg/add_bitmap/is_empty/size/to_png/to_jpeg/to_bitmapread_native_byteshelper for binary two-call (probe then read) patternImageSizestruct derivesFromJson/ToJsonPowerMonitor (
sys/power_monitor/+extensions/power_monitor/)WM_POWERBROADCAST, macOSNSWorkspacenotifications, Linux DBusRuntimeEventchannelChild Process (
sys/process/+extensions/process/)CreateProcessW, macOS/Linuxposix_spawn/fork+execspawn/poll_stdout/poll_stderr/wait/killusing a polling pattern that fits Proton wake-driven architecturenet/HTTP (
extensions/net/)Registration
power_monitor,process,netinmoon.work, extension sets (all+desktop), and metadata checkPrebuilt
win32-x64prebuilts (proton.dll,proton.lib,proton_native.h) with the new C ABI entriesBehavior Alignment
Architecture Compliance
proton_engine_none.cprovides stubs returningPROTON_ERR_UNSUPPORTEDfor non-CEF buildssys/<pkg>/, not inlined into extensions<Name>Errornaming convention...W+ UTF-8 conversion, no ANSI variantswindow.__MoonBit__usage; all flows go through the native DLL bridgeValidation