forked from qt-creator/qt-creator
Terminal: Improve performance for cat /dev/random
Change-Id: Ibc7e09dd9388fd6f06f0bed3ade4e83d05f03c28 Reviewed-by: Cristian Adam <cristian.adam@qt.io>
This commit is contained in:
@@ -20,7 +20,6 @@ Scrollback::Line::Line(int cols, const VTermScreenCell *cells, VTermState *vts)
|
|||||||
vterm_state_convert_color_to_rgb(vts, &m_cells[i].fg);
|
vterm_state_convert_color_to_rgb(vts, &m_cells[i].fg);
|
||||||
vterm_state_convert_color_to_rgb(vts, &m_cells[i].bg);
|
vterm_state_convert_color_to_rgb(vts, &m_cells[i].bg);
|
||||||
}
|
}
|
||||||
m_layout = std::make_unique<QTextLayout>();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const VTermScreenCell *Scrollback::Line::cell(int i) const
|
const VTermScreenCell *Scrollback::Line::cell(int i) const
|
||||||
@@ -31,6 +30,9 @@ const VTermScreenCell *Scrollback::Line::cell(int i) const
|
|||||||
|
|
||||||
const QTextLayout &Scrollback::Line::layout(int version, const QFont &font, qreal lineSpacing) const
|
const QTextLayout &Scrollback::Line::layout(int version, const QFont &font, qreal lineSpacing) const
|
||||||
{
|
{
|
||||||
|
if (!m_layout)
|
||||||
|
m_layout = std::make_unique<QTextLayout>();
|
||||||
|
|
||||||
if (m_layoutVersion != version) {
|
if (m_layoutVersion != version) {
|
||||||
QString text;
|
QString text;
|
||||||
VTermColor defaultBg;
|
VTermColor defaultBg;
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ public:
|
|||||||
private:
|
private:
|
||||||
int m_cols;
|
int m_cols;
|
||||||
std::unique_ptr<VTermScreenCell[]> m_cells;
|
std::unique_ptr<VTermScreenCell[]> m_cells;
|
||||||
std::unique_ptr<QTextLayout> m_layout;
|
mutable std::unique_ptr<QTextLayout> m_layout;
|
||||||
mutable int m_layoutVersion{-1};
|
mutable int m_layoutVersion{-1};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -29,6 +29,8 @@
|
|||||||
#include <QScrollBar>
|
#include <QScrollBar>
|
||||||
#include <QTextLayout>
|
#include <QTextLayout>
|
||||||
|
|
||||||
|
#include <chrono>
|
||||||
|
|
||||||
Q_LOGGING_CATEGORY(terminalLog, "qtc.terminal", QtWarningMsg)
|
Q_LOGGING_CATEGORY(terminalLog, "qtc.terminal", QtWarningMsg)
|
||||||
|
|
||||||
using namespace Utils;
|
using namespace Utils;
|
||||||
@@ -36,6 +38,11 @@ using namespace Utils::Terminal;
|
|||||||
|
|
||||||
namespace Terminal {
|
namespace Terminal {
|
||||||
|
|
||||||
|
using namespace std::chrono_literals;
|
||||||
|
|
||||||
|
// Minimum time between two refreshes.
|
||||||
|
static const auto minRefreshInterval = 16ms;
|
||||||
|
|
||||||
TerminalWidget::TerminalWidget(QWidget *parent, const OpenTerminalParameters &openParameters)
|
TerminalWidget::TerminalWidget(QWidget *parent, const OpenTerminalParameters &openParameters)
|
||||||
: QAbstractScrollArea(parent)
|
: QAbstractScrollArea(parent)
|
||||||
, m_vterm(vterm_new(size().height(), size().width()), vterm_free)
|
, m_vterm(vterm_new(size().height(), size().width()), vterm_free)
|
||||||
@@ -47,6 +54,7 @@ TerminalWidget::TerminalWidget(QWidget *parent, const OpenTerminalParameters &op
|
|||||||
, m_zoomInAction(Tr::tr("Zoom In"))
|
, m_zoomInAction(Tr::tr("Zoom In"))
|
||||||
, m_zoomOutAction(Tr::tr("Zoom Out"))
|
, m_zoomOutAction(Tr::tr("Zoom Out"))
|
||||||
, m_openParameters(openParameters)
|
, m_openParameters(openParameters)
|
||||||
|
, m_lastFlush(QDateTime::currentDateTime())
|
||||||
{
|
{
|
||||||
setupVTerm();
|
setupVTerm();
|
||||||
setupFont();
|
setupFont();
|
||||||
@@ -66,13 +74,10 @@ TerminalWidget::TerminalWidget(QWidget *parent, const OpenTerminalParameters &op
|
|||||||
|
|
||||||
setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
|
setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
|
||||||
|
|
||||||
m_readDelayTimer.setSingleShot(true);
|
m_flushDelayTimer.setSingleShot(true);
|
||||||
m_readDelayTimer.setInterval(10);
|
m_flushDelayTimer.setInterval(minRefreshInterval);
|
||||||
|
|
||||||
connect(&m_readDelayTimer, &QTimer::timeout, this, [this] {
|
connect(&m_flushDelayTimer, &QTimer::timeout, this, [this]() { flushVTerm(true); });
|
||||||
m_readDelayRestarts = 0;
|
|
||||||
onReadyRead();
|
|
||||||
});
|
|
||||||
|
|
||||||
connect(&m_copyAction, &QAction::triggered, this, &TerminalWidget::copyToClipboard);
|
connect(&m_copyAction, &QAction::triggered, this, &TerminalWidget::copyToClipboard);
|
||||||
connect(&m_pasteAction, &QAction::triggered, this, &TerminalWidget::pasteFromClipboard);
|
connect(&m_pasteAction, &QAction::triggered, this, &TerminalWidget::pasteFromClipboard);
|
||||||
@@ -109,14 +114,8 @@ void TerminalWidget::setupPty()
|
|||||||
m_process->setWorkingDirectory(*m_openParameters.workingDirectory);
|
m_process->setWorkingDirectory(*m_openParameters.workingDirectory);
|
||||||
m_process->setEnvironment(env);
|
m_process->setEnvironment(env);
|
||||||
|
|
||||||
connect(m_process.get(), &QtcProcess::readyReadStandardOutput, this, [this] {
|
connect(m_process.get(), &QtcProcess::readyReadStandardOutput, this, [this]() {
|
||||||
if (m_readDelayTimer.isActive())
|
onReadyRead(false);
|
||||||
m_readDelayRestarts++;
|
|
||||||
|
|
||||||
if (m_readDelayRestarts > 100)
|
|
||||||
return;
|
|
||||||
|
|
||||||
m_readDelayTimer.start();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
connect(m_process.get(), &QtcProcess::done, this, [this] {
|
connect(m_process.get(), &QtcProcess::done, this, [this] {
|
||||||
@@ -138,7 +137,9 @@ void TerminalWidget::setupPty()
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (m_openParameters.m_exitBehavior == ExitBehavior::Restart) {
|
if (m_openParameters.m_exitBehavior == ExitBehavior::Restart) {
|
||||||
QMetaObject::invokeMethod(this, [this] {
|
QMetaObject::invokeMethod(
|
||||||
|
this,
|
||||||
|
[this] {
|
||||||
m_process.reset();
|
m_process.reset();
|
||||||
setupPty();
|
setupPty();
|
||||||
},
|
},
|
||||||
@@ -411,17 +412,29 @@ void TerminalWidget::clearContents()
|
|||||||
// Fake a scrollback clearing
|
// Fake a scrollback clearing
|
||||||
QByteArray data{"\x1b[3J"};
|
QByteArray data{"\x1b[3J"};
|
||||||
vterm_input_write(m_vterm.get(), data.constData(), data.size());
|
vterm_input_write(m_vterm.get(), data.constData(), data.size());
|
||||||
vterm_screen_flush_damage(m_vtermScreen);
|
|
||||||
|
|
||||||
// Send Ctrl+L which will clear the screen
|
// Send Ctrl+L which will clear the screen
|
||||||
writeToPty(QByteArray("\f"));
|
writeToPty(QByteArray("\f"));
|
||||||
}
|
}
|
||||||
|
|
||||||
void TerminalWidget::onReadyRead()
|
void TerminalWidget::onReadyRead(bool forceFlush)
|
||||||
{
|
{
|
||||||
QByteArray data = m_process->readAllRawStandardOutput();
|
QByteArray data = m_process->readAllRawStandardOutput();
|
||||||
vterm_input_write(m_vterm.get(), data.constData(), data.size());
|
vterm_input_write(m_vterm.get(), data.constData(), data.size());
|
||||||
|
|
||||||
|
flushVTerm(forceFlush);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TerminalWidget::flushVTerm(bool force)
|
||||||
|
{
|
||||||
|
if (force || QDateTime::currentDateTime() - m_lastFlush > minRefreshInterval) {
|
||||||
|
m_lastFlush = QDateTime::currentDateTime();
|
||||||
vterm_screen_flush_damage(m_vtermScreen);
|
vterm_screen_flush_damage(m_vtermScreen);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!m_flushDelayTimer.isActive())
|
||||||
|
m_flushDelayTimer.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
const VTermScreenCell *TerminalWidget::fetchCell(int x, int y) const
|
const VTermScreenCell *TerminalWidget::fetchCell(int x, int y) const
|
||||||
@@ -707,7 +720,7 @@ void TerminalWidget::applySizeChange()
|
|||||||
m_process->ptyData().resize(m_vtermSize);
|
m_process->ptyData().resize(m_vtermSize);
|
||||||
|
|
||||||
vterm_set_size(m_vterm.get(), m_vtermSize.height(), m_vtermSize.width());
|
vterm_set_size(m_vterm.get(), m_vtermSize.height(), m_vtermSize.width());
|
||||||
vterm_screen_flush_damage(m_vtermScreen);
|
flushVTerm(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TerminalWidget::updateScrollBars()
|
void TerminalWidget::updateScrollBars()
|
||||||
|
|||||||
@@ -76,7 +76,7 @@ protected:
|
|||||||
bool event(QEvent *event) override;
|
bool event(QEvent *event) override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void onReadyRead();
|
void onReadyRead(bool forceFlush);
|
||||||
void setupVTerm();
|
void setupVTerm();
|
||||||
void setupFont();
|
void setupFont();
|
||||||
void setupPty();
|
void setupPty();
|
||||||
@@ -110,6 +110,8 @@ protected:
|
|||||||
|
|
||||||
void updateScrollBars();
|
void updateScrollBars();
|
||||||
|
|
||||||
|
void flushVTerm(bool force);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::unique_ptr<Utils::QtcProcess> m_process;
|
std::unique_ptr<Utils::QtcProcess> m_process;
|
||||||
|
|
||||||
@@ -151,14 +153,15 @@ private:
|
|||||||
QAction m_zoomInAction;
|
QAction m_zoomInAction;
|
||||||
QAction m_zoomOutAction;
|
QAction m_zoomOutAction;
|
||||||
|
|
||||||
QTimer m_readDelayTimer;
|
QTimer m_flushDelayTimer;
|
||||||
int m_readDelayRestarts{0};
|
|
||||||
|
|
||||||
int m_layoutVersion{0};
|
int m_layoutVersion{0};
|
||||||
|
|
||||||
std::array<QColor, 18> m_currentColors;
|
std::array<QColor, 18> m_currentColors;
|
||||||
|
|
||||||
Utils::Terminal::OpenTerminalParameters m_openParameters;
|
Utils::Terminal::OpenTerminalParameters m_openParameters;
|
||||||
|
|
||||||
|
QDateTime m_lastFlush;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Terminal
|
} // namespace Terminal
|
||||||
|
|||||||
Reference in New Issue
Block a user