Files
qmltermwidget/lib/Pty_win.cpp
T

111 lines
2.8 KiB
C++

/*
Windows ConPTY-based Pty implementation using ptyqt.
Replaces the POSIX kpty/kptyprocess stack on Windows.
*/
#if defined(Q_OS_WIN)
#include "Pty.h"
#include <conptyprocess.h> // direct ConPTY backend — avoids WinPty dependency
#include <QtDebug>
using namespace Konsole;
Pty::Pty(QObject *parent) : QObject(parent) {}
Pty::Pty(int /*ptyMasterFd*/, QObject *parent) : QObject(parent) {}
Pty::~Pty()
{
if (_ptyProcess) {
_ptyProcess->stopProcess();
delete _ptyProcess;
}
}
int Pty::start(const QString &program,
const QStringList &arguments,
const QStringList &environment,
ulong /*winid*/,
bool /*addToUtmp*/)
{
_ptyProcess = new ConPtyProcess();
if (!ConPtyProcess::isAvailable()) {
qWarning() << "Pty: ConPTY not available on this Windows version (requires 10 build 1903+)";
delete _ptyProcess;
_ptyProcess = nullptr;
return -1;
}
connect(_ptyProcess, &IPtyProcess::readyRead, this, &Pty::onReadyRead);
connect(_ptyProcess, &IPtyProcess::finished, this, &Pty::onProcessFinished);
// arguments[0] is a duplicate of program (argv[0]); ptyqt takes args without it
QStringList args = arguments.size() > 1 ? arguments.mid(1) : QStringList{};
bool ok = _ptyProcess->startProcess(program, args, _workingDir, environment,
static_cast<qint16>(_windowColumns),
static_cast<qint16>(_windowLines));
if (!ok) {
qWarning() << "Pty: failed to start" << program << _ptyProcess->lastError();
delete _ptyProcess;
_ptyProcess = nullptr;
return -1;
}
emit started();
return 0;
}
void Pty::sendData(const char *buffer, int length)
{
if (_ptyProcess && length > 0)
_ptyProcess->write(QByteArray(buffer, length));
}
void Pty::setWindowSize(int lines, int cols)
{
_windowLines = lines;
_windowColumns = cols;
if (_ptyProcess)
_ptyProcess->setSize(static_cast<qint16>(cols), static_cast<qint16>(lines));
}
QSize Pty::windowSize() const
{
return {_windowColumns, _windowLines};
}
int Pty::foregroundProcessGroup() const
{
return _ptyProcess ? static_cast<int>(_ptyProcess->pid()) : 0;
}
QProcess::ProcessState Pty::state() const
{
if (_ptyProcess && _ptyProcess->isRunning())
return QProcess::Running;
return QProcess::NotRunning;
}
qint64 Pty::processId() const
{
return _ptyProcess ? static_cast<qint64>(_ptyProcess->pid()) : -1;
}
void Pty::onReadyRead()
{
if (!_ptyProcess)
return;
QByteArray data = _ptyProcess->readAll();
if (!data.isEmpty())
emit receivedData(data.constData(), data.size());
}
void Pty::onProcessFinished()
{
emit finished(0, QProcess::NormalExit);
}
#endif // Q_OS_WIN