diff options
author | Christian Kandeler <christian.kandeler@qt.io> | 2020-11-26 13:42:02 +0100 |
---|---|---|
committer | Christian Kandeler <christian.kandeler@qt.io> | 2020-11-26 14:24:31 +0000 |
commit | 0f3145862479c770ef40b608dc54fd27923e1572 (patch) | |
tree | c3160f0f5e8373462751ad2df69bfb9a135057bc | |
parent | 596e0c9fcbc3a46da87e1dc9b5778edcf7413821 (diff) |
Core::OutputWindow: Make auto-scrolling more robust
We relied on the scrollbar position as an invariant, which breaks if the
formatter writes into the text editor directly.
Instead, we update the "auto scroll" flag only if the user actively moves
the scrollbar, which is what the intention was anyway.
Task-number: QTCREATORBUG-24728
Change-Id: Ic747391b3206d6a5ba8eaf4e3cac9a70fed6dfbc
Reviewed-by: Orgad Shaneh <orgads@gmail.com>
-rw-r--r-- | src/plugins/coreplugin/outputwindow.cpp | 22 | ||||
-rw-r--r-- | src/plugins/coreplugin/outputwindow.h | 1 |
2 files changed, 14 insertions, 9 deletions
diff --git a/src/plugins/coreplugin/outputwindow.cpp b/src/plugins/coreplugin/outputwindow.cpp index 4c9b162667..8766305885 100644 --- a/src/plugins/coreplugin/outputwindow.cpp +++ b/src/plugins/coreplugin/outputwindow.cpp @@ -153,6 +153,9 @@ OutputWindow::OutputWindow(Context context, const QString &settingsKey, QWidget EditorManager::openEditorAt(fp.toString(), line, column); }); + connect(verticalScrollBar(), &QAbstractSlider::sliderMoved, + this, &OutputWindow::updateAutoScroll); + undoAction->setEnabled(false); redoAction->setEnabled(false); cutAction->setEnabled(false); @@ -219,9 +222,8 @@ void OutputWindow::resizeEvent(QResizeEvent *e) { //Keep scrollbar at bottom of window while resizing, to ensure we keep scrolling //This can happen if window is resized while building, or if the horizontal scrollbar appears - bool atBottom = isScrollbarAtBottom(); QPlainTextEdit::resizeEvent(e); - if (atBottom) + if (d->scrollToBottom) scrollToBottom(); } @@ -252,7 +254,6 @@ void OutputWindow::showEvent(QShowEvent *e) QPlainTextEdit::showEvent(e); if (d->scrollToBottom) verticalScrollBar()->setValue(verticalScrollBar()->maximum()); - d->scrollToBottom = false; } void OutputWindow::wheelEvent(QWheelEvent *e) @@ -272,6 +273,7 @@ void OutputWindow::wheelEvent(QWheelEvent *e) } } QAbstractScrollArea::wheelEvent(e); + updateAutoScroll(); updateMicroFocus(); } @@ -348,8 +350,6 @@ void OutputWindow::updateFilterProperties( void OutputWindow::filterNewContent() { - bool atBottom = isScrollbarAtBottom(); - QTextBlock lastBlock = document()->findBlockByNumber(d->lastFilteredBlockNumber); if (!lastBlock.isValid()) lastBlock = document()->begin(); @@ -381,7 +381,7 @@ void OutputWindow::filterNewContent() // FIXME: Why on earth is this necessary? We should probably do something else instead... setDocument(document()); - if (atBottom) + if (d->scrollToBottom) scrollToBottom(); } @@ -432,11 +432,9 @@ void OutputWindow::handleOutputChunk(const QString &output, OutputFormat format) } } - const bool atBottom = isScrollbarAtBottom() || d->scrollTimer.isActive(); - d->scrollToBottom = true; d->formatter.appendMessage(out, format); - if (atBottom) { + if (d->scrollToBottom) { if (d->lastMessage.elapsed() < 5) { d->scrollTimer.start(); } else { @@ -449,6 +447,11 @@ void OutputWindow::handleOutputChunk(const QString &output, OutputFormat format) enableUndoRedo(); } +void OutputWindow::updateAutoScroll() +{ + d->scrollToBottom = isScrollbarAtBottom(); +} + void OutputWindow::setMaxCharCount(int count) { d->maxCharCount = count; @@ -505,6 +508,7 @@ QMimeData *OutputWindow::createMimeDataFromSelection() const void OutputWindow::clear() { d->formatter.clear(); + d->scrollToBottom = true; } void OutputWindow::flush() diff --git a/src/plugins/coreplugin/outputwindow.h b/src/plugins/coreplugin/outputwindow.h index c29d1a5a07..de951ded95 100644 --- a/src/plugins/coreplugin/outputwindow.h +++ b/src/plugins/coreplugin/outputwindow.h @@ -109,6 +109,7 @@ private: void filterNewContent(); void handleNextOutputChunk(); void handleOutputChunk(const QString &output, Utils::OutputFormat format); + void updateAutoScroll(); Internal::OutputWindowPrivate *d = nullptr; }; |