diff --git a/src/Lib/Log.hh b/src/Lib/Log.hh
index 063187a9ea52e5e79fb8a84d0f2fc99c59c4c557..428fb35879cc48849da4d9cd91cea82fcd0e3b60 100644
--- a/src/Lib/Log.hh
+++ b/src/Lib/Log.hh
@@ -197,13 +197,6 @@ public:
         return dispatch;
     }
 
-    template <Derived<LogSinkDispatcher> DispatcherType, typename... Args>
-    DispatcherType *newUnmanagedDispatcher(Args &&...args) noexcept
-    {
-        DispatcherType *dispatch = new DispatcherType(std::forward<Args>(args)...);
-        return dispatch;
-    }
-
     std::shared_ptr<Logger> newLogger(const StringType auto &category) noexcept
     {
         std::shared_ptr<Logger> logger = std::make_shared<Logger>(this, category);
diff --git a/src/UI/LogConsole.cc b/src/UI/LogConsole.cc
index 7428a1a6a569d0c48b3f3994a5b19d82c338fd87..18363b67cab641a9b08ba83ea4cef2a794f9128a 100644
--- a/src/UI/LogConsole.cc
+++ b/src/UI/LogConsole.cc
@@ -2,9 +2,29 @@
 
 using namespace Vivy;
 
-ConsoleLogSinkDispatcher::ConsoleLogSinkDispatcher(QWidget *parent) noexcept
+ConsoleLogSinkDispatcher::ConsoleLogSinkDispatcher() noexcept
     : LogSinkDispatcher(std::string_view{ "console" })
-    , QListWidget(parent)
+{
+}
+
+void
+ConsoleLogSinkDispatcher::handleLogMessage(const std::string_view strv,
+                                           const LogMessage &msg) noexcept
+{
+    if (console)
+        console->handleLogMessage(strv, msg);
+}
+
+void
+ConsoleLogSinkDispatcher::attachLogConsole(LogConsole *widget) noexcept
+{
+    console = widget;
+    if (widget)
+        widget->setDispatcher(shared_from_this());
+}
+
+LogConsole::LogConsole(QWidget *parent) noexcept
+    : QListWidget(parent)
 {
     setSortingEnabled(false);
     setSelectionMode(QAbstractItemView::NoSelection);
@@ -13,8 +33,24 @@ ConsoleLogSinkDispatcher::ConsoleLogSinkDispatcher(QWidget *parent) noexcept
     setStyleSheet(style);
 }
 
+LogConsole::~LogConsole() noexcept
+{
+    if (auto parentDispatcher = dispatcher.lock()) {
+        qDebug() << "Reset parent LogConsole pointer";
+        parentDispatcher->attachLogConsole(nullptr);
+    } else {
+        qCritical() << "Failed to reset LogConsole from parent";
+    }
+}
+
 void
-ConsoleLogSinkDispatcher::setMessageCountLimit(int limit)
+LogConsole::setDispatcher(std::shared_ptr<ConsoleLogSinkDispatcher> ptr) noexcept
+{
+    dispatcher = std::weak_ptr<ConsoleLogSinkDispatcher>(ptr);
+}
+
+void
+LogConsole::setMessageCountLimit(int limit)
 {
     if (limit <= 0)
         throw std::logic_error("Can't pass a negative count!");
@@ -22,8 +58,7 @@ ConsoleLogSinkDispatcher::setMessageCountLimit(int limit)
 }
 
 void
-ConsoleLogSinkDispatcher::handleLogMessage(const std::string_view cat,
-                                           const LogMessage &msg) noexcept
+LogConsole::handleLogMessage(const std::string_view cat, const LogMessage &msg) noexcept
 {
     while (count() >= messageLimit) {
         QListWidgetItem *itemWidget = item(0);
diff --git a/src/UI/LogConsole.hh b/src/UI/LogConsole.hh
index 2525f10e86a7ba936e13566bff1efe2673652005..a388e330d81b87ff10e4ba93ee520bbf1ca30d16 100644
--- a/src/UI/LogConsole.hh
+++ b/src/UI/LogConsole.hh
@@ -5,15 +5,42 @@
 
 namespace Vivy
 {
-class ConsoleLogSinkDispatcher final : public LogSinkDispatcher, public QListWidget {
-    VIVY_UNMOVABLE_OBJECT(ConsoleLogSinkDispatcher)
+class LogConsole;
+class ConsoleLogSinkDispatcher;
+
+class LogConsole final : public QListWidget {
+    VIVY_UNMOVABLE_OBJECT(LogConsole)
 
     int messageLimit{ 1'000 };
+    std::weak_ptr<ConsoleLogSinkDispatcher> dispatcher;
 
 public:
-    explicit ConsoleLogSinkDispatcher(QWidget *parent = nullptr) noexcept;
-    void handleLogMessage(const std::string_view, const LogMessage &) noexcept override;
+    LogConsole(QWidget *parent = nullptr) noexcept;
+    ~LogConsole() noexcept override;
 
     void setMessageCountLimit(int limit);
+    void handleLogMessage(const std::string_view, const LogMessage &) noexcept;
+
+    // Hacky boi to set the `LogConsole *` in the dispatcher to nullptr when
+    // the `LogConsole` is destroyed.
+    void setDispatcher(std::shared_ptr<ConsoleLogSinkDispatcher> ptr) noexcept;
+};
+
+// Log console dispatcher, this is a proxy for the LogConsole which is the real
+// widget, we don't directly set the dispatcher being the widget because the
+// QDockWidget will demete its child on destruction, but the dispatcher is
+// already managed by the std::shared_ptr...
+class ConsoleLogSinkDispatcher final
+    : public LogSinkDispatcher,
+      public std::enable_shared_from_this<ConsoleLogSinkDispatcher> {
+    VIVY_UNMOVABLE_OBJECT(ConsoleLogSinkDispatcher)
+
+    LogConsole *console{ nullptr };
+
+public:
+    explicit ConsoleLogSinkDispatcher() noexcept;
+    void handleLogMessage(const std::string_view, const LogMessage &) noexcept override;
+
+    void attachLogConsole(LogConsole *const) noexcept;
 };
 }
diff --git a/src/VivyApplication.cc b/src/VivyApplication.cc
index de244c0a3cffb4b231736bcdef17e8578990c96f..f511fe9d3f34a840508a268651b7a4658639c04f 100644
--- a/src/VivyApplication.cc
+++ b/src/VivyApplication.cc
@@ -84,13 +84,15 @@ VivyApplication::exec() noexcept
         // Show the main window, also set up the log console
         mainWindowPtr               = std::make_shared<MainWindow>();
         QDockWidget *logConsoleDock = new QDockWidget("Console", mainWindowPtr.get());
+        LogConsole *logConsole      = new LogConsole(mainWindowPtr.get());
         std::shared_ptr<ConsoleLogSinkDispatcher> consoleLogSinkDispatcher =
-            logSink->newDispatcher<ConsoleLogSinkDispatcher>(nullptr);
+            logSink->newDispatcher<ConsoleLogSinkDispatcher>();
 
         DockWidgetTitleBar::addToDock(logConsoleDock);
+        consoleLogSinkDispatcher->attachLogConsole(logConsole);
         logConsoleDock->setAllowedAreas(Qt::BottomDockWidgetArea);
         logConsoleDock->setFeatures(QDockWidget::DockWidgetMovable);
-        logConsoleDock->setWidget(consoleLogSinkDispatcher.get());
+        logConsoleDock->setWidget(logConsole);
         mainWindowPtr->addDockWidget(Qt::BottomDockWidgetArea, logConsoleDock);
         mainWindowPtr->show();