From 636a62814f0094d5edf34ad2255d8ee5ae1d8fd7 Mon Sep 17 00:00:00 2001 From: Jon Kazama Date: Thu, 21 May 2026 14:43:26 +0200 Subject: [PATCH] fix(ui): isolate scroll-button state from pop-outs and tidy toolbar Guard _childScrolledUp writes behind updateScrollState param so pop-out windows no longer contaminate the main window's scroll state. Widen the honorific title slot budget when the scroll button is visible, fix stale comment, and apply csharpier formatting. --- HellionChat/Ui/ChatLogWindow.cs | 42 +++++++++++++++++++++++++-------- HellionChat/Ui/Popout.cs | 2 +- 2 files changed, 33 insertions(+), 11 deletions(-) diff --git a/HellionChat/Ui/ChatLogWindow.cs b/HellionChat/Ui/ChatLogWindow.cs index a066a77..d26be9f 100644 --- a/HellionChat/Ui/ChatLogWindow.cs +++ b/HellionChat/Ui/ChatLogWindow.cs @@ -781,7 +781,7 @@ public sealed class ChatLogWindow : Window private bool _scrollToBottomRequested; // UI-5: cached each frame inside the ##chat2-messages child. True when the - // user has scrolled up enough that the overlay button should be shown. + // user has scrolled up enough that the toolbar button should be shown. private bool _childScrolledUp; public override void Draw() @@ -1544,7 +1544,13 @@ public sealed class ChatLogWindow : Window CurrentHideState = HideState.User; } - internal void DrawMessageLog(Tab tab, PayloadHandler handler, float childHeight, bool switchedTab) + internal void DrawMessageLog( + Tab tab, + PayloadHandler handler, + float childHeight, + bool switchedTab, + bool updateScrollState = true + ) { using (var child = ImRaii.Child("##chat2-messages", new Vector2(-1, childHeight))) { @@ -1557,12 +1563,15 @@ public sealed class ChatLogWindow : Window // Cached for the header toolbar's scroll-to-bottom button, which is // drawn one frame later. GetScrollMaxY / GetScrollY here refer to - // the child's scroll context. - _childScrolledUp = ImGui.GetScrollMaxY() - ImGui.GetScrollY() > 1f; + // the child's scroll context. Pop-out windows pass updateScrollState: + // false so they do not overwrite the main window's cached state. + if (updateScrollState) + _childScrolledUp = ImGui.GetScrollMaxY() - ImGui.GetScrollY() > 1f; } else { - _childScrolledUp = false; + if (updateScrollState) + _childScrolledUp = false; } } } @@ -1603,15 +1612,17 @@ public sealed class ChatLogWindow : Window // Custom styles can have cellPadding that go above 4, which GetScrollY isn't respecting var cellPaddingOffset = !compact && oldCellPadding.Y > 4f ? oldCellPadding.Y - 4f : 0f; - if (switchedTab || _scrollToBottomRequested - || ImGui.GetScrollY() + cellPaddingOffset >= ImGui.GetScrollMaxY()) + if ( + switchedTab + || _scrollToBottomRequested + || ImGui.GetScrollY() + cellPaddingOffset >= ImGui.GetScrollMaxY() + ) ImGui.SetScrollHereY(1f); _scrollToBottomRequested = false; handler.Draw(); } } - } private void DrawMessages( @@ -2349,7 +2360,12 @@ public sealed class ChatLogWindow : Window var spacing = ImGui.GetStyle().ItemSpacing.X; ImGui.SetCursorPosX(ImGui.GetCursorPosX() + avail - 2 * iconWidth - spacing); - if (ImGuiUtil.IconButton(FontAwesomeIcon.ArrowDown, tooltip: HellionStrings.ChatLog_ScrollToBottom_Tooltip)) + if ( + ImGuiUtil.IconButton( + FontAwesomeIcon.ArrowDown, + tooltip: HellionStrings.ChatLog_ScrollToBottom_Tooltip + ) + ) _scrollToBottomRequested = true; // Keep the pop-out button on the same toolbar row. Without this the @@ -2408,7 +2424,13 @@ public sealed class ChatLogWindow : Window crownWidth = ImGui.CalcTextSize(FontAwesomeIcon.Crown.ToIconString()).X; } - var maxTitleWidth = avail - iconWidth - gapBeforeButton - crownWidth - gapAfterCrown; + // When the scroll button is also present it occupies iconWidth + ItemSpacing.X + // to the left of the pop-out button, so shrink the title budget accordingly. + var scrollButtonReserve = _childScrolledUp + ? iconWidth + ImGui.GetStyle().ItemSpacing.X + : 0f; + var maxTitleWidth = + avail - iconWidth - scrollButtonReserve - gapBeforeButton - crownWidth - gapAfterCrown; if (maxTitleWidth <= 0) { return; diff --git a/HellionChat/Ui/Popout.cs b/HellionChat/Ui/Popout.cs index 750cc55..95c6eb4 100644 --- a/HellionChat/Ui/Popout.cs +++ b/HellionChat/Ui/Popout.cs @@ -118,7 +118,7 @@ internal class Popout : Window var handler = ChatLogWindow.HandlerLender.Borrow(); var logHeight = ImGui.GetContentRegionAvail().Y - inputBarHeight - hintBannerHeight; - ChatLogWindow.DrawMessageLog(Tab, handler, logHeight, false); + ChatLogWindow.DrawMessageLog(Tab, handler, logHeight, false, updateScrollState: false); if (inputEnabled && InputBar != null) {