aboutsummaryrefslogtreecommitdiffstats
path: root/src/plugins/terminal/terminalprocessimpl.cpp
blob: 9a7f7e7dcd6c574eb8dc849ad64d0feca94d6541 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
// Copyright (C) 2022 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0

#include "terminalprocessimpl.h"
#include "terminalwidget.h"

#include <utils/externalterminalprocessimpl.h>

#include <QApplication>
#include <QLocalServer>
#include <QLocalSocket>
#include <QLoggingCategory>
#include <QTemporaryFile>
#include <QTimer>

Q_LOGGING_CATEGORY(terminalProcessLog, "qtc.terminal.stubprocess", QtDebugMsg)

using namespace Utils;
using namespace Utils::Terminal;

namespace Terminal {

class ProcessStubCreator : public StubCreator
{
public:
    ProcessStubCreator(TerminalProcessImpl *interface, TerminalPane *terminalPane)
        : m_terminalPane(terminalPane)
        , m_process(interface)
        , m_interface(interface)
    {}

    expected_str<qint64> startStubProcess(const ProcessSetupData &setup) override
    {
        if (QApplication::activeModalWidget()) {
            m_fallbackStubCreator = std::make_unique<Utils::ProcessStubCreator>(m_interface);
            return m_fallbackStubCreator->startStubProcess(setup);
        }

        const Id id = Id::fromString(setup.m_commandLine.executable().toUserOutput());

        TerminalWidget *terminal = m_terminalPane->stoppedTerminalWithId(id);

        const OpenTerminalParameters openParameters{setup.m_commandLine,
                                                    std::nullopt,
                                                    std::nullopt,
                                                    ExitBehavior::Keep,
                                                    id};

        if (!terminal) {
            terminal = new TerminalWidget(nullptr, openParameters);

            terminal->setShellName(setup.m_commandLine.executable().fileName());
            m_terminalPane->addTerminal(terminal, "App");
        } else {
            terminal->restart(openParameters);
        }

        m_terminalPane->ensureVisible(terminal);

        connect(terminal, &TerminalWidget::destroyed, m_process, [process = m_process] {
            if (process->inferiorProcessId())
                process->emitFinished(-1, QProcess::CrashExit);
        });

        return 0;
    }

    TerminalPane *m_terminalPane;
    TerminalProcessImpl *m_process;
    TerminalInterface *m_interface;
    std::unique_ptr<Utils::ProcessStubCreator> m_fallbackStubCreator;
};

TerminalProcessImpl::TerminalProcessImpl(TerminalPane *terminalPane)
    : TerminalInterface(false)
{
    auto creator = new ProcessStubCreator(this, terminalPane);
    creator->moveToThread(qApp->thread());
    setStubCreator(creator);
}

} // namespace Terminal