14
14
15
15
#include < algorithm>
16
16
#include < filesystem>
17
- #include < mutex>
18
17
#include < string>
19
18
20
19
using namespace std ::string_literals;
@@ -44,10 +43,16 @@ std::unique_ptr<vtpty::Pty> TerminalSessionManager::createPty(std::optional<std:
44
43
}
45
44
46
45
TerminalSession* TerminalSessionManager::createSession ()
46
+ {
47
+ return activateSession (createSessionInBackground ());
48
+ }
49
+
50
+ TerminalSession* TerminalSessionManager::createSessionInBackground ()
47
51
{
48
52
// TODO: Remove dependency on app-knowledge and pass shell / terminal-size instead.
49
53
// The GuiApp *or* (Global)Config could be made a global to be accessable from within QML.
50
- //
54
+
55
+ _previousActiveSession = _activeSession;
51
56
52
57
#if !defined(_WIN32)
53
58
auto ptyPath = [this ]() -> std::optional<std::string> {
@@ -72,7 +77,7 @@ TerminalSession* TerminalSessionManager::createSession()
72
77
#endif
73
78
74
79
auto * session = new TerminalSession (createPty (ptyPath), _app);
75
- managerLog ()(" CREATE SESSION, new session: {} " , ( void *) session );
80
+ managerLog ()(" Create new session with ID {} at index {} " , session-> id (), _sessions. size () );
76
81
77
82
_sessions.push_back (session);
78
83
@@ -84,55 +89,81 @@ TerminalSession* TerminalSessionManager::createSession()
84
89
// sessions. This will work around it, by explicitly claiming ownership of the object.
85
90
QQmlEngine::setObjectOwnership (session, QQmlEngine::CppOwnership);
86
91
87
- // we can close application right after session has been created
88
- _lastTabChange = std::chrono::steady_clock::now () - std::chrono::seconds (1 );
89
- _activeSession = session;
90
92
return session;
91
93
}
92
94
93
95
void TerminalSessionManager::setSession (size_t index)
94
96
{
95
97
Require (index <= _sessions.size ());
96
98
managerLog ()(std::format (" SET SESSION: index: {}, _sessions.size(): {}" , index , _sessions.size ()));
99
+
97
100
if (!isAllowedToChangeTabs ())
98
101
return ;
99
102
100
- Require (display != nullptr );
101
- auto const pixels = display->pixelSize ();
102
- auto const totalPageSize = display->calculatePageSize () + _activeSession->terminal ().statusLineHeight ();
103
+ if (index < _sessions.size ())
104
+ activateSession (_sessions[index ]);
105
+ else
106
+ activateSession (createSessionInBackground ());
107
+ }
103
108
104
- auto * oldSession = _activeSession;
109
+ TerminalSession* TerminalSessionManager::activateSession (TerminalSession* session, bool isNewSession)
110
+ {
111
+ managerLog ()(
112
+ " Activating session ID {} at index {}" , session->id (), getSessionIndexOf (session).value_or (-1 ));
105
113
106
- if (index < _sessions. size () )
114
+ if (_activeSession == session )
107
115
{
108
- _activeSession = _sessions[index ];
109
- // Ensure that the existing session is resized to the display's size.
110
- _activeSession->terminal ().resizeScreen (totalPageSize, pixels);
116
+ managerLog ()(" Session is already active. (index {}, ID {})" , getCurrentSessionIndex (), session->id ());
117
+ return session;
111
118
}
112
- else
113
- createSession ();
114
-
115
- if (oldSession == _activeSession)
116
- return ;
117
119
118
- display->setSession (_activeSession);
119
- // Resize active session after display is attached to it
120
- // to return a lost line
121
- _activeSession->terminal ().resizeScreen (totalPageSize, pixels);
120
+ _previousActiveSession = _activeSession;
121
+ _activeSession = session;
122
+ _lastTabChange = std::chrono::steady_clock::now ();
122
123
updateStatusLine ();
123
124
124
- _lastTabChange = std::chrono::steady_clock::now ();
125
+ if (display)
126
+ {
127
+ managerLog ()(" Attaching display to session." );
128
+ auto const pixels = display->pixelSize ();
129
+ auto const totalPageSize =
130
+ display->calculatePageSize () + _previousActiveSession->terminal ().statusLineHeight ();
131
+
132
+ // Ensure that the existing session is resized to the display's size.
133
+ if (!isNewSession)
134
+ _activeSession->terminal ().resizeScreen (totalPageSize, pixels);
135
+
136
+ display->setSession (_activeSession);
137
+
138
+ // Resize active session after display is attached to it
139
+ // to return a lost line
140
+ _activeSession->terminal ().resizeScreen (totalPageSize, pixels);
141
+ }
142
+
143
+ return session;
125
144
}
126
145
127
146
void TerminalSessionManager::addSession ()
128
147
{
129
- setSession (_sessions.size ());
148
+ activateSession (createSessionInBackground (), true /* force resize on before display-attach*/ );
149
+ }
150
+
151
+ void TerminalSessionManager::switchToPreviousTab ()
152
+ {
153
+ managerLog ()(" switch to previous tab (current: {}, previous: {})" ,
154
+ getSessionIndexOf (_activeSession).value_or (-1 ),
155
+ getSessionIndexOf (_previousActiveSession).value_or (-1 ));
156
+
157
+ if (!isAllowedToChangeTabs ())
158
+ return ;
159
+
160
+ activateSession (_previousActiveSession);
130
161
}
131
162
132
163
void TerminalSessionManager::switchToTabLeft ()
133
164
{
134
165
const auto currentSessionIndex = getCurrentSessionIndex ();
135
- managerLog ()(std::format (" PREVIOUS TAB : currentSessionIndex: {}, _sessions.size(): {}" ,
166
+ managerLog ()(std::format (" previous tab : currentSessionIndex: {}, _sessions.size(): {}" ,
136
167
currentSessionIndex,
137
168
_sessions.size ()));
138
169
@@ -164,73 +195,59 @@ void TerminalSessionManager::switchToTabRight()
164
195
165
196
void TerminalSessionManager::switchToTab (int position)
166
197
{
167
- managerLog ()(std::format (
168
- " switchToTab from {} to {} (out of {})" , getCurrentSessionIndex (), position - 1 , _sessions.size ()));
198
+ managerLog ()(" switchToTab from index {} to {} (out of {})" ,
199
+ getSessionIndexOf (_activeSession).value_or (-1 ),
200
+ position - 1 ,
201
+ _sessions.size ());
202
+
203
+ if (!isAllowedToChangeTabs ())
204
+ return ;
169
205
170
206
if (1 <= position && position <= static_cast <int >(_sessions.size ()))
171
- {
172
- setSession (position - 1 );
173
- }
207
+ activateSession (_sessions[position - 1 ]);
174
208
}
175
209
176
210
void TerminalSessionManager::closeTab ()
177
211
{
178
- const auto currentSessionIndex = getCurrentSessionIndex ();
179
- managerLog ()(std::format (
180
- " CLOSE TAB: currentSessionIndex: {}, _sessions.size(): {}" , currentSessionIndex, _sessions.size ()));
181
-
182
- // Session was removed outside of terminal session manager, we need to switch to another tab.
183
- if (currentSessionIndex == -1 && !_sessions.empty ())
184
- {
185
- // We need to switch to another tab, so we permit consequent tab changes.
186
- // TODO: This is a bit hacky.
187
- _lastTabChange = std::chrono::steady_clock::now () - std::chrono::seconds (1 );
188
- setSession (0 );
189
- return ;
190
- }
191
-
192
- if (_sessions.size () > 1 )
193
- {
212
+ managerLog ()(" Close tab: current session ID {}, index {}" ,
213
+ getSessionIndexOf (_activeSession).value_or (-1 ),
214
+ _activeSession->id ());
194
215
195
- if (!isAllowedToChangeTabs ())
196
- return ;
197
-
198
- removeSession (*_activeSession);
199
-
200
- // We need to switch to another tab, so we permit consequent tab changes.
201
- // TODO: This is a bit hacky.
202
- _lastTabChange = std::chrono::steady_clock::now () - std::chrono::seconds (1 );
203
-
204
- if (std::cmp_less_equal (currentSessionIndex, _sessions.size () - 1 ))
205
- {
206
- setSession (currentSessionIndex + 1 );
207
- }
208
- else
209
- {
210
- setSession (currentSessionIndex - 1 );
211
- }
212
- }
216
+ removeSession (*_activeSession);
213
217
}
214
218
215
219
void TerminalSessionManager::removeSession (TerminalSession& thatSession)
216
220
{
217
- managerLog ()(std::format (
218
- " REMOVE SESSION: session: {}, _sessions.size(): {}" , (void *) &thatSession, _sessions.size ()));
221
+ managerLog ()(" REMOVE SESSION: session: {}, _sessions.size(): {}" , (void *) &thatSession, _sessions.size ());
219
222
220
223
if (!isAllowedToChangeTabs ())
221
224
return ;
222
225
223
- _app.onExit (thatSession); // TODO: the logic behind that impl could probably be moved here.
226
+ if (&thatSession == _activeSession && _previousActiveSession)
227
+ activateSession (_previousActiveSession);
224
228
225
- auto i = std::ranges::find_if (_sessions, [&]( auto p) { return p == & thatSession; } );
226
- if (i ! = _sessions.end ())
229
+ auto i = std::ranges::find (_sessions, & thatSession);
230
+ if (i = = _sessions.end ())
227
231
{
228
- _sessions.erase (i);
232
+ managerLog ()(" Session not found in session list." );
233
+ return ;
229
234
}
235
+ _sessions.erase (i);
236
+ _app.onExit (thatSession); // TODO: the logic behind that impl could probably be moved here.
237
+
238
+ _previousActiveSession = [&]() -> TerminalSession* {
239
+ auto const currentIndex = getSessionIndexOf (_activeSession).value_or (0 );
240
+ if (currentIndex + 1 < _sessions.size ())
241
+ return _sessions[currentIndex + 1 ];
242
+ else if (currentIndex > 0 )
243
+ return _sessions[currentIndex - 1 ];
244
+ else
245
+ return nullptr ;
246
+ }();
247
+ managerLog ()(" Calculated next \" previous\" session index {}" ,
248
+ getSessionIndexOf (_previousActiveSession).value_or (-1 ));
230
249
231
250
updateStatusLine ();
232
- _lastTabChange = std::chrono::steady_clock::now ();
233
- // Notify app if all sessions have been killed to trigger app termination.
234
251
}
235
252
236
253
void TerminalSessionManager::updateColorPreference (vtbackend::ColorPreference const & preference)
0 commit comments