diff --git a/src/ui/qml/session/src/session_model_ui.cpp b/src/ui/qml/session/src/session_model_ui.cpp index bc4dc8362..f7fa9a371 100644 --- a/src/ui/qml/session/src/session_model_ui.cpp +++ b/src/ui/qml/session/src/session_model_ui.cpp @@ -627,6 +627,17 @@ void SessionModel::processChildren(const nlohmann::json &rj, const QModelIndex & emit dataChanged(parent_index, parent_index, roles); } + // After populating session/playlist children, re-trigger the viewport and + // current container lookup. On session restore the initial lookup fires + // before the model tree is fully built (the children arrive asynchronously), + // so timelines inside playlists are not yet findable. Re-checking here + // ensures the timeline panel picks up the active container once its node + // actually exists in the tree. + if (type == "Session" || type == "Container List" || type == "Playlist") { + updateCurrentMediaContainerIndexFromBackend(); + updateViewportCurrentMediaContainerIndexFromBackend(); + } + emit jsonChanged(); CHECK_SLOW_WATCHER_FAST() diff --git a/ui/qml/xstudio/views/timeline/XsTimeline.qml b/ui/qml/xstudio/views/timeline/XsTimeline.qml index 6a5789b80..5302bc30f 100644 --- a/ui/qml/xstudio/views/timeline/XsTimeline.qml +++ b/ui/qml/xstudio/views/timeline/XsTimeline.qml @@ -306,6 +306,30 @@ Rectangle { initTimeline() }}(), 50); + } else if (viewedMediaSetProperties.index.valid && viewedMediaSetProperties.values.typeRole == "Playlist") { + // When restoring a session, the viewed container may be a Playlist + // rather than a Timeline. Find the first Timeline child inside the + // Playlist's Container List (row 2) and initialise from it. + let containerListIndex = theSessionData.index(2, 0, viewedMediaSetProperties.index) + let childCount = theSessionData.rowCount(containerListIndex) + for (let i = 0; i < childCount; i++) { + let childIndex = theSessionData.index(i, 0, containerListIndex) + if (theSessionData.get(childIndex, "typeRole") == "Timeline") { + // Switch the viewed container to this Timeline so the + // playhead and viewport are correctly attached. + theSessionData.viewportCurrentMediaContainerIndex = childIndex + return + } + } + // No timeline children found (or not yet loaded). If the container + // list is empty the data may still be arriving asynchronously, so + // retry after a short delay. + if (childCount == 0 && !timeline_items.rootIndex.valid) { + callbackTimer.setTimeout(function() { return function() { + viewedMediaSetChanged() + }}(), 250); + } + } else if (!timeline_items.rootIndex.valid) { // if the user has selected something that is not a timeline (playlist, // subset etc.), we do not update our index here (unless the timeline