diff --git a/extension/content-script.js b/extension/content-script.js --- a/extension/content-script.js +++ b/extension/content-script.js @@ -390,6 +390,27 @@ subtree: true }); + // Observe changes to the tag in case it is updated after the player has started playing + var titleTag = document.querySelector("head > title"); + if (titleTag) { + var titleObserver = new MutationObserver(function (mutations) { + mutations.forEach(function (mutation) { + var pageTitle = mutation.target.textContent; + if (pageTitle) { + sendMessage("mpris", "titlechange", { + pageTitle: pageTitle + }); + } + }); + }); + + titleObserver.observe(titleTag, { + childList: true, // text content is technically a child node + subtree: true, + characterData: true + }); + } + window.addEventListener("beforeunload", function () { // about to navigate to a different page, tell our extension that the player will be gone shortly // we listen for tab closed in the extension but we don't for navigating away as URL change doesn't diff --git a/extension/extension.js b/extension/extension.js --- a/extension/extension.js +++ b/extension/extension.js @@ -288,7 +288,7 @@ } }); -addRuntimeCallback("mpris", ["duration", "timeupdate", "seeking", "seeked", "ratechange", "volumechange"], function (message, sender, action) { +addRuntimeCallback("mpris", ["duration", "timeupdate", "seeking", "seeked", "ratechange", "volumechange", "titlechange"], function (message, sender, action) { if (currentPlayerTabId == sender.tab.id) { sendPortMessage("mpris", action, message); } diff --git a/host/mprisplugin.h b/host/mprisplugin.h --- a/host/mprisplugin.h +++ b/host/mprisplugin.h @@ -134,6 +134,8 @@ void processMetadata(const QJsonObject &data); void processCallbacks(const QJsonArray &data); + QString effectiveTitle() const; + QDBusAbstractAdaptor *m_root; QDBusAbstractAdaptor *m_player; diff --git a/host/mprisplugin.cpp b/host/mprisplugin.cpp --- a/host/mprisplugin.cpp +++ b/host/mprisplugin.cpp @@ -211,6 +211,13 @@ processMetadata(data.value(QStringLiteral("metadata")).toObject()); } else if (event == QLatin1String("callbacks")) { processCallbacks(data.value(QStringLiteral("callbacks")).toArray()); + } else if (event == QLatin1String("titlechange")) { + const QString oldTitle = effectiveTitle(); + m_pageTitle = data.value(QStringLiteral("pageTitle")).toString(); + + if (oldTitle != effectiveTitle()) { + emitPropertyChange(m_player, "Metadata"); + } } else { qWarning() << "Don't know how to handle mpris event" << event; } @@ -349,6 +356,14 @@ emitPropertyChange(m_player, "LoopStatus"); } +QString MPrisPlugin::effectiveTitle() const +{ + if (!m_title.isEmpty()) { + return m_title; + } + return m_pageTitle; +} + QVariantMap MPrisPlugin::metadata() const { QVariantMap metadata; @@ -361,9 +376,9 @@ // the browser window isn't owned by us metadata.insert(QStringLiteral("kde:pid"), getppid()); - const QString &effectiveTitle = !m_title.isEmpty() ? m_title : m_pageTitle; - if (!effectiveTitle.isEmpty()) { - metadata.insert(QStringLiteral("xesam:title"), effectiveTitle); + const QString title = effectiveTitle(); + if (!title.isEmpty()) { + metadata.insert(QStringLiteral("xesam:title"), title); } if (m_url.isValid()) {