Deliver native events to webview screens on Android - #379
Open
gwleuverink wants to merge 5 commits into
Open
Conversation
…hat only the edge queue carried
…n edge screens like it already did on webview
…ceive ShakeDetected
gwleuverink
marked this pull request as ready for review
August 25, 2026 14:26
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.
Fixes #360.
AppearanceChangedandShakeDetectedwere sent withNativeElementBridge.sendNativeEvent, which only feeds the EDGE element queue. Nothing drains that queue on a webview screen, so neither PHP nor the page's JS listener ever heard them.System::appearance()froze on its first read for the life of the process, and shakes vanished entirely.#[On], noEvent::listen, nonative-eventin the pageThe fix
sendNativeEventbecomes the one dispatch channel. It writes the element queue as before, then hands the event to an installableWebEventSink:MainActivityimplements the sink and injects into the page throughNativeActionCoordinator.dispatchToWebView(CustomEvent, Livewire dispatch, POST to/_native/api/events). It skips whileNativeUIBridge.isActive, because an EDGE screen's runloop is already draining the queue and injecting into the page behind it would deliver the same event twice when that page returns.Fixing the channel rather than the two call sites is deliberate. Every future emitter gets web delivery, and calling the primitive directly can no longer skip the page.
__-prefixed signals (__deeplink) stay queue-only, since they exist purely to wake the runloop and carry no PHP event class.NativeActionCoordinator.dispatchnow just calls the channel, so alert and file-picker events stop doing their own separate injection and deliver once instead of twice.Two smaller pieces
ShakeDetectednow implementsBroadcastsGlobally, likeAppearanceChangedalready did. Webview screens reachedEvent::listenthrough the POST; EDGE screens only reached#[On]handlers. A shake has no owning component, so the marker closes that gap without relying on the page injection.On iOS,
ShakeDetectorcalledNativeElementBridge.sendNativeEventdirectly instead of going throughLaravelBridge.send, whichContentViewupgrades to the web-injecting closure once a WebView exists. So iOS shake never reached webview screens either. It now routes like every other device event.Verification
Rig with probes on both surfaces, logging one line per delivery arm with the PHP pid, so a process restart can't be mistaken for a fix.
Android webview, appearance flipped with
adb shell cmd uimode night yesthenno:Same pid throughout, so the API tracked the OS rather than being reseeded by a relaunch. Every shake delivers exactly once per arm, on both platforms:
EDGE screens are unchanged, verified in the hybrid case too (an EDGE screen over a cached WebView): one
#[On]call, no page injection, no duplicate POST.__deeplinkstill navigates and never reaches the web arm.Suite is green, 58 passed.
Merge order with #359
Larry's thermal monitor in #359 calls the same primitive, so it inherits this fix without changes to his branch. #359 merges onto this one with no conflicts (
MainActivity.ktis the only shared file and it auto-merges), and the combined tree's suite is green including his new thermal tests. Built with both applied, a thermal override now reaches every arm and the cached read follows:Before this fix nothing arrived on a webview screen at all. The enum 500 I reported on #359 is gone since his
48074ed. Suggested order: this PR first, then #359 on top.