diff --git a/src/plugins/terminal/scrollback.cpp b/src/plugins/terminal/scrollback.cpp index ca85c942d3d..e22d5fa2436 100644 --- a/src/plugins/terminal/scrollback.cpp +++ b/src/plugins/terminal/scrollback.cpp @@ -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(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(); } diff --git a/src/plugins/terminal/scrollback.h b/src/plugins/terminal/scrollback.h index 356b44fa535..9ca71eec615 100644 --- a/src/plugins/terminal/scrollback.h +++ b/src/plugins/terminal/scrollback.h @@ -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 &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(); diff --git a/src/plugins/terminal/terminalsurface.cpp b/src/plugins/terminal/terminalsurface.cpp index 128c05213d6..83749596c38 100644 --- a/src/plugins/terminal/terminalsurface.cpp +++ b/src/plugins/terminal/terminalsurface.cpp @@ -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 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(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; diff --git a/src/plugins/terminal/terminalsurface.h b/src/plugins/terminal/terminalsurface.h index 04958582c27..01923fb538f 100644 --- a/src/plugins/terminal/terminalsurface.h +++ b/src/plugins/terminal/terminalsurface.h @@ -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 background; + std::variant foregroundColor; + std::variant 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: diff --git a/src/plugins/terminal/terminalwidget.cpp b/src/plugins/terminal/terminalwidget.cpp index e9c86bec886..12d696c69e2 100644 --- a/src/plugins/terminal/terminalwidget.cpp +++ b/src/plugins/terminal/terminalwidget.cpp @@ -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 color) const +{ + if (std::holds_alternative(color)) { + int idx = std::get(color); + if (idx >= 0 && idx < 18) + return m_currentColors[idx]; + + return m_currentColors[Internal::ColorIndex::Background]; + } + return std::get(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(cell.backgroundColor) + && std::get(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; } diff --git a/src/plugins/terminal/terminalwidget.h b/src/plugins/terminal/terminalwidget.h index 34b95a2e2d2..d7aff0648b8 100644 --- a/src/plugins/terminal/terminalwidget.h +++ b/src/plugins/terminal/terminalwidget.h @@ -166,6 +166,8 @@ protected: void configBlinkTimer(); + QColor toQColor(std::variant color) const; + private: std::unique_ptr m_process; std::unique_ptr m_surface;