fix(ui): keep messages visible after scrolling in non-chat windows #123

Manually merged
jabber.developer merged 5 commits from fix/scroll-non-chat-windows into master 2026-05-16 15:48:09 +00:00
Collaborator

Summary

Two small fixes around paged scroll state on non-WIN_CHAT windows (MUC, private, AI, console).

  • _win_printf: while the user is scrolled, always bump unread_msg but only skip the buffer append / pad render for WIN_CHAT — it can recover dropped messages via chatwin_db_history on scroll-down. Other window types have no DB fallback, so messages now land in the buffer instead of being silently lost.
  • win_page_down: when a non-chat window reaches the buffer bottom, clear paged and unread_msg. WIN_SCROLL_REACHED_BOTTOM is only set on the is_chat DB branch, so without this the [SCROLLED] / [NEW MESSAGES] indicator would never go off on non-chat windows.

Also removes a local workaround in cl_ev_send_ai_msg that manually reset paged before printing the user prompt — _win_printf now handles this for AI as well.

Test plan

  • In a MUC: scroll up, receive a message, scroll back down — message is present in the buffer and [SCROLLED, NEW MESSAGES] clears on return to bottom.
  • In an AI window: scroll up, send a prompt — prompt appears in the buffer; assistant response also lands; [SCROLLED] clears on scroll-down.
  • In a 1:1 chat: scroll up, receive a message — old behaviour preserved (suppressed in the buffer, recovered via DB on scroll-down).
## Summary Two small fixes around `paged` scroll state on non-`WIN_CHAT` windows (MUC, private, AI, console). - **`_win_printf`**: while the user is scrolled, always bump `unread_msg` but only skip the buffer append / pad render for `WIN_CHAT` — it can recover dropped messages via `chatwin_db_history` on scroll-down. Other window types have no DB fallback, so messages now land in the buffer instead of being silently lost. - **`win_page_down`**: when a non-chat window reaches the buffer bottom, clear `paged` and `unread_msg`. `WIN_SCROLL_REACHED_BOTTOM` is only set on the `is_chat` DB branch, so without this the `[SCROLLED]` / `[NEW MESSAGES]` indicator would never go off on non-chat windows. Also removes a local workaround in `cl_ev_send_ai_msg` that manually reset `paged` before printing the user prompt — `_win_printf` now handles this for AI as well. ## Test plan - [ ] In a MUC: scroll up, receive a message, scroll back down — message is present in the buffer and `[SCROLLED, NEW MESSAGES]` clears on return to bottom. - [x] In an AI window: scroll up, send a prompt — prompt appears in the buffer; assistant response also lands; `[SCROLLED]` clears on scroll-down. - [x] In a 1:1 chat: scroll up, receive a message — old behaviour preserved (suppressed in the buffer, recovered via DB on scroll-down).
jabber.developer2 added 2 commits 2026-05-15 16:51:47 +00:00
fix(ui): preserve messages in non-chat windows while scrolled
All checks were successful
CI Code / Check spelling (pull_request) Successful in 17s
CI Code / Check coding style (pull_request) Successful in 27s
CI Code / Code Coverage (pull_request) Successful in 2m44s
CI Code / Linux (debian) (pull_request) Successful in 4m42s
CI Code / Linux (ubuntu) (pull_request) Successful in 4m57s
CI Code / Linux (arch) (pull_request) Successful in 5m50s
ef0dd74dc1
_win_printf used to drop the buffer append and pad render for any window
in paged state, but only WIN_CHAT can recover lost messages via
chatwin_db_history on scroll-down. WIN_MUC, WIN_PRIVATE and WIN_AI have
no such fallback, so incoming and outgoing messages were silently lost
when the user was viewing history. Suppress the buffer/render only for
WIN_CHAT; for the rest, still bump unread_msg but let the message land
in the buffer so it becomes visible on scroll-down.

This also removes the manual paged/unread_msg reset before printing the
user message in cl_ev_send_ai_msg — it was a local workaround for the
same drop and is no longer needed.

The buffer-bottom reset in win_page_down (c167f487) is still required:
it is the only path that clears paged and unread_msg for non-chat
windows when the user scrolls back to the bottom (WIN_SCROLL_REACHED_BOTTOM
is set only on the is_chat DB branch).
jabber.developer added 1 commit 2026-05-16 12:24:39 +00:00
fix(ui): handle ai window scrolling in titlebar
All checks were successful
CI Code / Check spelling (pull_request) Successful in 17s
CI Code / Check coding style (pull_request) Successful in 30s
CI Code / Code Coverage (pull_request) Successful in 2m45s
CI Code / Linux (debian) (pull_request) Successful in 4m37s
CI Code / Linux (ubuntu) (pull_request) Successful in 4m52s
CI Code / Linux (arch) (pull_request) Successful in 5m40s
506794474a
Add missing scroll rendering for AI windows in
the title bar draw function. This ensures AI
windows display their scrolled state consistently
with other non-chat window types.

