Terminal: Add enable setting

Change-Id: I13cca8b2d4c55df7db29807c1252718e2819ea0b
Reviewed-by: Cristian Adam <cristian.adam@qt.io>
This commit is contained in:
Marcus Tillmanns
2023-03-22 16:54:53 +01:00
parent 75bdaf25d0
commit 1d9c96a9f4
9 changed files with 130 additions and 33 deletions

View File

@@ -732,7 +732,7 @@ public:
if (m_setup.m_ptyData) if (m_setup.m_ptyData)
return new PtyProcessImpl; return new PtyProcessImpl;
if (m_setup.m_terminalMode != TerminalMode::Off) if (m_setup.m_terminalMode != TerminalMode::Off)
return Terminal::Hooks::instance().createTerminalProcessInterfaceHook()(); return Terminal::Hooks::instance().createTerminalProcessInterface();
const ProcessImpl impl = m_setup.m_processImpl == ProcessImpl::Default const ProcessImpl impl = m_setup.m_processImpl == ProcessImpl::Default
? defaultProcessImpl() : m_setup.m_processImpl; ? defaultProcessImpl() : m_setup.m_processImpl;

View File

@@ -8,6 +8,7 @@
#include "terminalcommand.h" #include "terminalcommand.h"
#include "terminalinterface.h" #include "terminalinterface.h"
#include <QMutex>
#include <QTemporaryFile> #include <QTemporaryFile>
namespace Utils::Terminal { namespace Utils::Terminal {
@@ -88,21 +89,65 @@ public:
ExternalTerminalProcessImpl() { setStubCreator(new ProcessStubCreator(this)); } ExternalTerminalProcessImpl() { setStubCreator(new ProcessStubCreator(this)); }
}; };
struct HooksPrivate class HooksPrivate
{ {
public:
HooksPrivate() HooksPrivate()
: m_openTerminalHook([](const OpenTerminalParameters &parameters) { : m_getTerminalCommandsForDevicesHook([] { return QList<NameAndCommandLine>{}; })
{
auto openTerminal = [](const OpenTerminalParameters &parameters) {
DeviceFileHooks::instance().openTerminal(parameters.workingDirectory.value_or( DeviceFileHooks::instance().openTerminal(parameters.workingDirectory.value_or(
FilePath{}), FilePath{}),
parameters.environment.value_or(Environment{})); parameters.environment.value_or(Environment{}));
}) };
, m_createTerminalProcessInterfaceHook([] { return new ExternalTerminalProcessImpl(); }) auto createProcessInterface = []() { return new ExternalTerminalProcessImpl(); };
, m_getTerminalCommandsForDevicesHook([] { return QList<NameAndCommandLine>{}; })
{} addCallbackSet("External", {openTerminal, createProcessInterface});
}
void addCallbackSet(const QString &name, const Hooks::CallbackSet &callbackSet)
{
QMutexLocker lk(&m_mutex);
m_callbackSets.push_back(qMakePair(name, callbackSet));
m_createTerminalProcessInterface
= m_callbackSets.back().second.createTerminalProcessInterface;
m_openTerminal = m_callbackSets.back().second.openTerminal;
}
void removeCallbackSet(const QString &name)
{
if (name == "External")
return;
QMutexLocker lk(&m_mutex);
m_callbackSets.removeIf([name](const auto &pair) { return pair.first == name; });
m_createTerminalProcessInterface
= m_callbackSets.back().second.createTerminalProcessInterface;
m_openTerminal = m_callbackSets.back().second.openTerminal;
}
Hooks::CreateTerminalProcessInterface createTerminalProcessInterface()
{
QMutexLocker lk(&m_mutex);
return m_createTerminalProcessInterface;
}
Hooks::OpenTerminal openTerminal()
{
QMutexLocker lk(&m_mutex);
return m_openTerminal;
}
Hooks::OpenTerminalHook m_openTerminalHook;
Hooks::CreateTerminalProcessInterfaceHook m_createTerminalProcessInterfaceHook;
Hooks::GetTerminalCommandsForDevicesHook m_getTerminalCommandsForDevicesHook; Hooks::GetTerminalCommandsForDevicesHook m_getTerminalCommandsForDevicesHook;
private:
Hooks::OpenTerminal m_openTerminal;
Hooks::CreateTerminalProcessInterface m_createTerminalProcessInterface;
QMutex m_mutex;
QList<QPair<QString, Hooks::CallbackSet>> m_callbackSets;
}; };
Hooks &Hooks::instance() Hooks &Hooks::instance()
@@ -117,14 +162,14 @@ Hooks::Hooks()
Hooks::~Hooks() = default; Hooks::~Hooks() = default;
Hooks::OpenTerminalHook &Hooks::openTerminalHook() void Hooks::openTerminal(const OpenTerminalParameters &parameters) const
{ {
return d->m_openTerminalHook; d->openTerminal()(parameters);
} }
Hooks::CreateTerminalProcessInterfaceHook &Hooks::createTerminalProcessInterfaceHook() ProcessInterface *Hooks::createTerminalProcessInterface() const
{ {
return d->m_createTerminalProcessInterfaceHook; return d->createTerminalProcessInterface()();
} }
Hooks::GetTerminalCommandsForDevicesHook &Hooks::getTerminalCommandsForDevicesHook() Hooks::GetTerminalCommandsForDevicesHook &Hooks::getTerminalCommandsForDevicesHook()
@@ -132,4 +177,14 @@ Hooks::GetTerminalCommandsForDevicesHook &Hooks::getTerminalCommandsForDevicesHo
return d->m_getTerminalCommandsForDevicesHook; return d->m_getTerminalCommandsForDevicesHook;
} }
void Hooks::addCallbackSet(const QString &name, const CallbackSet &callbackSet)
{
d->addCallbackSet(name, callbackSet);
}
void Hooks::removeCallbackSet(const QString &name)
{
d->removeCallbackSet(name);
}
} // namespace Utils::Terminal } // namespace Utils::Terminal

