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 {
|
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_cols(cols)
|
||||||
, m_cells(std::make_unique<VTermScreenCell[]>(cols))
|
, m_cells(std::make_unique<VTermScreenCell[]>(cols))
|
||||||
{
|
{
|
||||||
memcpy(m_cells.get(), cells, cols * sizeof(cells[0]));
|
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
|
const VTermScreenCell *Scrollback::Line::cell(int i) const
|
||||||
@@ -31,9 +27,9 @@ Scrollback::Scrollback(size_t capacity)
|
|||||||
: m_capacity(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) {
|
while (m_deque.size() > m_capacity) {
|
||||||
m_deque.pop_back();
|
m_deque.pop_back();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ public:
|
|||||||
class Line
|
class Line
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Line(int cols, const VTermScreenCell *cells, VTermState *vts);
|
Line(int cols, const VTermScreenCell *cells);
|
||||||
Line(Line &&other) = default;
|
Line(Line &&other) = default;
|
||||||
Line() = delete;
|
Line() = delete;
|
||||||
|
|
||||||
@@ -44,9 +44,7 @@ public:
|
|||||||
const Line &line(size_t index) const { return m_deque.at(index); };
|
const Line &line(size_t index) const { return m_deque.at(index); };
|
||||||
const std::deque<Line> &lines() const { return m_deque; };
|
const std::deque<Line> &lines() const { return m_deque; };
|
||||||
|
|
||||||
void emplace(int cols,
|
void emplace(int cols, const VTermScreenCell *cells);
|
||||||
const VTermScreenCell *cells,
|
|
||||||
VTermState *vts);
|
|
||||||
void popto(int cols, VTermScreenCell *cells);
|
void popto(int cols, VTermScreenCell *cells);
|
||||||
|
|
||||||
void clear();
|
void clear();
|
||||||
|
|||||||
@@ -89,6 +89,18 @@ struct TerminalSurfacePrivate
|
|||||||
vterm_state_set_unrecognised_fallbacks(vts, &m_vtermStateFallbacks, this);
|
vterm_state_set_unrecognised_fallbacks(vts, &m_vtermStateFallbacks, this);
|
||||||
vterm_state_set_bold_highbright(vts, true);
|
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);
|
vterm_screen_reset(m_vtermScreen, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -101,6 +113,25 @@ struct TerminalSurfacePrivate
|
|||||||
return QSize(cols, rows);
|
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 toCell(const VTermScreenCell &cell)
|
||||||
{
|
{
|
||||||
TerminalCell result;
|
TerminalCell result;
|
||||||
@@ -113,13 +144,8 @@ struct TerminalSurfacePrivate
|
|||||||
if (static_cast<bool>(cell.attrs.reverse))
|
if (static_cast<bool>(cell.attrs.reverse))
|
||||||
std::swap(fg, bg);
|
std::swap(fg, bg);
|
||||||
|
|
||||||
const QColor cellBgColor = toQColor(*bg);
|
result.backgroundColor = toVariantColor(*bg);
|
||||||
const QColor cellFgColor = toQColor(*fg);
|
result.foregroundColor = toVariantColor(*fg);
|
||||||
|
|
||||||
if (cellBgColor != m_defaultBgColor)
|
|
||||||
result.background = toQColor(*bg);
|
|
||||||
|
|
||||||
result.foreground = cellFgColor;
|
|
||||||
|
|
||||||
result.bold = cell.attrs.bold;
|
result.bold = cell.attrs.bold;
|
||||||
result.strikeOut = cell.attrs.strike;
|
result.strikeOut = cell.attrs.strike;
|
||||||
@@ -151,26 +177,6 @@ struct TerminalSurfacePrivate
|
|||||||
return result;
|
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
|
// Callbacks from vterm
|
||||||
void invalidate(VTermRect rect)
|
void invalidate(VTermRect rect)
|
||||||
{
|
{
|
||||||
@@ -185,7 +191,7 @@ struct TerminalSurfacePrivate
|
|||||||
|
|
||||||
int sb_pushline(int cols, const VTermScreenCell *cells)
|
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());
|
emit q->fullSizeChanged(q->fullSize());
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@@ -284,8 +290,6 @@ struct TerminalSurfacePrivate
|
|||||||
static VTermScreenCell refCell{};
|
static VTermScreenCell refCell{};
|
||||||
VTermPos vtp{y, x};
|
VTermPos vtp{y, x};
|
||||||
vterm_screen_get_cell(m_vtermScreen, vtp, &refCell);
|
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;
|
return &refCell;
|
||||||
}
|
}
|
||||||
@@ -295,7 +299,6 @@ struct TerminalSurfacePrivate
|
|||||||
VTermScreenCallbacks m_vtermScreenCallbacks;
|
VTermScreenCallbacks m_vtermScreenCallbacks;
|
||||||
VTermStateFallbacks m_vtermStateFallbacks;
|
VTermStateFallbacks m_vtermStateFallbacks;
|
||||||
|
|
||||||
QColor m_defaultBgColor;
|
|
||||||
Cursor m_cursor;
|
Cursor m_cursor;
|
||||||
QString m_currentCommand;
|
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
|
TerminalCell TerminalSurface::fetchCell(int x, int y) const
|
||||||
{
|
{
|
||||||
static TerminalCell
|
static TerminalCell emptyCell{1,
|
||||||
emptyCell{1, {}, {}, false, {}, std::nullopt, QTextCharFormat::NoUnderline, false};
|
{},
|
||||||
|
{},
|
||||||
|
false,
|
||||||
|
ColorIndex::Foreground,
|
||||||
|
ColorIndex::Background,
|
||||||
|
QTextCharFormat::NoUnderline,
|
||||||
|
false};
|
||||||
|
|
||||||
QTC_ASSERT(y >= 0, return emptyCell);
|
QTC_ASSERT(y >= 0, return emptyCell);
|
||||||
QTC_ASSERT(y < fullSize().height() && x < fullSize().width(), 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);
|
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)
|
void TerminalSurface::pasteFromClipboard(const QString &clipboardText)
|
||||||
{
|
{
|
||||||
if (clipboardText.isEmpty())
|
if (clipboardText.isEmpty())
|
||||||
@@ -496,11 +478,6 @@ Cursor TerminalSurface::cursor() const
|
|||||||
return cursor;
|
return cursor;
|
||||||
}
|
}
|
||||||
|
|
||||||
QColor TerminalSurface::defaultBgColor() const
|
|
||||||
{
|
|
||||||
return toQColor(d->defaultBgColor());
|
|
||||||
}
|
|
||||||
|
|
||||||
ShellIntegration *TerminalSurface::shellIntegration() const
|
ShellIntegration *TerminalSurface::shellIntegration() const
|
||||||
{
|
{
|
||||||
return d->m_shellIntegration;
|
return d->m_shellIntegration;
|
||||||
|
|||||||
@@ -18,14 +18,16 @@ class Scrollback;
|
|||||||
|
|
||||||
struct TerminalSurfacePrivate;
|
struct TerminalSurfacePrivate;
|
||||||
|
|
||||||
|
enum ColorIndex { Foreground = 16, Background = 17 };
|
||||||
|
|
||||||
struct TerminalCell
|
struct TerminalCell
|
||||||
{
|
{
|
||||||
int width;
|
int width;
|
||||||
QString text;
|
QString text;
|
||||||
bool bold{false};
|
bool bold{false};
|
||||||
bool italic{false};
|
bool italic{false};
|
||||||
QColor foreground;
|
std::variant<int, QColor> foregroundColor;
|
||||||
std::optional<QColor> background;
|
std::variant<int, QColor> backgroundColor;
|
||||||
QTextCharFormat::UnderlineStyle underlineStyle{QTextCharFormat::NoUnderline};
|
QTextCharFormat::UnderlineStyle underlineStyle{QTextCharFormat::NoUnderline};
|
||||||
bool strikeOut{false};
|
bool strikeOut{false};
|
||||||
};
|
};
|
||||||
@@ -81,9 +83,6 @@ public:
|
|||||||
void dataFromPty(const QByteArray &data);
|
void dataFromPty(const QByteArray &data);
|
||||||
void flush();
|
void flush();
|
||||||
|
|
||||||
void setColors(QColor foreground, QColor background);
|
|
||||||
void setAnsiColor(int index, QColor color);
|
|
||||||
|
|
||||||
void pasteFromClipboard(const QString &text);
|
void pasteFromClipboard(const QString &text);
|
||||||
|
|
||||||
void sendKey(Qt::Key key);
|
void sendKey(Qt::Key key);
|
||||||
@@ -94,8 +93,6 @@ public:
|
|||||||
|
|
||||||
Cursor cursor() const;
|
Cursor cursor() const;
|
||||||
|
|
||||||
QColor defaultBgColor() const;
|
|
||||||
|
|
||||||
ShellIntegration *shellIntegration() const;
|
ShellIntegration *shellIntegration() const;
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
|||||||
@@ -218,14 +218,8 @@ void TerminalWidget::setupColors()
|
|||||||
|
|
||||||
m_currentColors = newColors;
|
m_currentColors = newColors;
|
||||||
|
|
||||||
m_surface->setColors(TerminalSettings::instance().foregroundColor.value(),
|
updateViewport();
|
||||||
TerminalSettings::instance().backgroundColor.value());
|
update();
|
||||||
|
|
||||||
for (int i = 0; i < 16; ++i) {
|
|
||||||
m_surface->setAnsiColor(i, TerminalSettings::instance().colors[i].value());
|
|
||||||
}
|
|
||||||
|
|
||||||
clearContents();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void TerminalWidget::setupActions()
|
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)
|
void TerminalWidget::setFont(const QFont &font)
|
||||||
{
|
{
|
||||||
m_font = font;
|
m_font = font;
|
||||||
@@ -747,8 +753,9 @@ void TerminalWidget::paintSelectionOrBackground(QPainter &p,
|
|||||||
|
|
||||||
if (isInSelection)
|
if (isInSelection)
|
||||||
p.fillRect(cellRect, TerminalSettings::instance().selectionColor.value());
|
p.fillRect(cellRect, TerminalSettings::instance().selectionColor.value());
|
||||||
else if (cell.background)
|
else if (!(std::holds_alternative<int>(cell.backgroundColor)
|
||||||
p.fillRect(cellRect, *cell.background);
|
&& std::get<int>(cell.backgroundColor) == 17))
|
||||||
|
p.fillRect(cellRect, toQColor(cell.backgroundColor));
|
||||||
}
|
}
|
||||||
|
|
||||||
int TerminalWidget::paintCell(QPainter &p,
|
int TerminalWidget::paintCell(QPainter &p,
|
||||||
@@ -759,7 +766,7 @@ int TerminalWidget::paintCell(QPainter &p,
|
|||||||
{
|
{
|
||||||
paintSelectionOrBackground(p, cell, cellRect, gridPos);
|
paintSelectionOrBackground(p, cell, cellRect, gridPos);
|
||||||
|
|
||||||
p.setPen(cell.foreground);
|
p.setPen(toQColor(cell.foregroundColor));
|
||||||
|
|
||||||
f.setBold(cell.bold);
|
f.setBold(cell.bold);
|
||||||
f.setItalic(cell.italic);
|
f.setItalic(cell.italic);
|
||||||
@@ -909,12 +916,10 @@ void TerminalWidget::paintEvent(QPaintEvent *event)
|
|||||||
|
|
||||||
p.save();
|
p.save();
|
||||||
|
|
||||||
const QColor defaultBgColor = m_surface->defaultBgColor();
|
|
||||||
|
|
||||||
if (paintLog().isDebugEnabled())
|
if (paintLog().isDebugEnabled())
|
||||||
p.fillRect(event->rect(), QColor::fromRgb(rand() % 60, rand() % 60, rand() % 60));
|
p.fillRect(event->rect(), QColor::fromRgb(rand() % 60, rand() % 60, rand() % 60));
|
||||||
else
|
else
|
||||||
p.fillRect(event->rect(), defaultBgColor);
|
p.fillRect(event->rect(), m_currentColors[Internal::ColorIndex::Background]);
|
||||||
|
|
||||||
int scrollOffset = verticalScrollBar()->value();
|
int scrollOffset = verticalScrollBar()->value();
|
||||||
int offset = -(scrollOffset * m_cellSize.height());
|
int offset = -(scrollOffset * m_cellSize.height());
|
||||||
@@ -929,7 +934,8 @@ void TerminalWidget::paintEvent(QPaintEvent *event)
|
|||||||
|
|
||||||
p.restore();
|
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 (selectionLog().isDebugEnabled()) {
|
||||||
if (m_selection)
|
if (m_selection)
|
||||||
@@ -1295,8 +1301,7 @@ bool TerminalWidget::event(QEvent *event)
|
|||||||
|
|
||||||
if (event->type() == QEvent::Paint) {
|
if (event->type() == QEvent::Paint) {
|
||||||
QPainter p(this);
|
QPainter p(this);
|
||||||
p.fillRect(QRect(QPoint(0, 0), size()),
|
p.fillRect(QRect(QPoint(0, 0), size()), m_currentColors[Internal::ColorIndex::Background]);
|
||||||
TerminalSettings::instance().backgroundColor.value());
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -166,6 +166,8 @@ protected:
|
|||||||
|
|
||||||
void configBlinkTimer();
|
void configBlinkTimer();
|
||||||
|
|
||||||
|
QColor toQColor(std::variant<int, QColor> color) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::unique_ptr<Utils::QtcProcess> m_process;
|
std::unique_ptr<Utils::QtcProcess> m_process;
|
||||||
std::unique_ptr<Internal::TerminalSurface> m_surface;
|
std::unique_ptr<Internal::TerminalSurface> m_surface;
|
||||||
|
|||||||
Reference in New Issue
Block a user