diff --git a/src/plugins/terminal/terminalsurface.cpp b/src/plugins/terminal/terminalsurface.cpp index eb95215f948..ad47fd8b15b 100644 --- a/src/plugins/terminal/terminalsurface.cpp +++ b/src/plugins/terminal/terminalsurface.cpp @@ -459,9 +459,6 @@ void TerminalSurface::sendKey(QKeyEvent *event) } vterm_keyboard_unichar(d->m_vterm.get(), event->text().toUcs4()[0], VTERM_MOD_NONE); - - // TODO: ?? - //setSelection(std::nullopt); } else if (mod == VTERM_MOD_CTRL && event->key() >= Qt::Key_A && event->key() < Qt::Key_Z) { vterm_keyboard_unichar(d->m_vterm.get(), 'a' + (event->key() - Qt::Key_A), mod); } diff --git a/src/plugins/terminal/terminalwidget.cpp b/src/plugins/terminal/terminalwidget.cpp index b40110e653e..cb8e50166da 100644 --- a/src/plugins/terminal/terminalwidget.cpp +++ b/src/plugins/terminal/terminalwidget.cpp @@ -256,7 +256,12 @@ void TerminalWidget::setupSurface() connect(m_surface.get(), &Internal::TerminalSurface::invalidated, this, - [this](const QRect &rect) { updateViewport(gridToViewport(rect)); }); + [this](const QRect &rect) { + if (setSelection(std::nullopt)) + updateViewport(); + else + updateViewport(gridToViewport(rect)); + }); connect(m_surface.get(), &Internal::TerminalSurface::cursorChanged, this, @@ -430,13 +435,20 @@ void TerminalWidget::flushVTerm(bool force) } } -void TerminalWidget::setSelection(const std::optional &selection) +bool TerminalWidget::setSelection(const std::optional &selection) { if (selection.has_value() != m_selection.has_value()) { qCDebug(selectionLog) << "Copy enabled:" << selection.has_value(); m_copyAction.setEnabled(selection.has_value()); } + + if (selection.has_value() && m_selection.has_value()) { + if (*selection == *m_selection) + return false; + } + m_selection = selection; + return true; } QString TerminalWidget::shellName() const @@ -628,14 +640,31 @@ static void drawTextItemDecoration(QPainter &painter, painter.setBrush(oldBrush); } +void TerminalWidget::paintSelectionOrBackground(QPainter &p, + const Internal::TerminalCell &cell, + const QRectF &cellRect, + const QPoint gridPos) const +{ + bool isInSelection = false; + + if (m_selection) { + const int pos = m_surface->gridToPos(gridPos); + isInSelection = pos >= m_selection->start && pos < m_selection->end; + } + + if (isInSelection) + p.fillRect(cellRect, TerminalSettings::instance().selectionColor.value()); + else if (cell.background) + p.fillRect(cellRect, *cell.background); +} + int TerminalWidget::paintCell(QPainter &p, const QRectF &cellRect, QPoint gridPos, const Internal::TerminalCell &cell, QFont &f) const { - if (cell.background) - p.fillRect(cellRect, *cell.background); + paintSelectionOrBackground(p, cell, cellRect, gridPos); p.setPen(cell.foreground); @@ -759,37 +788,6 @@ void TerminalWidget::paintCells(QPainter &p, QPaintEvent *event) const } } -void TerminalWidget::paintSelection(QPainter &p) const -{ - if (!m_selection) - return; - - const QPoint start = m_surface->posToGrid(m_selection->start); - const QPoint end = m_surface->posToGrid(m_selection->end); - - const QColor selectionColor = TerminalSettings::instance().selectionColor.value(); - const QSize liveSize = m_surface->liveSize(); - - if (start.y() != end.y()) { - QRectF firstLineRect = QRectF(gridToGlobal(start), - gridToGlobal({liveSize.width(), start.y()}, true)); - - p.fillRect(firstLineRect, selectionColor); - - if (end.y() > start.y() + 1) { - QRectF middleRect = QRectF(gridToGlobal({0, (start.y() + 1)}), - gridToGlobal({liveSize.width(), end.y() - 1}, true)); - p.fillRect(middleRect, selectionColor); - } - - QRectF lastLineRect = QRectF(gridToGlobal({0, end.y()}), gridToGlobal(end, true)); - p.fillRect(lastLineRect, selectionColor); - } else { - QRectF rect = QRectF(gridToGlobal(start), gridToGlobal(end, true)); - p.fillRect(rect, selectionColor); - } -} - void TerminalWidget::paintDebugSelection(QPainter &p, const Selection &selection) const { auto s = globalToViewport(gridToGlobal(m_surface->posToGrid(selection.start)).toPoint()); @@ -829,7 +827,6 @@ void TerminalWidget::paintEvent(QPaintEvent *event) p.translate(QPointF{0.0, offset + margin}); - paintSelection(p); paintCells(p, event); paintCursor(p); paintPreedit(p); @@ -878,8 +875,8 @@ void TerminalWidget::keyPressEvent(QKeyEvent *event) } if (actionTriggered) { - setSelection(std::nullopt); - updateViewport(); + if (setSelection(std::nullopt)) + updateViewport(); return; } diff --git a/src/plugins/terminal/terminalwidget.h b/src/plugins/terminal/terminalwidget.h index 6238fac52c7..3e4da77fc18 100644 --- a/src/plugins/terminal/terminalwidget.h +++ b/src/plugins/terminal/terminalwidget.h @@ -56,6 +56,8 @@ public: { return start != other.start || end != other.end; } + + bool operator==(const Selection &other) const { return !operator!=(other); } }; struct LinkSelection : public Selection @@ -111,7 +113,10 @@ protected: void paintCells(QPainter &painter, QPaintEvent *event) const; void paintCursor(QPainter &painter) const; void paintPreedit(QPainter &painter) const; - void paintSelection(QPainter &painter) const; + void paintSelectionOrBackground(QPainter &painter, + const Internal::TerminalCell &cell, + const QRectF &cellRect, + const QPoint gridPos) const; void paintDebugSelection(QPainter &painter, const Selection &selection) const; qreal topMargin() const; @@ -148,7 +153,7 @@ protected: void flushVTerm(bool force); - void setSelection(const std::optional &selection); + bool setSelection(const std::optional &selection); void configBlinkTimer();