aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian Kandeler <christian.kandeler@qt.io>2020-11-26 13:42:02 +0100
committerChristian Kandeler <christian.kandeler@qt.io>2020-11-26 14:24:31 +0000
commit0f3145862479c770ef40b608dc54fd27923e1572 (patch)
treec3160f0f5e8373462751ad2df69bfb9a135057bc
parent596e0c9fcbc3a46da87e1dc9b5778edcf7413821 (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.cpp22
-rw-r--r--src/plugins/coreplugin/outputwindow.h1
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;
};