diff --git a/src/api/call.h b/src/api/call.h
index a6545a40792d9bdd119e944988b74cc80e52a162..c95e6fb1b93e984d95dfece6ba1ee0c29e34814e 100644
--- a/src/api/call.h
+++ b/src/api/call.h
@@ -26,6 +26,8 @@
 #include <ctime>
 #include <chrono>
 
+#include "typedefs.h"
+
 namespace lrc
 {
 
@@ -143,6 +145,7 @@ struct Info
     bool videoMuted = false;
     bool isAudioOnly = false;
     Layout layout = Layout::GRID;
+    VectorMapStringString participantsInfos = {};
 };
 
 static inline bool
diff --git a/src/api/newcallmodel.h b/src/api/newcallmodel.h
index c1fe7bac0857dbaef72b403541e88856f9acf436..86e1ddf0403796a7bd4e3616dc304da09e734df1 100644
--- a/src/api/newcallmodel.h
+++ b/src/api/newcallmodel.h
@@ -241,6 +241,11 @@ Q_SIGNALS:
      * @param callId
      */
     void callStatusChanged(const QString& callId, int code) const;
+    /**
+     * Emitted when the rendered image changed
+     * @param confId
+     */
+    void onParticipantsChanged(const QString& confId) const;
     /**
      * Emitted when a call starts
      * @param callId
diff --git a/src/newcallmodel.cpp b/src/newcallmodel.cpp
index 05e8ef6000a69e80893e3da2da8e86345530f211..13fb5a370ad0c71c0b236f160827d1377fac83bb 100644
--- a/src/newcallmodel.cpp
+++ b/src/newcallmodel.cpp
@@ -36,6 +36,7 @@
 #include "dbus/callmanager.h"
 #include "vcard.h"
 #include "video/renderer.h"
+#include "typedefs.h"
 
 // Ring daemon
 #include <media_const.h>
@@ -183,6 +184,12 @@ public Q_SLOTS:
      * @param urgentCount
      */
     void slotVoiceMailNotify(const QString& accountId, int newCount, int oldCount, int urgentCount);
+    /**
+     * Listen from CallManager when a conference layout is updated
+     * @param confId
+     * @param infos
+     */
+    void slotOnConferenceInfosUpdated(const QString& confId, const VectorMapStringString& infos);
 };
 
 NewCallModel::NewCallModel(const account::Info& owner, const CallbacksHandler& callbacksHandler)
@@ -506,6 +513,7 @@ NewCallModelPimpl::NewCallModelPimpl(const NewCallModel& linked, const Callbacks
     connect(&callbacksHandler, &CallbacksHandler::incomingVCardChunk, this, &NewCallModelPimpl::slotincomingVCardChunk);
     connect(&callbacksHandler, &CallbacksHandler::conferenceCreated, this , &NewCallModelPimpl::slotConferenceCreated);
     connect(&callbacksHandler, &CallbacksHandler::voiceMailNotify, this, &NewCallModelPimpl::slotVoiceMailNotify);
+    connect(&CallManager::instance(), &CallManagerInterface::onConferenceInfosUpdated, this, &NewCallModelPimpl::slotOnConferenceInfosUpdated);
 
 #ifndef ENABLE_LIBWRAP
     // Only necessary with dbus since the daemon runs separately
@@ -543,6 +551,8 @@ NewCallModelPimpl::initCallFromDaemon()
             callInfo->videoMuted = details["VIDEO_MUTED"] == "true";
             callInfo->audioMuted = details["AUDIO_MUTED"] == "true";
             callInfo->type = call::Type::DIALOG;
+            VectorMapStringString infos = CallManager::instance().getConferenceInfos(callId);
+            callInfo->participantsInfos = infos;
             calls.emplace(callId, std::move(callInfo));
             // NOTE/BUG: the videorenderer can't know that the client has restarted
             // So, for now, a user will have to manually restart the medias until
@@ -575,6 +585,8 @@ NewCallModelPimpl::initConferencesFromDaemon()
         }
         if (!isForThisAccount) break;
         callInfo->type = call::Type::CONFERENCE;
+        VectorMapStringString infos = CallManager::instance().getConferenceInfos(callId);
+        callInfo->participantsInfos = infos;
         calls.emplace(callId, std::move(callInfo));
     }
 }
