Tell the client when an inset other than the top moves - #34
Merged
Merged
Conversation
Both iOS hosts gated reportResizeIfChanged on the bounds and the TOP inset alone: if (w == _last_w && h == _last_h && top_inset == _last_top_inset) return; so a change confined to the left, right or bottom inset raised nothing at all. That was defensible while the top inset was the only one anybody acted on -- it is the one get_client_rect subtracts -- but safe_area_insets reports all four, and docs/host-ios.md tells every iOS client to subtract the other three by hand. A client that does has no way to hear that they moved. Both hosts now track all four edges and split the two notifications. RESIZE fires exactly where it did: the top inset is folded into the rect get_client_rect reports, so a top-only change is a resize to a client even when the bounds held still, which is what the comment in platform_ios.mm already said and is left alone. The other three are not in that rect, so they raise METRICS_CHANGED on its own. The insets are read off the same view each host's safe_area_insets seam reads, so the gate and the answer cannot drift apart. On what this does NOT fix: the case that prompted it was launching straight into landscape, the idea being that the bounds arrive first and the inset resolve is then swallowed. That does not reproduce. Measured on an iPhone 17 Pro / iOS 26.5 with one client binary and only these two files differing, a landscape launch lays out 74 pt clear on each side either way -- UIKit resolves the safe area before the first viewDidLayoutSubviews, so the opening RESIZE already carries the right insets. The hole is real but I have no reproduction of it biting. The concrete trigger is set_home_indicator_auto_hidden, which NEUI_API_IOS ships: it moves safeAreaInsets.bottom and changes no bounds. Verified: fresh iOS configure with NEUI_WERROR=ON builds clean, and the suite on the simulator is 351 cases / 2107 checks, 0 failed.
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.
Both iOS hosts gated
reportResizeIfChangedon the bounds and the top inset alone:so a change confined to the left, right or bottom inset raised nothing at all. That was defensible while the top inset was the only one anybody acted on — it is the one
get_client_rectsubtracts — butsafe_area_insetsreports all four, anddocs/host-ios.mdtells every iOS client to subtract the other three by hand. A client that does had no way to hear that they moved.What changed
Both hosts track all four edges and split the two notifications:
RESIZEfires exactly where it did. The top inset is folded into the rectget_client_rectreports, so a top-only change is a resize to a client even when the bounds held still.platform_ios.mmalready said so in a comment; that behaviour is untouched.METRICS_CHANGEDon their own. They are not in the client rect, so calling them a resize would be a lie.The insets are read off the same view each host's
safe_area_insetsseam reads ([self contentView]/[self neuiView]), so the gate and the answer cannot drift apart.What this does not fix
The case that prompted it was launching straight into landscape — the idea being that the bounds arrive first and the inset resolve is then swallowed. It does not reproduce. Measured on an iPhone 17 Pro / iOS 26.5, one client binary, only these two files differing:
UIKit resolves the safe area before the first
viewDidLayoutSubviews, so the openingRESIZEalready carries the right insets. The hole is real, but I have no reproduction of it biting. The concrete trigger isset_home_indicator_auto_hidden, whichNEUI_API_IOSships: it movessafeAreaInsets.bottomand changes no bounds.Landing it on that basis rather than on an observed break is the call to make when reviewing.
Verified
-DNEUI_WERROR=ON— builds clean, no new warnings.docs/host-ios.mdalready claimedMETRICS_CHANGEDfires on safe-area change, which was only true for the top inset. That line is now accurate and says which event you get for which edge.