Chatterino / chatterino2

Chat client for https://twitch.tv
MIT License
2.07k stars 449 forks source link

Smooth scrolling is not smooth #5349

Open adrian-r-villa opened 7 months ago

adrian-r-villa commented 7 months ago

Checklist

Describe your issue

I updated to 2.5.0 today to notice that the chat looked very choppy in comparison to the browser, so I ran a side-by-side test with FFZ's 'very-fast' smooth scrolling setting on the left and Chatterino's smooth scrolling and smooth scrolling on new messages settings on the right. The two used to be exactly identical in behavior prior to this update; I am not sure what has changed.

Screenshots

https://github.com/Chatterino/chatterino2/assets/38902903/d0ade95f-d862-48d7-99aa-0ae01b54989f

OS and Chatterino Version

Chatterino 2.5.0 (commit 3aead093) built with Qt 6.5.0, MSVC 193833135 Running on Windows 10 Version 22H2, kernel: 10.0.19045

Pizzabelly commented 7 months ago

Did you update from a version before 2.4.5? There was a change in that version that made the behavior of smooth scrolling on new messages more consistent. But that now means the animation consistently has a duration of only 150ms, which is likely to be seen as subjectively not smooth. It should be possible to have a separate duration and easing curve for new messages and manual scrolling. I made a proof of concept here:

diff --git a/src/widgets/Scrollbar.cpp b/src/widgets/Scrollbar.cpp
index 6ca0e248..884e8ee1 100644
--- a/src/widgets/Scrollbar.cpp
+++ b/src/widgets/Scrollbar.cpp
@@ -23,9 +23,6 @@ Scrollbar::Scrollbar(size_t messagesLimit, ChannelView *parent)
     , highlights_(messagesLimit)
 {
     this->resize(int(16 * this->scale()), 100);
-    this->currentValueAnimation_.setDuration(150);
-    this->currentValueAnimation_.setEasingCurve(
-        QEasingCurve(QEasingCurve::OutCubic));
     connect(&this->currentValueAnimation_, &QAbstractAnimation::finished, this,
             &Scrollbar::resetMaximum);

@@ -146,21 +143,26 @@ void Scrollbar::setSmallChange(qreal value)
     this->updateScroll();
 }

-void Scrollbar::setDesiredValue(qreal value, bool animated)
+void Scrollbar::setDesiredValue(qreal value, bool animated, bool wheelInput)
 {
     value = std::max(this->minimum_, std::min(this->getBottom(), value));

+    this->atBottom_ = (this->getBottom() - value) <= 0.0001;
+
     if (std::abs(this->currentValue_ - value) <= 0.0001)
     {
         return;
     }

+    wheelInput = wheelInput && !this->atBottom_;
+    this->currentValueAnimation_.setEasingCurve(
+        QEasingCurve(wheelInput ? QEasingCurve::OutCubic : QEasingCurve::Linear));
+    this->currentValueAnimation_.setDuration(wheelInput ? 150 : 330);
+
     this->desiredValue_ = value;

     this->desiredValueChanged_.invoke();

-    this->atBottom_ = (this->getBottom() - value) <= 0.0001;
-
     if (animated && getSettings()->enableSmoothScrolling)
     {
         // stop() does not emit QAbstractAnimation::finished().
diff --git a/src/widgets/Scrollbar.hpp b/src/widgets/Scrollbar.hpp
index d025539c..5edabd93 100644
--- a/src/widgets/Scrollbar.hpp
+++ b/src/widgets/Scrollbar.hpp
@@ -40,7 +40,7 @@ public:
     void offsetMinimum(qreal value);
     void setLargeChange(qreal value);
     void setSmallChange(qreal value);
-    void setDesiredValue(qreal value, bool animated = false);
+    void setDesiredValue(qreal value, bool animated = false, bool wheelInput = false);
     qreal getMaximum() const;
     qreal getMinimum() const;
     qreal getLargeChange() const;
diff --git a/src/widgets/helper/ChannelView.cpp b/src/widgets/helper/ChannelView.cpp
index c5a67972..15477fc6 100644
--- a/src/widgets/helper/ChannelView.cpp
+++ b/src/widgets/helper/ChannelView.cpp
@@ -1765,7 +1765,7 @@ void ChannelView::wheelEvent(QWheelEvent *event)
             }
         }

-        this->scrollBar_->setDesiredValue(desired, true);
+        this->scrollBar_->setDesiredValue(desired, true, true);
     }
 }

Ideally I think this should be user-configurable.

adrian-r-villa commented 7 months ago

Yes, I have been on v2.4.6 since it was released, and I noticed the issue then as well, but believed it to be hardware acceleration related (web-browser, etc.). Prior versions were perfect for me and "FFZ-like," as I mentioned in the original post. I believe that was mostly due to me not using the split tab feature after checking previous user issues. I have had zero issues for years, great software.

The implementation is over my head, as I am just a tech savvy user and I do not program in C++, but I want to ask a question, as I am interested in contributing to more projects in the future. If the implementation is user-configurable, would it be possible to get ms lower than FFZ's "Very Fast" setting showcased in the comparison video? Whether or not if it's feasible, I really appreciate everyone working on Chatterino and look forward to smooth scrolling being fixed. Thank you!