Skip to content

Commit 5723019

Browse files
committed
further update
1 parent 71c9946 commit 5723019

File tree

5 files changed

+120
-93
lines changed

5 files changed

+120
-93
lines changed

metainfo.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@
111111
<li>Fixes `CancelSelection` default binding with escape (#1710)</li>
112112
<li>Fixes `CreateTab` to sometimes spawn more than one tab (#1695)</li>
113113
<li>Fixes crash using Chinese IME (#1707)</li>
114+
<li>Fixes handling of multiple windows and tabs (#1725)</li>
114115
<li>Ensure inserting new tabs happens right next to the currently active tab (#1695)</li>
115116
<li>Allow glyphs to underflow if they are not bigger than the cell size (#1603)</li>
116117
<li>Adds `MoveTabToLeft` and `MoveTabToRight` actions to move tabs around (#1695)</li>

src/contour/TerminalSession.cpp

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -606,8 +606,9 @@ void TerminalSession::inspect()
606606
// Deferred termination? Then close display now.
607607
if (_terminal.device().isClosed() && !_app.dumpStateAtExit().has_value())
608608
{
609-
sessionLog()("Terminal device is closed. Closing display.");
610-
_display->closeDisplay();
609+
sessionLog()("Terminal device is closed. Notify session manager.");
610+
_manager->currentSessionIsTerminated();
611+
//_display->closeDisplay(); // TODO MOVE LOGIC
611612
}
612613
}
613614

@@ -680,8 +681,9 @@ void TerminalSession::onClosed()
680681
inspect();
681682
else if (_display)
682683
{
683-
sessionLog()("Terminal device is closed. Closing display.");
684-
_display->closeDisplay();
684+
sessionLog()("Terminal device is closed. Notify manager.");
685+
_manager->currentSessionIsTerminated();
686+
// _display->closeDisplay(); // TODO MOVE LOGIC
685687
}
686688
else
687689
sessionLog()("Terminal device is closed. But no display available (yet).");

src/contour/TerminalSessionManager.cpp

Lines changed: 93 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,8 @@ TerminalSession* TerminalSessionManager::createSessionInBackground()
7474
#endif
7575

7676
auto* session = new TerminalSession(this, createPty(ptyPath), _app);
77-
managerLog()("Create new session with ID {} at index {}", session->id(), _sessions.size());
77+
managerLog()(
78+
"Create new session with ID {}({}) at index {}", session->id(), (void*) session, _sessions.size());
7879

7980
_sessions.insert(_sessions.end(), session);
8081

@@ -105,91 +106,101 @@ TerminalSession* TerminalSessionManager::activateSession(TerminalSession* sessio
105106
if (!session)
106107
return nullptr;
107108

108-
managerLog()(
109-
"Activating session ID {} at index {}", session->id(), getSessionIndexOf(session).value_or(-1));
109+
// debug for displayStates
110+
for (auto& [display, state]: _displayStates)
111+
{
112+
managerLog()("display: {}, session: {}\n", (void*) display, (void*) state);
113+
}
114+
115+
managerLog()("Activating session ID {} {} at index {}",
116+
session->id(),
117+
(void*) session,
118+
getSessionIndexOf(session).value_or(-1));
110119

111120
// iterate over _displayStates to see if this session is already active
112121
for (auto& [display, state]: _displayStates)
113122
{
114-
if (state.activeSession == session)
123+
if (state == session && (nullptr != display))
115124
{
116-
managerLog()("Session is already active : (display {}, ID {})", (void*) display, session->id());
117-
// return session;
125+
managerLog()("Session is already active : (display {}, ID {} {})",
126+
(void*) display,
127+
session->id(),
128+
(void*) session);
129+
return session;
118130
}
119131
}
120132

121133
if (!activeDisplay)
122134
{
123135
managerLog()("No active display fond. something went wrong.");
124136
}
125-
else
126-
{
127-
managerLog()("Active display found: {}", (void*) activeDisplay);
128-
_displayStates[activeDisplay].activeSession = session;
129-
_displayStates.erase(nullptr);
130-
}
131137

132138
auto& displayState = _displayStates[activeDisplay];
133-
displayState.previousActiveSession = displayState.activeSession;
134-
displayState.activeSession = session;
139+
displayState = session;
135140
updateStatusLine();
136141

137-
if (session->display())
138-
{
139-
managerLog()("Session already has another display attached.");
140-
}
141142
if (activeDisplay)
142143
{
143-
// check if we are trying to attach to another display, we need to deatach the session from the old
144-
// display first
145-
// if (session->display() != activeDisplay)
146-
// {
147-
// managerLog()(
148-
// "Deataching display {} from session: {}.", (void*) session->display(), session->id());
149-
// if (session->display() != nullptr)
150-
// //session->detachDisplay(*session->display());
151-
// }
152144

153145
auto const pixels = activeDisplay->pixelSize();
154-
auto const totalPageSize = activeDisplay->calculatePageSize() + [&] {
155-
if (displayState.previousActiveSession)
156-
return displayState.previousActiveSession->terminal().statusLineHeight();
157-
return vtpty::LineCount(0);
158-
}();
146+
auto const totalPageSize =
147+
activeDisplay->calculatePageSize() + displayState->terminal().statusLineHeight();
159148

160149
// Ensure that the existing session is resized to the display's size.
161150
if (!isNewSession)
162151
{
163152
managerLog()("Resize existing session to display size: {}x{}.",
164153
activeDisplay->width(),
165154
activeDisplay->height());
155+
displayState->terminal().resizeScreen(totalPageSize, pixels);
166156
}
167-
// displayState.activeSession->terminal().resizeScreen(totalPageSize, pixels);
168157

169-
managerLog()("Set display {} to session: {}.", (void*) activeDisplay, session->id());
170-
activeDisplay->setSession(displayState.activeSession);
171-
managerLog()("Done.");
158+
managerLog()(
159+
"Set display {} to session: {}({}).", (void*) activeDisplay, session->id(), (void*) session);
160+
// resize terminal session before display is attached to it
161+
activeDisplay->setSession(displayState);
172162

173163
// Resize active session after display is attached to it
174164
// to return a lost line
175-
displayState.activeSession->terminal().resizeScreen(totalPageSize, pixels);
165+
displayState->terminal().resizeScreen(totalPageSize, pixels);
176166
}
177167

178168
return session;
179169
}
180170

171+
void TerminalSessionManager::FocusOnDisplay(display::TerminalDisplay* display)
172+
{
173+
managerLog()("Setting active display to {}", (void*) display);
174+
activeDisplay = display;
175+
176+
// if we have a session in nullptr display, set it to this one
177+
if (_displayStates[nullptr] != nullptr)
178+
{
179+
_displayStates[activeDisplay] = _displayStates[nullptr];
180+
_displayStates[nullptr] = nullptr;
181+
activateSession(_displayStates[activeDisplay]);
182+
}
183+
184+
// if this is new display, find a session to attach to
185+
if (_displayStates[activeDisplay] == nullptr)
186+
{
187+
tryFindSessionForDisplayOrClose();
188+
}
189+
}
190+
181191
TerminalSession* TerminalSessionManager::createSession()
182192
{
183193
return activateSession(createSessionInBackground(), true /*force resize on before display-attach*/);
184194
}
185195

186196
void TerminalSessionManager::switchToPreviousTab()
187197
{
188-
managerLog()("switch to previous tab (current: {}, previous: {})",
189-
getSessionIndexOf(_displayStates[activeDisplay].activeSession).value_or(-1),
190-
getSessionIndexOf(_displayStates[activeDisplay].previousActiveSession).value_or(-1));
198+
return;
199+
// managerLog()("switch to previous tab (current: {}, previous: {})",
200+
// getSessionIndexOf(_displayStates[activeDisplay].activeSession).value_or(-1),
201+
// getSessionIndexOf(_displayStates[activeDisplay].previousActiveSession).value_or(-1));
191202

192-
activateSession(_displayStates[activeDisplay].previousActiveSession);
203+
// activateSession(_displayStates[activeDisplay].previousActiveSession);
193204
}
194205

195206
void TerminalSessionManager::switchToTabLeft()
@@ -228,7 +239,7 @@ void TerminalSessionManager::switchToTabRight()
228239
void TerminalSessionManager::switchToTab(int position)
229240
{
230241
managerLog()("switchToTab from index {} to {} (out of {})",
231-
getSessionIndexOf(_displayStates[activeDisplay].activeSession).value_or(-1),
242+
getSessionIndexOf(_displayStates[activeDisplay]).value_or(-1),
232243
position - 1,
233244
_sessions.size());
234245

@@ -239,15 +250,15 @@ void TerminalSessionManager::switchToTab(int position)
239250
void TerminalSessionManager::closeTab()
240251
{
241252
managerLog()("Close tab: current session ID {}, index {}",
242-
getSessionIndexOf(_displayStates[activeDisplay].activeSession).value_or(-1),
243-
_displayStates[activeDisplay].activeSession->id());
253+
getSessionIndexOf(_displayStates[activeDisplay]).value_or(-1),
254+
_displayStates[activeDisplay]->id());
244255

245-
removeSession(*_displayStates[activeDisplay].activeSession);
256+
removeSession(*_displayStates[activeDisplay]);
246257
}
247258

248259
void TerminalSessionManager::moveTabTo(int position)
249260
{
250-
auto const currentIndexOpt = getSessionIndexOf(_displayStates[activeDisplay].activeSession);
261+
auto const currentIndexOpt = getSessionIndexOf(_displayStates[activeDisplay]);
251262
if (!currentIndexOpt)
252263
return;
253264

@@ -290,13 +301,16 @@ void TerminalSessionManager::moveTabToRight(TerminalSession* session)
290301
}
291302
}
292303

293-
void TerminalSessionManager::removeSession(TerminalSession& thatSession)
304+
void TerminalSessionManager::currentSessionIsTerminated()
294305
{
295-
managerLog()("REMOVE SESSION: session: {}, _sessions.size(): {}", (void*) &thatSession, _sessions.size());
306+
managerLog()("got notified that session is terminated, number of existing sessions: _sessions.size(): {}",
307+
_sessions.size());
308+
return;
309+
}
296310

297-
if (&thatSession == _displayStates[activeDisplay].activeSession
298-
&& _displayStates[activeDisplay].previousActiveSession)
299-
activateSession(_displayStates[activeDisplay].previousActiveSession);
311+
void TerminalSessionManager::removeSession(TerminalSession& thatSession)
312+
{
313+
managerLog()("remove session: session: {}, _sessions.size(): {}", (void*) &thatSession, _sessions.size());
300314

301315
auto i = std::ranges::find(_sessions, &thatSession);
302316
if (i == _sessions.end())
@@ -305,21 +319,36 @@ void TerminalSessionManager::removeSession(TerminalSession& thatSession)
305319
return;
306320
}
307321
_sessions.erase(i);
308-
_app.onExit(thatSession); // TODO: the logic behind that impl could probably be moved here.
309-
310-
_displayStates[activeDisplay].previousActiveSession = [&]() -> TerminalSession* {
311-
auto const currentIndex = getSessionIndexOf(_displayStates[activeDisplay].activeSession).value_or(0);
312-
if (currentIndex + 1 < _sessions.size())
313-
return _sessions[currentIndex + 1];
314-
else if (currentIndex > 0)
315-
return _sessions[currentIndex - 1];
316-
else
317-
return nullptr;
318-
}();
319-
managerLog()("Calculated next \"previous\" session index {}",
320-
getSessionIndexOf(_displayStates[activeDisplay].previousActiveSession).value_or(-1));
322+
tryFindSessionForDisplayOrClose();
323+
//_app.onExit(thatSession); // TODO: the logic behind that impl could probably be moved here.
324+
}
325+
326+
void TerminalSessionManager::tryFindSessionForDisplayOrClose()
327+
{
328+
for (auto& session: _sessions)
329+
{
330+
bool saveToSwitch { true };
331+
// check if session is not used by any display and then switch
332+
for (auto& [display, state]: _displayStates)
333+
{
334+
if ((state == session) && (display != nullptr))
335+
{
336+
saveToSwitch = false;
337+
break;
338+
}
339+
}
340+
341+
if (saveToSwitch)
342+
{
343+
managerLog()("Switching to session: {}", (void*) session);
344+
activateSession(session);
345+
return;
346+
}
347+
}
321348

322349
updateStatusLine();
350+
_displayStates.erase(activeDisplay);
351+
activeDisplay->closeDisplay();
323352
}
324353

325354
void TerminalSessionManager::updateColorPreference(vtbackend::ColorPreference const& preference)

src/contour/TerminalSessionManager.h

Lines changed: 20 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,6 @@
1313
namespace contour
1414
{
1515

16-
struct DisplayState
17-
{
18-
TerminalSession* activeSession = nullptr;
19-
TerminalSession* previousActiveSession = nullptr;
20-
};
21-
2216
/**
2317
* Manages terminal sessions.
2418
*/
@@ -41,14 +35,15 @@ class TerminalSessionManager: public QAbstractListModel
4135
void switchToTabLeft();
4236
void switchToTabRight();
4337
void switchToTab(int position);
44-
void closeTab();
38+
Q_INVOKABLE void closeTab();
4539
void moveTabTo(int position);
4640
void moveTabToLeft(TerminalSession* session);
4741
void moveTabToRight(TerminalSession* session);
4842

4943
void setSession(size_t index);
5044

5145
void removeSession(TerminalSession&);
46+
void currentSessionIsTerminated();
5247

5348
Q_INVOKABLE [[nodiscard]] QVariant data(const QModelIndex& index,
5449
int role = Qt::DisplayRole) const override;
@@ -59,14 +54,16 @@ class TerminalSessionManager: public QAbstractListModel
5954
void updateColorPreference(vtbackend::ColorPreference const& preference);
6055

6156
display::TerminalDisplay* activeDisplay = nullptr;
62-
void FocusOnDisplay(display::TerminalDisplay* display) { activeDisplay = display; }
57+
void FocusOnDisplay(display::TerminalDisplay* display);
6358

6459
void update() { updateStatusLine(); }
6560

6661
private:
6762
contour::TerminalSession* activateSession(TerminalSession* session, bool isNewSession = false);
6863
std::unique_ptr<vtpty::Pty> createPty(std::optional<std::string> cwd);
6964

65+
void tryFindSessionForDisplayOrClose();
66+
7067
[[nodiscard]] std::optional<std::size_t> getSessionIndexOf(TerminalSession* session) const noexcept
7168
{
7269
if (auto const i = std::ranges::find(_sessions, session); i != _sessions.end())
@@ -76,31 +73,30 @@ class TerminalSessionManager: public QAbstractListModel
7673

7774
[[nodiscard]] auto getCurrentSessionIndex() noexcept
7875
{
79-
return getSessionIndexOf(_displayStates[activeDisplay].activeSession).value();
76+
// TODO cache this value
77+
return getSessionIndexOf(_displayStates[activeDisplay]).value();
8078
}
8179

8280
void updateStatusLine()
8381
{
84-
if (!_displayStates[activeDisplay].activeSession)
82+
if (!_displayStates[activeDisplay])
8583
return;
86-
_displayStates[activeDisplay].activeSession->terminal().setGuiTabInfoForStatusLine(
87-
vtbackend::TabsInfo {
88-
.tabs = std::ranges::transform_view(_sessions,
89-
[](auto* session) {
90-
return vtbackend::TabsInfo::Tab {
91-
.name = session->name(),
92-
.color = vtbackend::RGBColor { 0, 0, 0 },
93-
};
94-
})
95-
| ranges::to<std::vector>(),
96-
.activeTabPosition =
97-
1 + getSessionIndexOf(_displayStates[activeDisplay].activeSession).value_or(0),
98-
});
84+
_displayStates[activeDisplay]->terminal().setGuiTabInfoForStatusLine(vtbackend::TabsInfo {
85+
.tabs = std::ranges::transform_view(_sessions,
86+
[](auto* session) {
87+
return vtbackend::TabsInfo::Tab {
88+
.name = session->name(),
89+
.color = vtbackend::RGBColor { 0, 0, 0 },
90+
};
91+
})
92+
| ranges::to<std::vector>(),
93+
.activeTabPosition = 1 + getSessionIndexOf(_displayStates[activeDisplay]).value_or(0),
94+
});
9995
}
10096

10197
ContourGuiApp& _app;
10298
std::chrono::seconds _earlyExitThreshold;
103-
std::unordered_map<display::TerminalDisplay*, DisplayState> _displayStates;
99+
std::unordered_map<display::TerminalDisplay*, TerminalSession*> _displayStates;
104100
std::vector<TerminalSession*> _sessions;
105101
};
106102

src/contour/display/TerminalDisplay.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -831,7 +831,6 @@ void TerminalDisplay::focusInEvent(QFocusEvent* event)
831831

832832
if (_session)
833833
{
834-
managerLog()("Setting active display to {}", (void*) this);
835834
_session->getTerminalManager()->FocusOnDisplay(this);
836835
_session->sendFocusInEvent(); // TODO: paint with "normal" colors
837836
}

0 commit comments

Comments
 (0)