[polari] chatview: Keep scroll position when loading extra logs



commit 9dd0ae90d24e892332879da60a2b2cfec285ec25
Author: Raidro Manchester <raibo quadrofus gmail com>
Date:   Sun Jun 6 11:31:53 2021 +0300

    chatview: Keep scroll position when loading extra logs
    
    Everyone else does it, and it makes a lot more sense.
    This is mostly based on how Fractal implements this.
    
    Disabling kinetic scrolling inbetween loads is needed due to
    https://gitlab.gnome.org/GNOME/gtk/merge_requests/395.

 src/chatView.js | 21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)
---
diff --git a/src/chatView.js b/src/chatView.js
index 10267aaf..9ef5851d 100644
--- a/src/chatView.js
+++ b/src/chatView.js
@@ -323,6 +323,8 @@ const ChatView = GObject.registerClass({
         this.vadjustment.connect('value-changed',
             this._onValueChanged.bind(this));
         this.vadjustment.connect('changed', this._updateScroll.bind(this));
+        this.vadjustment.connect('notify::upper',
+            this._onUpperChanged.bind(this));
 
         this._view.connect('key-press-event', this._onKeyPress.bind(this));
         this._view.connect('motion-notify-event',
@@ -371,6 +373,7 @@ const ChatView = GObject.registerClass({
         this._getLogEvents(NUM_INITIAL_LOG_EVENTS);
 
         this._autoscroll = true;
+        this._originalUpper = this.vadjustment.get_upper();
 
         this._app = Gio.Application.get_default();
         DropTargetIface.addTargets(this, this._view);
@@ -642,6 +645,10 @@ const ChatView = GObject.registerClass({
         let iter = this._view.buffer.get_start_iter();
 
         for (let i = 0; i < pending.length; i++) {
+            // Workaround https://gitlab.gnome.org/GNOME/gtk/merge_requests/395
+            this.set_kinetic_scrolling(false);
+            this._insertingBacklog = true;
+
             this._insertMessage(iter, pending[i], state);
 
             if (i === indicatorIndex)
@@ -771,6 +778,20 @@ const ChatView = GObject.registerClass({
         });
     }
 
+    _onUpperChanged() {
+        const newUpper = this.vadjustment.get_upper();
+        const diff = newUpper - this._originalUpper;
+
+        if (diff !== 0.0) {
+            this._originalUpper = newUpper;
+            if (this._insertingBacklog) {
+                this.vadjustment.set_value(this.vadjustment.get_value() + diff);
+                this.set_kinetic_scrolling(true);
+                this._insertingBacklog = false;
+            }
+        }
+    }
+
     _pendingMessageRemoved(channel, message) {
         let [id, valid] = message.get_pending_message_id();
         if (!valid || !this._pending.has(id))


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]