@@ -832,6 +844,23 @@ NewCallModelPimpl::slotVoiceMailNotify(const QString& accountId, int newCount, i
     emit linked.voiceMailNotify(accountId, newCount, oldCount, urgentCount);
 }
 
+void
+NewCallModelPimpl::slotOnConferenceInfosUpdated(const QString& confId, const VectorMapStringString& infos)
+{
+    auto it = calls.find(confId);
+    if (it == calls.end() or not it->second)
+        return;
+
+    qDebug() << "New conference layout received for call " << confId;
+
+    // if Jami, remove @ring.dht
+    it->second->participantsInfos = infos;
+    for (auto& i: it->second->participantsInfos)
+        i["uri"].replace("@ring.dht", "");
+
+    emit linked.onParticipantsChanged(confId);
+}
+
 bool
 NewCallModel::hasCall(const QString& callId) const
 {
@@ -850,7 +879,7 @@ NewCallModelPimpl::slotConferenceCreated(const QString& confId)
     QStringList callList = CallManager::instance().getParticipantList(confId);
     foreach(const auto& call, callList) {
         emit linked.callAddedToConference(call, confId);
-        // Remove acll from pendingConferences_
+        // Remove call from pendingConferences_
         pendingConferences_.erase(call);
     }
 
diff --git a/src/qtwrapper/callmanager_wrap.h b/src/qtwrapper/callmanager_wrap.h
index bd168d3be1e062b3f7ce16ca722b4ccf95e837e9..292f28e994294bbbf94b241070385445fe3a870c 100644
--- a/src/qtwrapper/callmanager_wrap.h
+++ b/src/qtwrapper/callmanager_wrap.h
@@ -118,6 +118,11 @@ public:
                     LOG_DRING_SIGNAL2("onRtcpReportReceived",QString(callID.c_str()), convertStringInt(report));
                     Q_EMIT onRtcpReportReceived(QString(callID.c_str()), convertStringInt(report));
                 }),
+            exportable_callback<CallSignal::OnConferenceInfosUpdated>(
+                [this] (const std::string& confId, const std::vector<std::map<std::string, std::string>>& infos) {
+                    LOG_DRING_SIGNAL2("onConferenceInfosUpdated",QString(confId.c_str()),convertVecMap(infos));
+                    Q_EMIT onConferenceInfosUpdated(QString(confId.c_str()), convertVecMap(infos));
+                }),
             exportable_callback<CallSignal::PeerHold>(
                 [this] (const std::string &callID, bool state) {
                     LOG_DRING_SIGNAL2("peerHold",QString(callID.c_str()), state);
@@ -201,6 +206,14 @@ public Q_SLOTS: // METHODS
         return temp;
     }
 
+    VectorMapStringString getConferenceInfos(const QString &confId)
+    {
+        VectorMapStringString temp =
+            convertVecMap(DRing::getConferenceInfos(
+                confId.toStdString()));
+        return temp;
+    }
+
     QString getConferenceId(const QString &callID)
     {
         QString temp(DRing::getConferenceId(callID.toStdString()).c_str());
@@ -399,6 +412,7 @@ Q_SIGNALS: // SIGNALS
     void conferenceRemoved(const QString &confID);
     void recordingStateChanged(const QString &callID, bool recordingState);
     void onRtcpReportReceived(const QString &callID, MapStringInt report);
+    void onConferenceInfosUpdated(const QString &confId, VectorMapStringString infos);
     void audioMuted(const QString &callID, bool state);
     void videoMuted(const QString &callID, bool state);
     void peerHold(const QString &callID, bool state);
diff --git a/src/qtwrapper/configurationmanager_wrap.h b/src/qtwrapper/configurationmanager_wrap.h
index 3d2730468db8c2f1fcc8e4d357bec080af42e81b..5fa19498fd6d1d2fc0424ba6bf9085ff88cb46a7 100644
--- a/src/qtwrapper/configurationmanager_wrap.h
+++ b/src/qtwrapper/configurationmanager_wrap.h
@@ -722,7 +722,7 @@ public Q_SLOTS: // METHODS
     }
 
     bool setMessageDisplayed(const QString& accountId, const QString& contactId, const QString& messageId, int status) {
-        DRing::setMessageDisplayed(accountId.toStdString(), contactId.toStdString(), messageId.toStdString(), status);
+        return DRing::setMessageDisplayed(accountId.toStdString(), contactId.toStdString(), messageId.toStdString(), status);
     }
 
 Q_SIGNALS: // SIGNALS