View File

@@ -37,7 +37,7 @@ private:
}; };
namespace Terminal { namespace Terminal {
struct HooksPrivate; class HooksPrivate;
enum class ExitBehavior { Close, Restart, Keep }; enum class ExitBehavior { Close, Restart, Keep };
@@ -61,18 +61,29 @@ QTCREATOR_UTILS_EXPORT FilePath defaultShellForDevice(const FilePath &deviceRoot
class QTCREATOR_UTILS_EXPORT Hooks class QTCREATOR_UTILS_EXPORT Hooks
{ {
public: public:
using OpenTerminalHook = Hook<void, const OpenTerminalParameters &>; using OpenTerminal = std::function<void(const OpenTerminalParameters &)>;
using CreateTerminalProcessInterfaceHook = Hook<ProcessInterface *>; using CreateTerminalProcessInterface = std::function<ProcessInterface *()>;
struct CallbackSet
{
OpenTerminal openTerminal;
CreateTerminalProcessInterface createTerminalProcessInterface;
};
using GetTerminalCommandsForDevicesHook = Hook<QList<NameAndCommandLine>>; using GetTerminalCommandsForDevicesHook = Hook<QList<NameAndCommandLine>>;
public: public:
static Hooks &instance(); static Hooks &instance();
~Hooks(); ~Hooks();
OpenTerminalHook &openTerminalHook();
CreateTerminalProcessInterfaceHook &createTerminalProcessInterfaceHook();
GetTerminalCommandsForDevicesHook &getTerminalCommandsForDevicesHook(); GetTerminalCommandsForDevicesHook &getTerminalCommandsForDevicesHook();
void openTerminal(const OpenTerminalParameters &parameters) const;
ProcessInterface *createTerminalProcessInterface() const;
void addCallbackSet(const QString &name, const CallbackSet &callbackSet);
void removeCallbackSet(const QString &name);
private: private:
Hooks(); Hooks();
std::unique_ptr<HooksPrivate> d; std::unique_ptr<HooksPrivate> d;

View File

@@ -106,7 +106,7 @@ void FileUtils::showInFileSystemView(const FilePath &path)
void FileUtils::openTerminal(const FilePath &path, const Environment &env) void FileUtils::openTerminal(const FilePath &path, const Environment &env)
{ {
Terminal::Hooks::instance().openTerminalHook()({std::nullopt, path, env}); Terminal::Hooks::instance().openTerminal({std::nullopt, path, env});
} }
QString FileUtils::msgFindInDirectory() QString FileUtils::msgFindInDirectory()

View File

@@ -3818,7 +3818,7 @@ void ProjectExplorerPluginPrivate::openTerminalHere(const EnvironmentGetter &env
BuildConfiguration *bc = activeBuildConfiguration(ProjectTree::projectForNode(currentNode)); BuildConfiguration *bc = activeBuildConfiguration(ProjectTree::projectForNode(currentNode));
if (!bc) { if (!bc) {
Terminal::Hooks::instance().openTerminalHook()({{}, currentNode->directory(), environment}); Terminal::Hooks::instance().openTerminal({{}, currentNode->directory(), environment});
return; return;
} }
@@ -3835,10 +3835,9 @@ void ProjectExplorerPluginPrivate::openTerminalHere(const EnvironmentGetter &env
const FilePath shell = Terminal::defaultShellForDevice(buildDevice->rootPath()); const FilePath shell = Terminal::defaultShellForDevice(buildDevice->rootPath());
if (!shell.isEmpty() && buildDevice->rootPath().needsDevice()) { if (!shell.isEmpty() && buildDevice->rootPath().needsDevice()) {
Terminal::Hooks::instance().openTerminalHook()( Terminal::Hooks::instance().openTerminal({CommandLine{shell, {}}, workingDir, environment});
{CommandLine{shell, {}}, workingDir, environment});
} else { } else {
Terminal::Hooks::instance().openTerminalHook()({std::nullopt, workingDir, environment}); Terminal::Hooks::instance().openTerminal({std::nullopt, workingDir, environment});
} }
} }
@@ -3870,11 +3869,10 @@ void ProjectExplorerPluginPrivate::openTerminalHereWithRunEnv()
const FilePath shell = Terminal::defaultShellForDevice(device->rootPath()); const FilePath shell = Terminal::defaultShellForDevice(device->rootPath());
if (!shell.isEmpty() && device->rootPath().needsDevice()) { if (!shell.isEmpty() && device->rootPath().needsDevice()) {
Terminal::Hooks::instance().openTerminalHook()( Terminal::Hooks::instance().openTerminal(
{CommandLine{shell, {}}, workingDir, runnable.environment}); {CommandLine{shell, {}}, workingDir, runnable.environment});
} else { } else {
Terminal::Hooks::instance().openTerminalHook()( Terminal::Hooks::instance().openTerminal({std::nullopt, workingDir, runnable.environment});
{std::nullopt, workingDir, runnable.environment});
} }
} }

View File

@@ -43,13 +43,34 @@ void TerminalPlugin::extensionsInitialized()
m_terminalPane = new TerminalPane(); m_terminalPane = new TerminalPane();
ExtensionSystem::PluginManager::instance()->addObject(m_terminalPane); ExtensionSystem::PluginManager::instance()->addObject(m_terminalPane);
Utils::Terminal::Hooks::instance().openTerminalHook().set( auto enable = [this] {
[this](const Utils::Terminal::OpenTerminalParameters &p) { Utils::Terminal::Hooks::instance()
.addCallbackSet("Internal",
{[this](const Utils::Terminal::OpenTerminalParameters &p) {
m_terminalPane->openTerminal(p); m_terminalPane->openTerminal(p);
}); },
[this] { return new TerminalProcessImpl(m_terminalPane); }});
};
Utils::Terminal::Hooks::instance().createTerminalProcessInterfaceHook().set( auto disable = [] { Utils::Terminal::Hooks::instance().removeCallbackSet("Internal"); };
[this] { return new TerminalProcessImpl(m_terminalPane); });
static bool isEnabled = false;
auto settingsChanged = [enable, disable] {
if (isEnabled != TerminalSettings::instance().enableTerminal.value()) {
isEnabled = TerminalSettings::instance().enableTerminal.value();
if (isEnabled)
enable();
else
disable();
}
};
QObject::connect(&TerminalSettings::instance(),
&Utils::AspectContainer::applied,
this,
settingsChanged);
settingsChanged();
} }
} // namespace Internal } // namespace Internal

View File

@@ -64,6 +64,13 @@ TerminalSettings::TerminalSettings()
setAutoApply(false); setAutoApply(false);
setSettingsGroup("Terminal"); setSettingsGroup("Terminal");
enableTerminal.setSettingsKey("EnableTerminal");
enableTerminal.setLabelText(Tr::tr("Use internal Terminal"));
enableTerminal.setToolTip(
Tr::tr("If enabled, use the internal terminal when \"Run In Terminal\" is "
"enabled and for \"Open Terminal here\"."));
enableTerminal.setDefaultValue(true);
font.setSettingsKey("FontFamily"); font.setSettingsKey("FontFamily");
font.setLabelText(Tr::tr("Family:")); font.setLabelText(Tr::tr("Family:"));
font.setHistoryCompleter("Terminal.Fonts.History"); font.setHistoryCompleter("Terminal.Fonts.History");
@@ -121,6 +128,7 @@ TerminalSettings::TerminalSettings()
registerAspect(&fontSize); registerAspect(&fontSize);
registerAspect(&shell); registerAspect(&shell);
registerAspect(&allowBlinkingCursor); registerAspect(&allowBlinkingCursor);
registerAspect(&enableTerminal);
} }
} // namespace Terminal } // namespace Terminal

View File

@@ -13,13 +13,14 @@ public:
static TerminalSettings &instance(); static TerminalSettings &instance();
Utils::BoolAspect enableTerminal;
Utils::StringAspect font; Utils::StringAspect font;
Utils::IntegerAspect fontSize; Utils::IntegerAspect fontSize;
Utils::StringAspect shell; Utils::StringAspect shell;
Utils::ColorAspect foregroundColor; Utils::ColorAspect foregroundColor;
Utils::ColorAspect backgroundColor; Utils::ColorAspect backgroundColor;
Utils::ColorAspect selectionColor; Utils::ColorAspect selectionColor;
Utils::ColorAspect colors[16]; Utils::ColorAspect colors[16];

View File

@@ -47,6 +47,9 @@ QWidget *TerminalSettingsPage::widget()
// clang-format off // clang-format off
Column { Column {
Row {
settings.enableTerminal, st,
},
Group { Group {
title(Tr::tr("Font")), title(Tr::tr("Font")),
Row { Row {