forked from qt-creator/qt-creator
Terminal: Fix selections
Selections were invisible if a cell with a background color was selected. Changes to the terminal did not reliably reset the selection. Change-Id: I923223f43e5ee1b6576966f9dd791aa109ac1d5f Reviewed-by: Cristian Adam <cristian.adam@qt.io> Reviewed-by: <github-actions-qt-creator@cristianadam.eu>
This commit is contained in:
@@ -459,9 +459,6 @@ void TerminalSurface::sendKey(QKeyEvent *event)
|
|||||||
}
|
}
|
||||||
|
|
||||||
vterm_keyboard_unichar(d->m_vterm.get(), event->text().toUcs4()[0], VTERM_MOD_NONE);
|
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) {
|
} 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);
|
vterm_keyboard_unichar(d->m_vterm.get(), 'a' + (event->key() - Qt::Key_A), mod);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -256,7 +256,12 @@ void TerminalWidget::setupSurface()
|
|||||||
connect(m_surface.get(),
|
connect(m_surface.get(),
|
||||||
&Internal::TerminalSurface::invalidated,
|
&Internal::TerminalSurface::invalidated,
|
||||||
this,
|
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(),
|
connect(m_surface.get(),
|
||||||
&Internal::TerminalSurface::cursorChanged,
|
&Internal::TerminalSurface::cursorChanged,
|
||||||
this,
|
this,
|
||||||
@@ -430,13 +435,20 @@ void TerminalWidget::flushVTerm(bool force)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TerminalWidget::setSelection(const std::optional<Selection> &selection)
|
bool TerminalWidget::setSelection(const std::optional<Selection> &selection)
|
||||||
{
|
{
|
||||||
if (selection.has_value() != m_selection.has_value()) {
|
if (selection.has_value() != m_selection.has_value()) {
|
||||||
qCDebug(selectionLog) << "Copy enabled:" << selection.has_value();
|
qCDebug(selectionLog) << "Copy enabled:" << selection.has_value();
|
||||||
m_copyAction.setEnabled(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;
|
m_selection = selection;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString TerminalWidget::shellName() const
|
QString TerminalWidget::shellName() const
|
||||||
@@ -628,14 +640,31 @@ static void drawTextItemDecoration(QPainter &painter,
|
|||||||
painter.setBrush(oldBrush);
|
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,
|
int TerminalWidget::paintCell(QPainter &p,
|
||||||
const QRectF &cellRect,
|
const QRectF &cellRect,
|
||||||
QPoint gridPos,
|
QPoint gridPos,
|
||||||
const Internal::TerminalCell &cell,
|
const Internal::TerminalCell &cell,
|
||||||
QFont &f) const
|
QFont &f) const
|
||||||
{
|
{
|
||||||
if (cell.background)
|
paintSelectionOrBackground(p, cell, cellRect, gridPos);
|
||||||
p.fillRect(cellRect, *cell.background);
|
|
||||||
|
|
||||||
p.setPen(cell.foreground);
|
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
|
void TerminalWidget::paintDebugSelection(QPainter &p, const Selection &selection) const
|
||||||
{
|
{
|
||||||
auto s = globalToViewport(gridToGlobal(m_surface->posToGrid(selection.start)).toPoint());
|
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});
|
p.translate(QPointF{0.0, offset + margin});
|
||||||
|
|
||||||
paintSelection(p);
|
|
||||||
paintCells(p, event);
|
paintCells(p, event);
|
||||||
paintCursor(p);
|
paintCursor(p);
|
||||||
paintPreedit(p);
|
paintPreedit(p);
|
||||||
@@ -878,7 +875,7 @@ void TerminalWidget::keyPressEvent(QKeyEvent *event)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (actionTriggered) {
|
if (actionTriggered) {
|
||||||
setSelection(std::nullopt);
|
if (setSelection(std::nullopt))
|
||||||
updateViewport();
|
updateViewport();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -56,6 +56,8 @@ public:
|
|||||||
{
|
{
|
||||||
return start != other.start || end != other.end;
|
return start != other.start || end != other.end;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool operator==(const Selection &other) const { return !operator!=(other); }
|
||||||
};
|
};
|
||||||
|
|
||||||
struct LinkSelection : public Selection
|
struct LinkSelection : public Selection
|
||||||
@@ -111,7 +113,10 @@ protected:
|
|||||||
void paintCells(QPainter &painter, QPaintEvent *event) const;
|
void paintCells(QPainter &painter, QPaintEvent *event) const;
|
||||||
void paintCursor(QPainter &painter) const;
|
void paintCursor(QPainter &painter) const;
|
||||||
void paintPreedit(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;
|
void paintDebugSelection(QPainter &painter, const Selection &selection) const;
|
||||||
|
|
||||||
qreal topMargin() const;
|
qreal topMargin() const;
|
||||||
@@ -148,7 +153,7 @@ protected:
|
|||||||
|
|
||||||
void flushVTerm(bool force);
|
void flushVTerm(bool force);
|
||||||
|
|
||||||
void setSelection(const std::optional<Selection> &selection);
|
bool setSelection(const std::optional<Selection> &selection);
|
||||||
|
|
||||||
void configBlinkTimer();
|
void configBlinkTimer();
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user