From 8e353761c7670a82a420f659e73ebcdaf33d33ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 25 Oct 2026 09:41:38 +0100 Subject: [PATCH] UI: Let scroll views extend under the bottom inset when they don't quite reach the edge A vertical ScrollView that extends into the bottom inset (like a navigation bar) adds that much space after its contents, so the end can be scrolled out from under it. It only did that when the view reached the very bottom of the screen, and then added the whole inset. Since 58fa522d48 inset the content area of dialog screens on screens over 600 dp, a phone like the S21 Ultra (617 dp wide) got a 1.7 dp inset, which turned the extra space off. Add exactly the part of the view that lies in the inset instead, and skip the bottom shadow in that case. Co-Authored-By: Claude Opus 5.5 (1M context) --- Common/UI/ScrollView.cpp | 12 ++++++++---- Common/UI/ScrollView.h | 2 ++ 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/Common/UI/ScrollView.cpp b/Common/UI/ScrollView.cpp index 5ace3d90b7..67769db2b6 100644 --- a/Common/UI/ScrollView.cpp +++ b/Common/UI/ScrollView.cpp @@ -246,13 +246,17 @@ bool ScrollView::Touch(const TouchInput &input) { } } +float ScrollView::BottomInsetOverlap() const { + const float insetStart = g_display.dp_yres - System_GetPropertyFloat(SYSPROP_DISPLAY_SAFE_INSET_BOTTOM); + return std::max(0.0f, bounds_.y2() - insetStart); +} + float ScrollView::ChildSize() const { float extraSpace = 0.0f; if (orientation_ == ORIENT_VERTICAL) { - if (bounds_.y2() >= g_display.dp_yres - 1) { - extraSpace = System_GetPropertyFloat(SYSPROP_DISPLAY_SAFE_INSET_BOTTOM); - } + // Let the end of the contents scroll up out of the bottom inset. + extraSpace = BottomInsetOverlap(); } if (views_.empty()) { @@ -320,7 +324,7 @@ void ScrollView::Draw(UIContext &dc) { // Same at the bottom. (we check against the common UI layout mode) const float y2 = dc.GetLayoutBounds(ViewLayoutMode::IgnoreBottomInset, false).y2(); - if (shadows_ && bounds_.y2() < y2 && orientation_ == ORIENT_VERTICAL) { + if (shadows_ && bounds_.y2() < y2 && BottomInsetOverlap() <= 0.0f && orientation_ == ORIENT_VERTICAL) { float radius = 20.0f; Bounds shadowBounds = bounds_; diff --git a/Common/UI/ScrollView.h b/Common/UI/ScrollView.h index 36af547523..b416dcb8e0 100644 --- a/Common/UI/ScrollView.h +++ b/Common/UI/ScrollView.h @@ -52,6 +52,8 @@ public: private: Margins GetMargins() const; float ChildSize() const; // in the scrolled direction + // How far the view reaches into the bottom inset (like a navigation bar). + float BottomInsetOverlap() const; float ScrollMax() const; float HardClampedScrollPos(float pos) const;