forked from qt-creator/qt-creator
Terminal: Move color mapping to widget
This allows us to easily update the view when the colors are changed in the settings. Change-Id: I0b4f150b4fc9cec9aee2796d63f2395e05ce70df Reviewed-by: Cristian Adam <cristian.adam@qt.io>
This commit is contained in:
@@ -10,15 +10,11 @@
|
||||
|
||||
namespace Terminal::Internal {
|
||||
|
||||
Scrollback::Line::Line(int cols, const VTermScreenCell *cells, VTermState *vts)
|
||||
Scrollback::Line::Line(int cols, const VTermScreenCell *cells)
|
||||
: m_cols(cols)
|
||||
, m_cells(std::make_unique<VTermScreenCell[]>(cols))
|
||||
{
|
||||
memcpy(m_cells.get(), cells, cols * sizeof(cells[0]));
|
||||
for (int i = 0; i < cols; ++i) {
|
||||
vterm_state_convert_color_to_rgb(vts, &m_cells[i].fg);
|
||||
vterm_state_convert_color_to_rgb(vts, &m_cells[i].bg);
|
||||
}
|
||||
}
|
||||
|
||||
const VTermScreenCell *Scrollback::Line::cell(int i) const
|
||||
@@ -31,9 +27,9 @@ Scrollback::Scrollback(size_t capacity)
|
||||
: m_capacity(capacity)
|
||||
{}
|
||||
|
||||
void Scrollback::emplace(int cols, const VTermScreenCell *cells, VTermState *vts)
|
||||
void Scrollback::emplace(int cols, const VTermScreenCell *cells)
|
||||
{
|
||||
m_deque.emplace_front(cols, cells, vts);
|
||||
m_deque.emplace_front(cols, cells);
|
||||
while (m_deque.size() > m_capacity) {
|
||||
m_deque.pop_back();
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@ public:
|
||||
class Line
|
||||
{
|
||||
public:
|
||||
Line(int cols, const VTermScreenCell *cells, VTermState *vts);
|
||||
Line(int cols, const VTermScreenCell *cells);
|
||||
Line(Line &&other) = default;
|
||||
Line() = delete;
|
||||
|
||||
@@ -44,9 +44,7 @@ public:
|
||||
const Line &line(size_t index) const { return m_deque.at(index); };
|
||||
const std::deque<Line> &lines() const { return m_deque; };
|
||||
|
||||
void emplace(int cols,
|
||||
const VTermScreenCell *cells,
|
||||
VTermState *vts);
|
||||
void emplace(int cols, const VTermScreenCell *cells);
|
||||
void popto(int cols, VTermScreenCell *cells);
|
||||
|
||||
void clear();
|
||||
|
||||
@@ -89,6 +89,18 @@ struct TerminalSurfacePrivate
|
||||
vterm_state_set_unrecognised_fallbacks(vts, &m_vtermStateFallbacks, this);
|
||||
vterm_state_set_bold_highbright(vts, true);
|
||||
|
||||
VTermColor fg;
|
||||
VTermColor bg;
|
||||
vterm_color_indexed(&fg, ColorIndex::Foreground);
|
||||
vterm_color_indexed(&bg, ColorIndex::Background);
|
||||
vterm_state_set_default_colors(vts, &fg, &bg);
|
||||
|
||||
for (int i = 0; i < 16; ++i) {
|
||||
VTermColor col;
|
||||
vterm_color_indexed(&col, i);
|
||||
vterm_state_set_palette_color(vts, i, &col);
|
||||
}
|
||||
|
||||
vterm_screen_reset(m_vtermScreen, 1);
|
||||
}
|
||||
|
||||
@@ -101,6 +113,25 @@ struct TerminalSurfacePrivate
|
||||
return QSize(cols, rows);
|
||||
}
|
||||
|
||||
std::variant<int, QColor> toVariantColor(const VTermColor &color)
|
||||
{
|
||||
if (color.type & VTERM_COLOR_DEFAULT_BG)
|
||||
return ColorIndex::Background;
|
||||
else if (color.type & VTERM_COLOR_DEFAULT_FG)
|
||||
return ColorIndex::Foreground;
|
||||
else if (color.type & VTERM_COLOR_INDEXED) {
|
||||
if (color.indexed.idx >= 16) {
|
||||
VTermColor c = color;
|
||||
vterm_state_convert_color_to_rgb(vterm_obtain_state(m_vterm.get()), &c);
|
||||
return toQColor(c);
|
||||
}
|
||||
return color.indexed.idx;
|
||||
} else if (color.type == VTERM_COLOR_RGB)
|
||||
return toQColor(color);
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
TerminalCell toCell(const VTermScreenCell &cell)
|
||||
{
|
||||
TerminalCell result;
|
||||
@@ -113,13 +144,8 @@ struct TerminalSurfacePrivate
|
||||
if (static_cast<bool>(cell.attrs.reverse))
|
||||
std::swap(fg, bg);
|
||||
|
||||
const QColor cellBgColor = toQColor(*bg);
|
||||
const QColor cellFgColor = toQColor(*fg);
|
||||
|
||||
if (cellBgColor != m_defaultBgColor)
|
||||
result.background = toQColor(*bg);
|
||||
|
||||
result.foreground = cellFgColor;
|
||||
result.backgroundColor = toVariantColor(*bg);
|
||||
result.foregroundColor = toVariantColor(*fg);
|
||||
|
||||
result.bold = cell.attrs.bold;
|
||||
result.strikeOut = cell.attrs.strike;
|
||||
@@ -151,26 +177,6 @@ struct TerminalSurfacePrivate
|
||||
return result;
|
||||
}
|
||||
|
||||
VTermColor defaultBgColor() const
|
||||
{
|
||||
VTermColor defaultBg;
|
||||
if (!m_altscreen) {
|
||||
VTermColor defaultFg;
|
||||
vterm_state_get_default_colors(vterm_obtain_state(m_vterm.get()),
|
||||
&defaultFg,
|
||||
&defaultBg);
|
||||
// We want to compare the cell bg against this later and cells don't
|
||||
// set DEFAULT_BG
|
||||
defaultBg.type = VTERM_COLOR_RGB;
|
||||
return defaultBg;
|
||||
} // This is a slightly better guess when in an altscreen
|
||||
|
||||
VTermPos vtp{0, 0};
|
||||
static VTermScreenCell refCell{};
|
||||
vterm_screen_get_cell(m_vtermScreen, vtp, &refCell);
|
||||
return refCell.bg;
|
||||
}
|
||||
|
||||
// Callbacks from vterm
|
||||
void invalidate(VTermRect rect)
|
||||
{
|
||||
@@ -185,7 +191,7 @@ struct TerminalSurfacePrivate
|
||||
|
||||
int sb_pushline(int cols, const VTermScreenCell *cells)
|
||||
{
|
||||
m_scrollback->emplace(cols, cells, vterm_obtain_state(m_vterm.get()));
|
||||
m_scrollback->emplace(cols, cells);
|
||||
emit q->fullSizeChanged(q->fullSize());
|
||||
return 1;
|
||||
}
|
||||
@@ -284,8 +290,6 @@ struct TerminalSurfacePrivate
|
||||
static VTermScreenCell refCell{};
|
||||
VTermPos vtp{y, x};
|
||||
vterm_screen_get_cell(m_vtermScreen, vtp, &refCell);
|
||||
vterm_screen_convert_color_to_rgb(m_vtermScreen, &refCell.fg);
|
||||
vterm_screen_convert_color_to_rgb(m_vtermScreen, &refCell.bg);
|
||||
|
||||
return &refCell;
|
||||
}
|
||||
@@ -295,7 +299,6 @@ struct TerminalSurfacePrivate
|
||||
VTermScreenCallbacks m_vtermScreenCallbacks;
|
||||
VTermStateFallbacks m_vtermStateFallbacks;
|
||||
|
||||
QColor m_defaultBgColor;
|
||||
Cursor m_cursor;
|
||||
QString m_currentCommand;
|
||||
|
||||
@@ -352,8 +355,14 @@ std::u32string::value_type TerminalSurface::fetchCharAt(int x, int y) const
|
||||
|
||||
TerminalCell TerminalSurface::fetchCell(int x, int y) const
|
||||
{
|
||||
static TerminalCell
|
||||
emptyCell{1, {}, {}, false, {}, std::nullopt, QTextCharFormat::NoUnderline, false};
|
||||
static TerminalCell emptyCell{1,
|
||||
{},
|
||||
{},
|
||||
false,
|
||||
ColorIndex::Foreground,
|
||||
ColorIndex::Background,
|
||||
QTextCharFormat::NoUnderline,
|
||||
false};
|
||||
|
||||
QTC_ASSERT(y >= 0, return emptyCell);
|
||||
QTC_ASSERT(y < fullSize().height() && x < fullSize().width(), return emptyCell);
|
||||
@@ -400,33 +409,6 @@ void TerminalSurface::flush()
|
||||
vterm_screen_flush_damage(d->m_vtermScreen);
|
||||
}
|
||||
|
||||
void TerminalSurface::setColors(QColor foreground, QColor background)
|
||||
{
|
||||
VTermState *vts = vterm_obtain_state(d->m_vterm.get());
|
||||
|
||||
VTermColor fg;
|
||||
VTermColor bg;
|
||||
|
||||
vterm_color_rgb(&fg, foreground.red(), foreground.green(), foreground.blue());
|
||||
vterm_color_rgb(&bg, background.red(), background.green(), background.blue());
|
||||
|
||||
d->m_defaultBgColor = background;
|
||||
|
||||
vterm_state_set_default_colors(vts, &fg, &bg);
|
||||
vterm_screen_reset(d->m_vtermScreen, 1);
|
||||
}
|
||||
|
||||
void TerminalSurface::setAnsiColor(int index, QColor color)
|
||||
{
|
||||
VTermState *vts = vterm_obtain_state(d->m_vterm.get());
|
||||
|
||||
VTermColor col;
|
||||
vterm_color_rgb(&col, color.red(), color.green(), color.blue());
|
||||
vterm_state_set_palette_color(vts, index, &col);
|
||||
|
||||
vterm_screen_reset(d->m_vtermScreen, 1);
|
||||
}
|
||||
|
||||
void TerminalSurface::pasteFromClipboard(const QString &clipboardText)
|
||||
{
|
||||
if (clipboardText.isEmpty())
|
||||
@@ -496,11 +478,6 @@ Cursor TerminalSurface::cursor() const
|
||||
return cursor;
|
||||
}
|
||||
|
||||
QColor TerminalSurface::defaultBgColor() const
|
||||
{
|
||||
return toQColor(d->defaultBgColor());
|
||||
}
|
||||
|
||||
ShellIntegration *TerminalSurface::shellIntegration() const
|
||||
{
|
||||
return d->m_shellIntegration;
|
||||
|
||||
@@ -18,14 +18,16 @@ class Scrollback;
|
||||
|
||||
struct TerminalSurfacePrivate;
|
||||
|
||||
enum ColorIndex { Foreground = 16, Background = 17 };
|
||||
|
||||
struct TerminalCell
|
||||
{
|
||||
int width;
|
||||
QString text;
|
||||
bool bold{false};
|
||||
bool italic{false};
|
||||
QColor foreground;
|
||||
std::optional<QColor> background;
|
||||
std::variant<int, QColor> foregroundColor;
|
||||
std::variant<int, QColor> backgroundColor;
|
||||
QTextCharFormat::UnderlineStyle underlineStyle{QTextCharFormat::NoUnderline};
|
||||
bool strikeOut{false};
|
||||
};
|
||||
@@ -81,9 +83,6 @@ public:
|
||||
void dataFromPty(const QByteArray &data);
|
||||
void flush();
|
||||
|
||||
void setColors(QColor foreground, QColor background);
|
||||
void setAnsiColor(int index, QColor color);
|
||||
|
||||
void pasteFromClipboard(const QString &text);
|
||||
|
||||
void sendKey(Qt::Key key);
|
||||
@@ -94,8 +93,6 @@ public:
|
||||
|
||||
Cursor cursor() const;
|
||||
|
||||
QColor defaultBgColor() const;
|
||||
|
||||
ShellIntegration *shellIntegration() const;
|
||||
|
||||
signals:
|
||||
|
||||
@@ -218,14 +218,8 @@ void TerminalWidget::setupColors()
|
||||
|
||||
m_currentColors = newColors;
|
||||
|
||||
m_surface->setColors(TerminalSettings::instance().foregroundColor.value(),
|
||||
TerminalSettings::instance().backgroundColor.value());
|
||||
|
||||
for (int i = 0; i < 16; ++i) {
|
||||
m_surface->setAnsiColor(i, TerminalSettings::instance().colors[i].value());
|
||||
}
|
||||
|
||||
clearContents();
|
||||
updateViewport();
|
||||
update();
|
||||
}
|
||||
|
||||
void TerminalWidget::setupActions()
|
||||
@@ -336,6 +330,18 @@ void TerminalWidget::configBlinkTimer()
|
||||
}
|
||||
}
|
||||
|
||||
QColor TerminalWidget::toQColor(std::variant<int, QColor> color) const
|
||||
{
|
||||
if (std::holds_alternative<int>(color)) {
|
||||
int idx = std::get<int>(color);
|
||||
if (idx >= 0 && idx < 18)
|
||||
return m_currentColors[idx];
|
||||
|
||||
return m_currentColors[Internal::ColorIndex::Background];
|
||||
}
|
||||
return std::get<QColor>(color);
|
||||
}
|
||||
|
||||
void TerminalWidget::setFont(const QFont &font)
|
||||
{
|
||||
m_font = font;
|
||||
@@ -747,8 +753,9 @@ void TerminalWidget::paintSelectionOrBackground(QPainter &p,
|
||||
|
||||
if (isInSelection)
|
||||
p.fillRect(cellRect, TerminalSettings::instance().selectionColor.value());
|
||||
else if (cell.background)
|
||||
p.fillRect(cellRect, *cell.background);
|
||||
else if (!(std::holds_alternative<int>(cell.backgroundColor)
|
||||
&& std::get<int>(cell.backgroundColor) == 17))
|
||||
p.fillRect(cellRect, toQColor(cell.backgroundColor));
|
||||
}
|
||||
|
||||
int TerminalWidget::paintCell(QPainter &p,
|
||||
@@ -759,7 +766,7 @@ int TerminalWidget::paintCell(QPainter &p,
|
||||
{
|
||||
paintSelectionOrBackground(p, cell, cellRect, gridPos);
|
||||
|
||||
p.setPen(cell.foreground);
|
||||
p.setPen(toQColor(cell.foregroundColor));
|
||||
|
||||
f.setBold(cell.bold);
|
||||
f.setItalic(cell.italic);
|
||||
@@ -909,12 +916,10 @@ void TerminalWidget::paintEvent(QPaintEvent *event)
|
||||
|
||||
p.save();
|
||||
|
||||
const QColor defaultBgColor = m_surface->defaultBgColor();
|
||||
|
||||
if (paintLog().isDebugEnabled())
|
||||
p.fillRect(event->rect(), QColor::fromRgb(rand() % 60, rand() % 60, rand() % 60));
|
||||
else
|
||||
p.fillRect(event->rect(), defaultBgColor);
|
||||
p.fillRect(event->rect(), m_currentColors[Internal::ColorIndex::Background]);
|
||||
|
||||
int scrollOffset = verticalScrollBar()->value();
|
||||
int offset = -(scrollOffset * m_cellSize.height());
|
||||
@@ -929,7 +934,8 @@ void TerminalWidget::paintEvent(QPaintEvent *event)
|
||||
|
||||
p.restore();
|
||||
|
||||
p.fillRect(QRectF{{0, 0}, QSizeF{(qreal) width(), topMargin()}}, defaultBgColor);
|
||||
p.fillRect(QRectF{{0, 0}, QSizeF{(qreal) width(), topMargin()}},
|
||||
m_currentColors[Internal::ColorIndex::Background]);
|
||||
|
||||
if (selectionLog().isDebugEnabled()) {
|
||||
if (m_selection)
|
||||
@@ -1295,8 +1301,7 @@ bool TerminalWidget::event(QEvent *event)
|
||||
|
||||
if (event->type() == QEvent::Paint) {
|
||||
QPainter p(this);
|
||||
p.fillRect(QRect(QPoint(0, 0), size()),
|
||||
TerminalSettings::instance().backgroundColor.value());
|
||||
p.fillRect(QRect(QPoint(0, 0), size()), m_currentColors[Internal::ColorIndex::Background]);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -166,6 +166,8 @@ protected:
|
||||
|
||||
void configBlinkTimer();
|
||||
|
||||
QColor toQColor(std::variant<int, QColor> color) const;
|
||||
|
||||
private:
|
||||
std::unique_ptr<Utils::QtcProcess> m_process;
|
||||
std::unique_ptr<Internal::TerminalSurface> m_surface;
|
||||
|
||||
Reference in New Issue
Block a user