X-Git-Url: https://git.quassel-irc.org/?p=quassel.git;a=blobdiff_plain;f=src%2Fqtui%2Fchatview.cpp;h=918cec64a42bb662d0729d9fdeb005435c209344;hp=eb800007c307af269d50ac67bb5bca6b95173518;hb=26406e4c1f049a021fd99fd6592389289a510e99;hpb=c1cf157116de7fc3da96203aa6f03c38c7ebb650 diff --git a/src/qtui/chatview.cpp b/src/qtui/chatview.cpp index eb800007..918cec64 100644 --- a/src/qtui/chatview.cpp +++ b/src/qtui/chatview.cpp @@ -1,5 +1,5 @@ /*************************************************************************** - * Copyright (C) 2005-2018 by the Quassel Project * + * Copyright (C) 2005-2020 by the Quassel Project * * devel@quassel-irc.org * * * * This program is free software; you can redistribute it and/or modify * @@ -20,6 +20,8 @@ #include "chatview.h" +#include + #include #include #include @@ -33,6 +35,7 @@ #include "messagefilter.h" #include "qtui.h" #include "qtuistyle.h" +#include "util.h" ChatView::ChatView(BufferId bufferId, QWidget* parent) : QGraphicsView(parent) @@ -81,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 @@ -97,8 +103,7 @@ bool ChatView::event(QEvent* event) case Qt::Key_Down: case Qt::Key_PageUp: case Qt::Key_PageDown: - if (!verticalScrollBar()->isVisible()) { - scene()->requestBacklog(); + if (requestBacklogForScroll()) { return true; } default: @@ -142,8 +147,7 @@ bool ChatView::event(QEvent* event) if (event->type() == QEvent::Wheel || (event->type() == QEvent::TouchBegin && ((QTouchEvent*)event)->device()->type() == QTouchDevice::TouchScreen) || event->type() == QEvent::TouchUpdate) { - if (!verticalScrollBar()->isVisible()) { - scene()->requestBacklog(); + if (requestBacklogForScroll()) { return true; } } @@ -156,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 @@ -291,8 +317,8 @@ QSet ChatView::visibleChatLines(Qt::ItemSelectionMode mode) const QList ChatView::visibleChatLinesSorted(Qt::ItemSelectionMode mode) const { - QList result = visibleChatLines(mode).toList(); - qSort(result.begin(), result.end(), chatLinePtrLessThan); + QList result = visibleChatLines(mode).values(); + std::sort(result.begin(), result.end(), chatLinePtrLessThan); return result; } @@ -406,6 +432,24 @@ void ChatView::setHasCache(ChatLine* line, bool hasCache) _linesWithCache.remove(line); } +bool ChatView::requestBacklogForScroll() +{ + if (!verticalScrollBar()->isVisible()) { + // Not able to scroll, fetch backlog + // + // 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; + } + else { + // Scrollbar already visible, no backlog requested + return false; + } +} + void ChatView::checkChatLineCaches() { qreal top = mapToScene(viewport()->rect().topLeft()).y() - 10; // some grace area to avoid premature cleaning