diff --git a/app/qml/Main.qml b/app/qml/Main.qml index ab26331..24fb203 100644 --- a/app/qml/Main.qml +++ b/app/qml/Main.qml @@ -191,7 +191,14 @@ ApplicationWindow { settings.syncPick() } - Component.onCompleted: win.reloadSessions() + /* The engine opens the workspace's last session (cst_agent_open()), so the + * window is created with a transcript already in it: draw it, or the pane + * starts empty while the sidebar points at the very session it belongs to. + * A switch draws it the same way (the sessionChanged handler below). */ + Component.onCompleted: { + win.reloadSessions() + win.replay() + } // ---- the shell ------------------------------------------------------- header: ToolBar { diff --git a/app/src/core/AgentCore.cpp b/app/src/core/AgentCore.cpp index 118b5f8..07f9293 100644 --- a/app/src/core/AgentCore.cpp +++ b/app/src/core/AgentCore.cpp @@ -551,8 +551,13 @@ bool AgentCore::newSession() { bool AgentCore::switchSession(const QString &id) { if (!m_agent || m_running || id.isEmpty()) return false; - if (id == sessionId()) + if (id == sessionId()) { + /* A click on the row of the session that is already open: nothing to + * switch, but the window still wants the transcript (the row is not a + * dead spot), and sessionChanged is what draws it. */ + emit sessionChanged(); return true; + } if (cst_agent_switch_session(m_agent, id.toUtf8().constData()) != 0) return false; afterSessionChange(); diff --git a/app/src/ui/UiTest.cpp b/app/src/ui/UiTest.cpp index c855fe5..16a21db 100644 --- a/app/src/ui/UiTest.cpp +++ b/app/src/ui/UiTest.cpp @@ -196,6 +196,15 @@ int runUiTest(AgentCore &core, const QString &size) { } } + /* A workspace is never empty on a second run: the engine opens the last + * session of the store (cst_agent_open()), so the window is created with a + * transcript already in the engine. Put one there before the QML loads, + * which is exactly what a restart looks like. */ + const QString resumed = + writeFixtureSession(core.workspace(), QStringLiteral("20260101-115959-on")); + check(!resumed.isEmpty() && core.switchSession(resumed), + QStringLiteral("the engine has a session open before the window exists")); + QQmlApplicationEngine engine; installThemeIcons(&engine); /* the window's icons, same as main() */ /* image://cstattach/: the session's stored images, pointed at the session @@ -219,6 +228,15 @@ int runUiTest(AgentCore &core, const QString &size) { } QTest::qWait(250); + /* --- the window opens on the session the engine already had ----------- */ + { + QQuickItem *tr = item(win, QStringLiteral("transcript")); + const int rows = tr ? tr->property("count").toInt() : -1; + check(rows == 5, + QStringLiteral("the open session is on screen at startup (%1 rows)") + .arg(rows)); + } + QQuickItem *docked = item(win, QStringLiteral("dockedSidebar")); QQuickItem *navButton = item(win, QStringLiteral("navButton")); QQuickItem *navPanel = item(win, QStringLiteral("navPanel")); @@ -464,8 +482,10 @@ int runUiTest(AgentCore &core, const QString &size) { /* The dialog drives the same two engine calls: open it, fold the advanced * section out and put a provider in through the form. */ clickMouse(win, QStringLiteral("settingsButton")); + QTest::qWait(150); /* the dialog's layout settles before it is clicked into */ if (panel && mfield) { clickMouse(win, QStringLiteral("settingsAdvanced")); + QTest::qWait(150); /* the fold-out re-lays the body out */ QQuickItem *nfield = item(win, QStringLiteral("advName")); QQuickItem *bfield = item(win, QStringLiteral("advBase")); check(nfield && nfield->isVisible(), QStringLiteral("Advanced options opens in the dialog")); diff --git a/include/cst_version.h b/include/cst_version.h index e694393..7fd7986 100644 --- a/include/cst_version.h +++ b/include/cst_version.h @@ -3,7 +3,7 @@ #define CST_VERSION_MAJOR 0 #define CST_VERSION_MINOR 9 -#define CST_VERSION_PATCH 0 +#define CST_VERSION_PATCH 1 #define CST_VERSION_STR_(x) #x #define CST_VERSION_STR(x) CST_VERSION_STR_(x)