diff --git a/src/UI/DocumentViews/AudioVisualizer.cc b/src/UI/DocumentViews/AudioVisualizer.cc
index 74df942f4a8e8d8068ac872163cded01f4ef2bba..6e6dabd083cfcd8ac3cab0c0630311cc6cd74f38 100644
--- a/src/UI/DocumentViews/AudioVisualizer.cc
+++ b/src/UI/DocumentViews/AudioVisualizer.cc
@@ -85,4 +85,10 @@ AudioVisualizer::printSpectrum(QImage pixmap, AudioContext::StreamPtr stream) no
             &TimingAxis::refreshTicks);
     connect(params->getRebuildSceneButton(), &QPushButton::released, timingScene,
             &TimingScene::rebuildScene);
+    // FIXME: should we replace rootView with a shared_ptr
+    // or is this expected weak_ptr usage?
+    if (auto p = rootView.lock())
+        if (auto sp = p.get())
+            connect(sp, &VivyDocumentView::assSubDocumentChanged, timingScene,
+                    &TimingScene::rebuildScene);
 }
diff --git a/src/UI/DocumentViews/AudioVisualizer/TimingScene.cc b/src/UI/DocumentViews/AudioVisualizer/TimingScene.cc
index 3f16407dd0d38bc7db1c617478a7dbefc10e14e5..3aee8bbcb7bb9c2cb66e05a5e615473335026e8e 100644
--- a/src/UI/DocumentViews/AudioVisualizer/TimingScene.cc
+++ b/src/UI/DocumentViews/AudioVisualizer/TimingScene.cc
@@ -38,13 +38,6 @@ TimingScene::TimingScene(QImage img_, AudioContext::StreamPtr stream,
     , audioStream(stream)
 {
     rebuildScene();
-
-    if (auto p = rootView.lock()) {
-        if (auto assLinesView = p->getAssLinesView()) {
-            connect(assLinesView, &AssLinesView::updateSelectedLines, this,
-                    &TimingScene::updateSelectedLines);
-        }
-    }
 }
 
 void
@@ -105,6 +98,15 @@ TimingScene::rebuildScene()
             }
         }
     }
+
+    // FIXME: do we need to "disconnect" it when assLinesView or *this is destroyed,
+    // or is this taken care of by Qt alone?
+    if (auto p = rootView.lock()) {
+        if (auto assLinesView = p->getAssLinesView()) {
+            connect(assLinesView, &AssLinesView::updateSelectedLines, this,
+                    &TimingScene::updateSelectedLines);
+        }
+    }
 }
 
 void
diff --git a/src/UI/VivyDocumentView.cc b/src/UI/VivyDocumentView.cc
index 0e977afe32c6e0e5a38fb7e10eee20a36c7780b9..dcc34cde4cf2e494a7db55b229a84ef16552691b 100644
--- a/src/UI/VivyDocumentView.cc
+++ b/src/UI/VivyDocumentView.cc
@@ -125,6 +125,8 @@ VivyDocumentView::loadAssView() noexcept
     assModel.reset(new AssLinesModel(document->getAssSubDocument()->getLines()));
     Utils::deleteInternalWidget(assLines);
     assLines->setWidget(new AssLinesView(assModel.get(), assLines));
+
+    emit assSubDocumentChanged();
 }
 
 void
diff --git a/src/UI/VivyDocumentView.hh b/src/UI/VivyDocumentView.hh
index c0dab04d45d5322999f33ebf495da974156bcafd..54adc4952f12384b3d6b35bdc9c35cb2698b9dc6 100644
--- a/src/UI/VivyDocumentView.hh
+++ b/src/UI/VivyDocumentView.hh
@@ -65,5 +65,11 @@ public:
     }
 
     AssLinesModel *getAssLinesModel() const noexcept { return assModel.get(); }
+
+signals:
+    // FIXME: fix default value or just send void?
+    void audioSubDocumentChanged(std::shared_ptr<AudioSubDocument> = nullptr);
+    void videoSubDocumentChanged(std::shared_ptr<VideoSubDocument> = nullptr);
+    void assSubDocumentChanged(std::shared_ptr<AssSubDocument> = nullptr);
 };
 }