client: Workaround initial backlog fetch scrolling
authorShane Synan <digitalcircuit36939@gmail.com>
Sun, 28 Jun 2020 08:41:44 +0000 (04:41 -0400)
committerManuel Nickschas <sputnick@quassel-irc.org>
Sun, 4 Oct 2020 16:19:48 +0000 (18:19 +0200)
Workaround ChatView scrolling somewhere into the middle when first
fetching enough backlog for the vertical scrollbar to become visible.

This happened before when fetching backlog by scrolling, but due to
initial backlog fetching was less noticeable.

A proper fix would be nicer, but this workaround seems to work for
now.  Feel free to tear this out later!

src/qtui/chatview.cpp
src/qtui/chatview.h

index f8fb586..918cec6 100644 (file)
@@ -84,6 +84,9 @@ void ChatView::init(MessageFilter* filter)
     connect(verticalScrollBar(), &QAbstractSlider::valueChanged, this, &ChatView::verticalScrollbarChanged);
     _lastScrollbarPos = verticalScrollBar()->maximum();
 
+    // Workaround for the ChatView scrolling up a fair bit when scrollbar becomes visible
+    verticalScrollBar()->installEventFilter(this);
+
     connect(Client::networkModel(), &NetworkModel::markerLineSet, this, &ChatView::markerLineSet);
 
     // only connect if client is synched with a core
@@ -157,6 +160,28 @@ bool ChatView::event(QEvent* event)
     return QGraphicsView::event(event);
 }
 
+bool ChatView::eventFilter(QObject* watched, QEvent* event)
+{
+    QAbstractSlider* vbar = verticalScrollBar();
+    Q_ASSERT(vbar);
+
+    if (watched != vbar) {
+        // Ignore and pass through all events not featuring the scrollbar
+        return false;
+    }
+    if (event->type() == QEvent::Show) {
+        // FIXME: Workaround for the ChatView scrolling up a fair bit when transitioning from the
+        // vertical scrollbar not being visible, to becoming visible.  This happens especially
+        // often when no initial backlog is loaded.
+        if (_backlogRequestedBeforeScrollable) {
+            _backlogRequestedBeforeScrollable = false;
+            vbar->setValue(vbar->maximum());
+        }
+    }
+    // Pass through all events
+    return false;
+}
+
 void ChatView::resizeEvent(QResizeEvent* event)
 {
     // if view is currently scrolled to bottom, we want it that way after resizing
@@ -415,6 +440,7 @@ bool ChatView::requestBacklogForScroll()
         // Future improvement: continue fetching backlog in chunks until the scrollbar is visible,
         // or the beginning of the buffer has been reached.
         scene()->requestBacklog();
+        _backlogRequestedBeforeScrollable = true;
         // Backlog has been requested
         return true;
     }
index 69bc2cd..0f90a66 100644 (file)
@@ -102,6 +102,7 @@ public slots:
 
 protected:
     bool event(QEvent* event) override;
+    bool eventFilter(QObject* watched, QEvent* event) override;
     void resizeEvent(QResizeEvent* event) override;
     void scrollContentsBy(int dx, int dy) override;
 
@@ -129,6 +130,8 @@ private:
     bool _invalidateFilter;
     QSet<ChatLine*> _linesWithCache;
     bool _firstTouchUpdateHappened = false;
+    /// Workaround: If true, backlog has been requested before the vertical scrollbar became visible
+    bool _backlogRequestedBeforeScrollable{false};
 };
 
 #endif