diff --git a/src/contour/TerminalSessionManager.cpp b/src/contour/TerminalSessionManager.cpp index 27723d478b..80b24f31f7 100644 --- a/src/contour/TerminalSessionManager.cpp +++ b/src/contour/TerminalSessionManager.cpp @@ -13,6 +13,8 @@ #include #include +#include +#include #include using namespace std::string_literals; @@ -27,13 +29,15 @@ TerminalSessionManager::TerminalSessionManager(ContourGuiApp& app): _app { app } { } -std::unique_ptr TerminalSessionManager::createPty() +std::unique_ptr TerminalSessionManager::createPty(std::optional cwd) { auto const& profile = _app.config().profile(_app.profileName()); #if defined(VTPTY_LIBSSH2) if (!profile->ssh.value().hostname.empty()) return make_unique(profile->ssh.value()); #endif + if (cwd) + profile->shell.value().workingDirectory = std::filesystem::path(cwd.value()); return make_unique(profile->shell.value(), vtpty::createPty(profile->terminalSize.value(), nullopt), profile->escapeSandbox.value()); @@ -43,7 +47,32 @@ TerminalSession* TerminalSessionManager::createSession() { // TODO: Remove dependency on app-knowledge and pass shell / terminal-size instead. // The GuiApp *or* (Global)Config could be made a global to be accessable from within QML. - auto* session = new TerminalSession(createPty(), _app); + // + +#if !defined(_WIN32) + auto ptyPath = [this]() -> std::optional { + if (_activeSession) + { + auto& terminal = _activeSession->terminal(); + if (auto const* ptyProcess = dynamic_cast(&terminal.device())) + return ptyProcess->workingDirectory(); + } + return std::nullopt; + }(); +#else + std::optional ptyPath = std::nullopt; + if (_activeSession) + { + auto& terminal = _activeSession->terminal(); + { + auto _l = std::scoped_lock { terminal }; + ptyPath = terminal.currentWorkingDirectory(); + } + } +#endif + + auto* session = new TerminalSession(createPty(ptyPath), _app); + managerLog()("CREATE SESSION, new session: {}", (void*) session); _sessions.push_back(session); @@ -57,6 +86,7 @@ TerminalSession* TerminalSessionManager::createSession() // we can close application right after session has been created _lastTabChange = std::chrono::steady_clock::now() - std::chrono::seconds(1); + _activeSession = session; return session; } @@ -72,14 +102,11 @@ void TerminalSessionManager::setSession(size_t index) if (index < _sessions.size()) _activeSession = _sessions[index]; else - _activeSession = createSession(); + createSession(); if (oldSession == _activeSession) return; - if (oldSession) - oldSession->detachDisplay(*display); - Require(display != nullptr); auto const pixels = display->pixelSize(); auto const totalPageSize = display->calculatePageSize() + _activeSession->terminal().statusLineHeight(); @@ -87,6 +114,7 @@ void TerminalSessionManager::setSession(size_t index) display->setSession(_activeSession); _activeSession->terminal().resizeScreen(totalPageSize, pixels); updateStatusLine(); + _lastTabChange = std::chrono::steady_clock::now(); } @@ -106,16 +134,9 @@ void TerminalSessionManager::switchToTabLeft() { setSession(currentSessionIndex - 1); } -} - -void TerminalSessionManager::switchToTab(int position) -{ - managerLog()(std::format( - "switchToTab from {} to {} (out of {})", getCurrentSessionIndex(), position - 1, _sessions.size())); - - if (1 <= position && position <= static_cast(_sessions.size())) + else // wrap { - setSession(position - 1); + setSession(_sessions.size() - 1); } } @@ -129,6 +150,21 @@ void TerminalSessionManager::switchToTabRight() { setSession(currentSessionIndex + 1); } + else // wrap + { + setSession(0); + } +} + +void TerminalSessionManager::switchToTab(int position) +{ + managerLog()(std::format( + "switchToTab from {} to {} (out of {})", getCurrentSessionIndex(), position - 1, _sessions.size())); + + if (1 <= position && position <= static_cast(_sessions.size())) + { + setSession(position - 1); + } } void TerminalSessionManager::closeTab() diff --git a/src/contour/TerminalSessionManager.h b/src/contour/TerminalSessionManager.h index e3d593ac3d..66cab609c2 100644 --- a/src/contour/TerminalSessionManager.h +++ b/src/contour/TerminalSessionManager.h @@ -49,7 +49,7 @@ class TerminalSessionManager: public QAbstractListModel TerminalSession* getSession() { return _sessions[0]; } private: - std::unique_ptr createPty(); + std::unique_ptr createPty(std::optional cwd); [[nodiscard]] auto getCurrentSessionIndex() const { return [](auto const& sessions, auto const& activeSession) { @@ -87,7 +87,7 @@ class TerminalSessionManager: public QAbstractListModel TerminalSession* _activeSession = nullptr; std::vector _sessions; std::chrono::time_point _lastTabChange; - std::chrono::milliseconds _timeBetweenTabSwitches { 100 }; + std::chrono::milliseconds _timeBetweenTabSwitches { 10 }; }; } // namespace contour diff --git a/src/contour/display/TerminalDisplay.cpp b/src/contour/display/TerminalDisplay.cpp index efdb310787..46043658c2 100644 --- a/src/contour/display/TerminalDisplay.cpp +++ b/src/contour/display/TerminalDisplay.cpp @@ -311,6 +311,8 @@ void TerminalDisplay::setSession(TerminalSession* newSession) window()->setFlag(Qt::FramelessWindowHint, !profile().showTitleBar.value()); if (!_renderer) + { + _renderer = make_unique( _session->profile().terminalSize.value(), sanitizeFontDescription(profile().fonts.value(), fontDPI()), @@ -323,9 +325,11 @@ void TerminalDisplay::setSession(TerminalSession* newSession) // TODO: , WindowMargin(windowMargin_.left, windowMargin_.bottom); ); - applyFontDPI(); - updateImplicitSize(); - updateMinimumSize(); + // setup once with the renderer creation + applyFontDPI(); + updateImplicitSize(); + updateMinimumSize(); + } _session->attachDisplay(*this); // NB: Requires Renderer to be instanciated to retrieve grid metrics. diff --git a/src/vtrasterizer/TextClusterGrouper_test.cpp b/src/vtrasterizer/TextClusterGrouper_test.cpp index 42ffa89713..4b7c668f94 100644 --- a/src/vtrasterizer/TextClusterGrouper_test.cpp +++ b/src/vtrasterizer/TextClusterGrouper_test.cpp @@ -8,7 +8,7 @@ #include -#include +#include #include #include