Philipp Hörist pushed to branch master at gajim / gajim


Commits:
41c3bfe0 by mesonium at 2026-08-25T20:33:16+02:00
cfix: ConversationView: Restore notifying when the view is at bottom

- - - - -
7e42129d by mesonium at 2026-08-25T20:50:57+02:00
cfix: ConversationView: Delay at-bottom signal on resize or scroll

- - - - -


1 changed file:

- gajim/gtk/conversation/view.py


Changes:

=====================================
gajim/gtk/conversation/view.py
=====================================
@@ -132,6 +132,7 @@ def __init__(
         self._requesting: str | None = None
         self._block_signals = False
         self._scroll_end_timeout_id: int | None = None
+        self._at_bottom_notify_pending = False
 
         self._signal_handlers_enabled = False
         self._signal_handler_ids = (0, 0)
@@ -233,6 +234,7 @@ def clear(self) -> None:
         if self._scroll_end_timeout_id is not None:
             GLib.source_remove(self._scroll_end_timeout_id)
             self._scroll_end_timeout_id = None
+        self._at_bottom_notify_pending = False
 
         self._reset()
 
@@ -436,9 +438,18 @@ def _restore_scroll_anchor(
         if abs(value - adj.get_value()) < 1:
             return False
 
-        # Keeping the content in place is not the user scrolling, don't let it
-        # turn into autoscroll. Otherwise content which shrinks enough to push
-        # the anchor against the bottom would latch the view there.
+        if row is None:
+            # We were already autoscrolling and are only keeping the view
+            # pinned to the bottom, so let the normal at-bottom bookkeeping
+            # (and the "mark as read" logic it triggers) run as usual.
+            adj.set_value(value)
+            return True
+
+        # Keeping a row in place while not autoscrolling is not the user
+        # scrolling, don't let it turn into autoscroll. Otherwise content
+        # which shrinks enough to push the anchor against the bottom would
+        # latch the view there, and firing "at-bottom" here would wrongly
+        # mark messages as read that the user hasn't actually seen.
         self._applying_anchor = True
         adj.set_value(value)
         self._applying_anchor = False
@@ -499,7 +510,14 @@ def _on_adj_value_changed(
 
         if not self._applying_anchor:
             self._autoscroll = self._determine_autoscroll()
-            self._notify("at-bottom")
+            # Defer the actual notification until scrolling settles (see
+            # _stop_scrolling): do_size_allocate() re-runs this every time
+            # anything resizes while pinned to the bottom (window resizes,
+            # avatar/preview loads, rewraps, ...), not just on new messages.
+            # Notifying synchronously here would re-trigger "mark as read"
+            # dozens of times per second, e.g. while the user drags a window
+            # edge, even though at_bottom hasn't actually changed.
+            self._at_bottom_notify_pending = True
 
         if self._upper_complete:
             self._request_history_at_upper = None
@@ -549,6 +567,10 @@ def _start_scrolling(self) -> None:
     def _stop_scrolling(self) -> bool:
         self._scroll_end_timeout_id = None
 
+        if self._at_bottom_notify_pending:
+            self._at_bottom_notify_pending = False
+            self._notify("at-bottom")
+
         self._reposition_message_row_actions()
         self._message_row_actions.set_scrolling(False)
 



View it on GitLab: 
https://dev.gajim.org/gajim/gajim/-/compare/cdea5792f41780cdf087279b6b0233aecc6bc4a3...7e42129d4f85f3e2673efae05a7f985a78083b47

-- 
View it on GitLab: 
https://dev.gajim.org/gajim/gajim/-/compare/cdea5792f41780cdf087279b6b0233aecc6bc4a3...7e42129d4f85f3e2673efae05a7f985a78083b47
You're receiving this email because of your account on dev.gajim.org.


_______________________________________________
Commits mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to