diff --git a/src/libs/solutions/terminal/terminalsurface.cpp b/src/libs/solutions/terminal/terminalsurface.cpp index 8ec68f8cfee..0c6d88f62ec 100644 --- a/src/libs/solutions/terminal/terminalsurface.cpp +++ b/src/libs/solutions/terminal/terminalsurface.cpp @@ -281,8 +281,10 @@ struct TerminalSurfacePrivate int sb_pushline(int cols, const VTermScreenCell *cells) { + auto oldSize = m_scrollback->size(); m_scrollback->emplace(cols, cells); - emit q->fullSizeChanged(q->fullSize()); + if (m_scrollback->size() != oldSize) + emit q->fullSizeChanged(q->fullSize()); return 1; } diff --git a/src/libs/solutions/terminal/terminalview.cpp b/src/libs/solutions/terminal/terminalview.cpp index 472346b3fcb..9ac29a271bb 100644 --- a/src/libs/solutions/terminal/terminalview.cpp +++ b/src/libs/solutions/terminal/terminalview.cpp @@ -50,6 +50,9 @@ public: m_flushDelayTimer.setSingleShot(true); m_flushDelayTimer.setInterval(minRefreshInterval); + m_updateTimer.setSingleShot(true); + m_updateTimer.setInterval(minRefreshInterval); + m_scrollTimer.setSingleShot(false); m_scrollTimer.setInterval(500ms); } @@ -73,6 +76,10 @@ public: QTimer m_flushDelayTimer; + QTimer m_updateTimer; + std::optional m_updateRegion; + QElapsedTimer m_sinceLastPaint; + QTimer m_scrollTimer; int m_scrollDirection{0}; @@ -142,6 +149,7 @@ TerminalView::TerminalView(QWidget *parent) setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); connect(&d->m_flushDelayTimer, &QTimer::timeout, this, [this] { flushVTerm(true); }); + connect(&d->m_updateTimer, &QTimer::timeout, this, &TerminalView::scheduleViewportUpdate); connect(&d->m_scrollTimer, &QTimer::timeout, this, [this] { if (d->m_scrollDirection < 0) @@ -920,6 +928,8 @@ void TerminalView::paintEvent(QPaintEvent *event) QToolTip::showText(this->mapToGlobal(QPoint(width() - 200, 0)), QString("Paint: %1ms").arg(t.elapsed())); } + + d->m_sinceLastPaint.start(); } void TerminalView::keyPressEvent(QKeyEvent *event) @@ -1018,17 +1028,39 @@ QPoint TerminalView::toGridPos(QMouseEvent *event) const return globalToGrid(QPointF(event->pos()) + QPointF(0, -topMargin() + 0.5)); } +void TerminalView::scheduleViewportUpdate() +{ + if (!d->m_passwordModeActive && d->m_updateRegion) + viewport()->update(*d->m_updateRegion); + else + viewport()->update(); + + d->m_updateRegion.reset(); +} + void TerminalView::updateViewport() { - viewport()->update(); + updateViewportRect({}); } void TerminalView::updateViewportRect(const QRect &rect) { - if (d->m_passwordModeActive) - viewport()->update(); + if (rect.isEmpty()) + d->m_updateRegion = QRegion{viewport()->rect()}; + else if (!d->m_updateRegion) + d->m_updateRegion = QRegion(rect); else - viewport()->update(rect); + d->m_updateRegion = d->m_updateRegion->united(rect); + + if (d->m_updateTimer.isActive()) + return; + + if (d->m_sinceLastPaint.durationElapsed() < minRefreshInterval) { + d->m_updateTimer.start(); + return; + } + + scheduleViewportUpdate(); } void TerminalView::focusInEvent(QFocusEvent *) diff --git a/src/libs/solutions/terminal/terminalview.h b/src/libs/solutions/terminal/terminalview.h index c69fbcd14e6..6e0c55d06f8 100644 --- a/src/libs/solutions/terminal/terminalview.h +++ b/src/libs/solutions/terminal/terminalview.h @@ -221,6 +221,9 @@ protected: QColor toQColor(std::variant color) const; +private: + void scheduleViewportUpdate(); + private: std::unique_ptr d; };