/* Windows ConPTY-based Pty implementation using ptyqt. Replaces the POSIX kpty/kptyprocess stack on Windows. */ #if defined(Q_OS_WIN) #include "Pty.h" #include // direct ConPTY backend — avoids WinPty dependency #include 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(_windowColumns), static_cast(_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(cols), static_cast(lines)); } QSize Pty::windowSize() const { return {_windowColumns, _windowLines}; } int Pty::foregroundProcessGroup() const { return _ptyProcess ? static_cast(_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(_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