Terminal: Add support for copy (OSC52)

Allows terminal apps like vim to set the clipboard, even from inside
an ssh/remote shell.

Change-Id: I1d068737ef65bb4541c3fc9c43870986865f1b45
Reviewed-by: Cristian Adam <cristian.adam@qt.io>
This commit is contained in:
Marcus Tillmanns
2023-08-03 08:25:10 +02:00
parent 0a69cdd277
commit 8ac9404725
5 changed files with 93 additions and 0 deletions

View File

@@ -14,6 +14,9 @@ public:
virtual void onBell() {}
virtual void onTitle(const QString &title) { Q_UNUSED(title); }
virtual void onSetClipboard(const QByteArray &text) { Q_UNUSED(text); }
virtual void onGetClipboard() {}
};
} // namespace TerminalSolution

View File

@@ -142,6 +142,41 @@ struct TerminalSurfacePrivate
VTermState *vts = vterm_obtain_state(m_vterm.get());
vterm_state_set_unrecognised_fallbacks(vts, &m_vtermStateFallbacks, this);
memset(&m_vtermSelectionCallbacks, 0, sizeof(m_vtermSelectionCallbacks));
m_vtermSelectionCallbacks.query = [](VTermSelectionMask mask, void *user) {
if (!(mask & 0xF))
return 0;
auto p = static_cast<TerminalSurfacePrivate *>(user);
if (p->m_surfaceIntegration)
p->m_surfaceIntegration->onGetClipboard();
return 0;
};
m_vtermSelectionCallbacks.set =
[](VTermSelectionMask mask, VTermStringFragment frag, void *user) {
if (!(mask & 0xF))
return 0;
auto p = static_cast<TerminalSurfacePrivate *>(user);
if (frag.initial)
p->m_selectionBuffer.clear();
p->m_selectionBuffer.append(frag.str, frag.len);
if (!frag.final)
return 1;
if (p->m_surfaceIntegration)
p->m_surfaceIntegration->onSetClipboard(p->m_selectionBuffer);
return 1;
};
vterm_state_set_selection_callbacks(vts, &m_vtermSelectionCallbacks, this, nullptr, 256);
vterm_state_set_bold_highbright(vts, true);
VTermColor fg;
@@ -363,6 +398,8 @@ struct TerminalSurfacePrivate
VTermScreenCallbacks m_vtermScreenCallbacks;
VTermStateFallbacks m_vtermStateFallbacks;
VTermSelectionCallbacks m_vtermSelectionCallbacks;
Cursor m_cursor;
QString m_currentCommand;
@@ -375,6 +412,7 @@ struct TerminalSurfacePrivate
TerminalSurface *q;
QTimer m_delayWriteTimer;
QByteArray m_writeBuffer;
QByteArray m_selectionBuffer;
TerminalSurface::WriteToPty m_writeToPty;
};

View File

@@ -179,4 +179,9 @@ void ShellIntegration::prepareProcess(Utils::Process &process)
process.setEnvironment(env);
}
void ShellIntegration::onSetClipboard(const QByteArray &text)
{
setClipboardAndSelection(QString::fromLocal8Bit(text));
}
} // namespace Terminal

View File

@@ -23,6 +23,8 @@ public:
void onBell() override;
void onTitle(const QString &title) override;
void onSetClipboard(const QByteArray &text) override;
void prepareProcess(Utils::Process &process);
signals:

45
src/plugins/terminal/tests/copy Executable file

File diff suppressed because one or more lines are too long