New concern: what happens if history is disabled for the user in a normal chat window?

New concern: what happens if history is disabled for the user in a normal chat window?
jabber.developer approved these changes 2026-05-16 13:12:15 +00:00
jabber.developer left a comment
Owner

LGTM

LGTM
jabber.developer2 added 1 commit 2026-05-16 14:06:41 +00:00
fix(ui): preserve WIN_CHAT messages when DB cannot replay them
All checks were successful
CI Code / Check spelling (pull_request) Successful in 16s
CI Code / Check coding style (pull_request) Successful in 32s
CI Code / Code Coverage (pull_request) Successful in 2m45s
CI Code / Linux (debian) (pull_request) Successful in 4m39s
CI Code / Linux (ubuntu) (pull_request) Successful in 4m56s
CI Code / Linux (arch) (pull_request) Successful in 5m45s
0f24910685
_win_printf skipped buffer/pad append for WIN_CHAT while the user was
scrolled, relying on chatwin_db_history() to replay missed messages on
scroll-down. That replay is unavailable when PREF_DBLOG is "off" (no
write) or "redact" ([REDACTED] body), or when the backend failed to
initialize — in those cases the message was lost.

Introduce log_database_can_recover_messages() and gate the WIN_CHAT
early return on it: when recovery is impossible, fall through and
append to the buffer just like non-chat windows do. Also treat
DB_RESPONSE_ERROR in win_page_down the same as DB_RESPONSE_EMPTY so
the [SCROLLED] indicator doesn't hang when the backend is dead.
jabber.developer requested changes 2026-05-16 14:31:13 +00:00
jabber.developer left a comment
Owner

Please address these findings.

Please address these findings.
src/ui/window.c Outdated
@@ -816,1 +816,3 @@
if (db_response == DB_RESPONSE_EMPTY)
// Treat transient DB error (e.g. no active backend) the same
// as EMPTY: no rows can be fetched, so stop indicating [SCROLLED].
if (db_response == DB_RESPONSE_EMPTY || db_response == DB_RESPONSE_ERROR)

If DB returns error, it might be a temporary problem, but it can get user stuck in the middle of the conversation if we change scroll_state. I do not think that DB_RESPONSE_ERROR is a valid reason to switch state.

If DB returns error, it might be a temporary problem, but it can get user stuck in the middle of the conversation if we change `scroll_state`. I do not think that DB_RESPONSE_ERROR is a valid reason to switch state.
jabber.developer marked this conversation as resolved
src/ui/window.c Outdated
@@ -1805,0 +1815,4 @@
* skips the buffer/render only when the DB will preserve the message
* verbatim chatwin_db_history on scroll-down will replay it. When
* the DB is off/redact/dead we cannot recover, so fall through and
* append to the buffer just like non-chat windows. */

it describes the behavior, which can be read from the code itself. It would only make sense to either add a concise explanation on WHY we do it, or to keep this stuff inside of the commit.

it describes the behavior, which can be read from the code itself. It would only make sense to either add a concise explanation on WHY we do it, or to keep this stuff inside of the commit.
jabber.developer marked this conversation as resolved
jabber.developer2 added 1 commit 2026-05-16 14:57:31 +00:00
fix(ui): address PR review on WIN_CHAT scroll handling
All checks were successful
CI Code / Check coding style (pull_request) Successful in 36s
CI Code / Check spelling (pull_request) Successful in 19s
CI Code / Code Coverage (pull_request) Successful in 2m40s
CI Code / Linux (debian) (pull_request) Successful in 4m38s
CI Code / Linux (ubuntu) (pull_request) Successful in 4m53s
CI Code / Linux (arch) (pull_request) Successful in 5m41s
ac7d6c31f0
- Drop DB_RESPONSE_ERROR -> REACHED_BOTTOM in win_page_down: a transient
  backend error (e.g. sqlite lock) should not force the scroll state
  forward, or the user would get stuck mid-conversation expecting more
  rows that did not load.
- Trim the _win_printf comment to a single WHY line; the rest belongs in
  the originating commit message.
jabber.developer manually merged commit a3a45ad477 into master 2026-05-16 15:48:09 +00:00
Sign in to join this conversation.
No description provided.