Skip to content

fix(ohos): pull-to-refresh contentInset offset rests at 0 under margin model, not -inset.top - #102

Merged
bytemain merged 1 commit into
staging2from
hanxin/ohos-pull-refresh-inset-1x
Aug 1, 2026
Merged

fix(ohos): pull-to-refresh contentInset offset rests at 0 under margin model, not -inset.top#102
bytemain merged 1 commit into
staging2from
hanxin/ohos-pull-refresh-inset-1x

Conversation

@bytemain

@bytemain bytemain commented Aug 1, 2026

Copy link
Copy Markdown
Member

Problem (Raft task #110)

On OpenHarmony, the Activity pull-to-refresh showed a ~2× (~180dp) top blank that stayed for the entire refresh, with the spinner centered in it. Android/iOS are unaffected.

Root cause

OHOS realizes KRScrollerView contentInset as an ArkUI margin (a physical top shift). But SetContentInset's animate path snaps the content offset to MaxContentOffsetInContentInset, whose top-overscroll branch returns {0, -content_inset->top} — the iOS resting-offset semantics — and then applies SetArkUIMargin(top=inset.top). During a held refresh inset (top=80), offset -80 + margin 80 double-count = 160vp ≈ 180dp = 2×. iOS is correct because its native contentInset shifts the coordinate origin (no margin); this file is core-render-ohos only.

Fix

Under the margin model the top resting offset is 0, so clamp top-overscroll to {0, 0}. Release then settles to offset 0 + margin 80 = 1×; the recycle path (inset top=0) still clamps a residual negative offset to 0.

  • MaxContentOffsetInContentInset is used only by SetContentInset → low blast radius, normal scroll/inertia clamps untouched.
  • The symmetric horizontal start branch is the same latent class but is not exercised by task fix(compose): redraw restored lazy descendants #110 (vertical/top); left as a separate follow-up, intentionally not bundled.

On-device verification (HOP-AL10, HarmonyOS)

  • Product PASS (artin, hands-on): the stuck ~2× blank is gone → now 1×. The remaining transient — pull reaches 2× while the finger drags, then bounces back to 1× on release — is standard pull-to-refresh (Android baseline behaves identically), not the bug.
  • Provenance / single-variable knife: device base 53e5892fd pins fork b57fc344 (this PR's parent) via gitlink + kuikly-render-staging2-b57fc344.har; candidate carrier ecf8d9816 advances only that fork to 19f29487. Native libkuikly.so BuildId changed e4077a2b…bfa3d280… (HAP 5c0fd527…), proving the device runs this exact change and not a stale HAR — the only runtime delta is this one commit.
  • Control-flow proof: post-fix there is no vertical top-overscroll path that returns -inset.top, so a release-time offset -80 + margin 80 (2×) is impossible by construction; the observed transient 2× can only come from finger-driven overscroll during the drag.

Credits: localization @赵梓淇/Cindy · Android oracle + repro @pixel · device verification & build provenance @ark.

Author: HanXin (see Signed-off-by). Per our flow the author does not self-merge — a permitted maintainer presses.

…n model, not -inset.top

OHOS realizes KRScrollerView contentInset via an ArkUI margin (physical
top shift). SetContentInset's animate path snapped the content offset to
MaxContentOffsetInContentInset's top target -inset.top (iOS resting-offset
semantics) and then applied margin(top=inset.top); during a held refresh
inset the offset(-top) and margin(top) double-count, so the Activity
pull-to-refresh showed ~2x (160vp / ~180dp) top blank. iOS is unaffected
(native contentInset shifts the origin); this file is core-render-ohos only.

Under the margin model the top resting offset is 0, so clamp top-overscroll
to {0,0}. The recycle path (inset top=0) still clamps a residual negative
offset to 0. The helper is used only by SetContentInset, so normal
scroll/inertia clamps are untouched. The symmetric horizontal `start`
branch is a separate latent case, not exercised by task #110, left as
follow-up.

task #110 — pending HOP-AL10 device verification.

Signed-off-by: PaoDing <raft-mobile-paoding@mail.build>
Signed-off-by: HanXin <hanxin@mail.build>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@bytemain
bytemain force-pushed the hanxin/ohos-pull-refresh-inset-1x branch from 19f2948 to 64a0fc6 Compare August 1, 2026 07:18
@bytemain
bytemain merged commit 4b51659 into staging2 Aug 1, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant