forked from qt-creator/qt-creator
Terminal: Lazily open remote terminals
Move the burden of finding the shell of a device from the shell menu to the TerminalWidget, so that opening the shell menu does not block the ui. Change-Id: I7f2e5a891f20faa53a1e3eec879866219f9bee0b Reviewed-by: hjk <hjk@qt.io>
This commit is contained in:
@@ -3,6 +3,9 @@
|
||||
|
||||
#include "shellmodel.h"
|
||||
|
||||
#include <projectexplorer/devicesupport/devicemanager.h>
|
||||
#include <projectexplorer/projectexplorerconstants.h>
|
||||
|
||||
#include <utils/algorithm.h>
|
||||
#include <utils/environment.h>
|
||||
#include <utils/filepath.h>
|
||||
@@ -138,11 +141,10 @@ ShellModelPrivate::ShellModelPrivate()
|
||||
});
|
||||
|
||||
// ... and filter out non-existing shells.
|
||||
localShells = Utils::transform(
|
||||
Utils::filtered(shells, [](const FilePath &shell) {return shell.exists(); }),
|
||||
[&iconProvider](const FilePath &shell) {
|
||||
return ShellItemBuilder(iconProvider, shell).item();
|
||||
});
|
||||
localShells = Utils::transform(Utils::filtered(shells, &FilePath::exists),
|
||||
[&iconProvider](const FilePath &shell) {
|
||||
return ShellItemBuilder(iconProvider, shell).item();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -161,14 +163,15 @@ QList<ShellModelItem> ShellModel::local() const
|
||||
|
||||
QList<ShellModelItem> ShellModel::remote() const
|
||||
{
|
||||
const auto deviceCmds = Utils::Terminal::Hooks::instance().getTerminalCommandsForDevicesHook()();
|
||||
QList<ShellModelItem> result;
|
||||
|
||||
const QList<ShellModelItem> deviceItems = Utils::transform(
|
||||
deviceCmds, [](const Utils::Terminal::NameAndCommandLine &item) -> ShellModelItem {
|
||||
return ShellModelItem{item.name, {item.commandLine}};
|
||||
ProjectExplorer::DeviceManager::instance()->forEachDevice(
|
||||
[&result](const QSharedPointer<const ProjectExplorer::IDevice> &device) {
|
||||
if (device->type() != ProjectExplorer::Constants::DESKTOP_DEVICE_TYPE)
|
||||
result << ShellModelItem{device->displayName(), {{device->rootPath(), {}}}};
|
||||
});
|
||||
|
||||
return deviceItems;
|
||||
return result;
|
||||
}
|
||||
|
||||
} // namespace Terminal::Internal
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
#include <coreplugin/messagemanager.h>
|
||||
|
||||
#include <utils/algorithm.h>
|
||||
#include <utils/async.h>
|
||||
#include <utils/environment.h>
|
||||
#include <utils/fileutils.h>
|
||||
#include <utils/hostosinfo.h>
|
||||
@@ -82,6 +83,33 @@ void TerminalWidget::setupPty()
|
||||
CommandLine shellCommand = m_openParameters.shellCommand.value_or(
|
||||
CommandLine{settings().shell(), settings().shellArguments(), CommandLine::Raw});
|
||||
|
||||
if (shellCommand.executable().isRootPath()) {
|
||||
writeToTerminal(Tr::tr("Connecting ...\r\n").toUtf8(), true);
|
||||
// We still have to find the shell to start ...
|
||||
m_findShellWatcher.reset(new QFutureWatcher<FilePath>());
|
||||
connect(m_findShellWatcher.get(), &QFutureWatcher<FilePath>::finished, this, [this] {
|
||||
const FilePath result = m_findShellWatcher->result();
|
||||
if (!result.isEmpty()) {
|
||||
m_openParameters.shellCommand->setExecutable(m_findShellWatcher->result());
|
||||
restart(m_openParameters);
|
||||
return;
|
||||
}
|
||||
|
||||
writeToTerminal(
|
||||
("\r\n\033[31m" + Tr::tr("Could not find shell to start.") + "\r\n").toUtf8(), true);
|
||||
});
|
||||
|
||||
m_findShellWatcher->setFuture(Utils::asyncRun([shellCommand] {
|
||||
const FilePath result = Utils::Terminal::defaultShellForDevice(
|
||||
shellCommand.executable());
|
||||
if (result.isExecutableFile())
|
||||
return result;
|
||||
return FilePath{};
|
||||
}));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
Environment env = m_openParameters.environment.value_or(Environment{})
|
||||
.appliedToEnvironment(shellCommand.executable().deviceEnvironment());
|
||||
|
||||
|
||||
@@ -16,6 +16,10 @@
|
||||
#include <utils/process.h>
|
||||
#include <utils/terminalhooks.h>
|
||||
|
||||
#include <QFutureWatcher>
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace Terminal {
|
||||
|
||||
using RegisteredAction = std::unique_ptr<QAction, std::function<void(QAction *)>>;
|
||||
@@ -105,6 +109,8 @@ private:
|
||||
RegisteredAction m_close;
|
||||
|
||||
Internal::ShortcutMap m_shortcutMap;
|
||||
|
||||
std::unique_ptr<QFutureWatcher<Utils::FilePath>> m_findShellWatcher;
|
||||
};
|
||||
|
||||
} // namespace Terminal
|
||||
|
||||
Reference in New Issue
Block a user