[Bug 1088772] [kde-workspace] plasma/generic: KSNI: fix IconThemePath support

Harald Sitter sitter.harald at gmail.com
Mon Dec 17 13:14:57 UTC 2012


Git commit 78cfd7a02fe4e260c5b09e8e055325e4803131bf by Harald Sitter.
Committed on 17/12/2012 at 14:13.
Pushed by sitter into branch 'master'.

KSNI: fix IconThemePath support

IconThemePath is used by a Canonical Patch to enable all Qt apps using
QSystemTrayIcon to transparently provide a SNI with icons exported into
a temporary path. Hence the lack of support breaks icons for all Qt apps
on Ubuntu.

Fix:
- in the dataengine export IconThemePath
- in the systray protocol pick up the value and forward to QML
- in QML set the themePath accordingly on the IconItem
  (requires changes in runtime)

https://bugs.launchpad.net/ubuntu/+source/kde-workspace/+bug/1088772
BUG: 311555
CCMAIL: 1088772 at bugs.launchpad.net
REVIEW: 107702

M  +2    -2    plasma/generic/applets/systemtray/package/contents/ui/StatusNotifierItem.qml
M  +83   -0    plasma/generic/applets/systemtray/protocols/dbussystemtray/dbussystemtraytask.cpp
M  +7    -1    plasma/generic/applets/systemtray/protocols/dbussystemtray/dbussystemtraytask.h
M  +1    -0    plasma/generic/dataengines/statusnotifieritem/statusnotifieritemsource.cpp

http://commits.kde.org/kde-
workspace/78cfd7a02fe4e260c5b09e8e055325e4803131bf

diff --git a/plasma/generic/applets/systemtray/package/contents/ui/StatusNotifierItem.qml b/plasma/generic/applets/systemtray/package/contents/ui/StatusNotifierItem.qml
index c79c8f0..8c1af92 100644
--- a/plasma/generic/applets/systemtray/package/contents/ui/StatusNotifierItem.qml
+++ b/plasma/generic/applets/systemtray/package/contents/ui/StatusNotifierItem.qml
@@ -179,11 +179,11 @@ Item {
 
     // Functions =======================================================================================================
     function __getDefaultIcon() {
-        return __icon_name != "" ? __icon_name : __icon
+        return task.customIcon(__icon_name != "" ? __icon_name : __icon)
     }
 
     function __getAttentionIcon() {
-        return __att_icon_name != "" ? __att_icon_name : __att_icon
+        return task.customIcon(__att_icon_name != "" ? __att_icon_name : __att_icon)
     }
 
     function __processClick(buttons, item) {
diff --git a/plasma/generic/applets/systemtray/protocols/dbussystemtray/dbussystemtraytask.cpp b/plasma/generic/applets/systemtray/protocols/dbussystemtray/dbussystemtraytask.cpp
index 6364272..7cb8272 100644
--- a/plasma/generic/applets/systemtray/protocols/dbussystemtray/dbussystemtraytask.cpp
+++ b/plasma/generic/applets/systemtray/protocols/dbussystemtray/dbussystemtraytask.cpp
@@ -29,7 +29,9 @@
 #include <QtGui/QIcon>
 
 #include <KDE/KJob>
+#include <KDE/KIcon>
 #include <KDE/KIconLoader>
+#include <KDE/KStandardDirs>
 #include <KDE/Plasma/ServiceJob>
 #include <KDE/Plasma/ToolTipManager>
 #include <KDE/Plasma/Applet>
@@ -41,6 +43,7 @@ DBusSystemTrayTask::DBusSystemTrayTask(const QString &serviceName, Plasma::DataE
     : Task(parent),
       m_serviceName(serviceName),
       m_typeId(serviceName),
+      m_customIconLoader(0),
       m_dataEngine(dataEngine),
       m_service(dataEngine->serviceForSource(serviceName)),
       m_isMenu(false),
@@ -121,6 +124,51 @@ void DBusSystemTrayTask::activateHorzScroll(int delta) const
     _activateScroll(delta, "Horizontal");
 }
 
+// Copied from kde-runtime/plasma/declarativeimports/core/iconitem.cpp
+bool static hasm_svgIcon(QVariant source)
+{
+    // Set up compat envrionment, afterwards it is 100% copy'n'pastable.
+    QVariant m_source = source;
+    Plasma::Svg svgIcon;
+    Plasma::Svg *m_svgIcon = &svgIcon;
+
+    //try as a svg toolbar icon
+    m_svgIcon->setImagePath("toolbar-icons/" + source.toString().split("-").first());
+
+    //try as a svg normal icon (like systray)
+    if (!m_svgIcon->isValid() || !m_svgIcon->hasElement(m_source.toString())) {
+        m_svgIcon->setImagePath("icons/" + source.toString().split("-").first());
+    }
+    m_svgIcon->setContainsMultipleImages(true);
+
+    //success?
+    if (m_svgIcon->isValid() && m_svgIcon->hasElement(m_source.toString())) {
+        return true;
+    }
+    return false;
+}
+
+QVariant DBusSystemTrayTask::customIcon(QVariant variant) const
+{
+    if (variant.canConvert<QString>()) {
+        // If we have no icon loader there is nothing to be done with strings.
+        if (!m_customIconLoader)
+            return variant;
+
+        // If an SVG icon can be found (via Plasma theme) the name needs to be
+        // passed along for IconItem to be able to resolve to the theme name as
+        // well.
+        if (hasm_svgIcon(variant))
+            return variant;
+
+        // Otherwise return a QIcon from our custom icon loader.
+        return QVariant(KIcon(variant.toString(), m_customIconLoader));
+    } else {
+        // Most importantly QIcons. Nothing to do for those.
+        return variant;
+    }
+}
+
 void DBusSystemTrayTask::activateVertScroll(int delta) const
 {
     _activateScroll(delta, "Vertical");
@@ -237,6 +285,7 @@ void DBusSystemTrayTask::syncIcons(const Plasma::DataEngine::Data &properties)
     QString att_icon_name        = properties["AttentionIconName"].toString();
     QString movie_path           = properties["AttentionMovieName"].toString();
     QString overlay_icon_name    = properties["OverlayIconName"].value<QString>();
+    QString icon_theme_path      = properties["IconThemePath"].value<QString>();
     bool is_icon_name_changed           = false;
     bool is_att_icon_name_changed       = false;
     bool is_movie_path_changed          = false;
@@ -266,6 +315,40 @@ void DBusSystemTrayTask::syncIcons(const Plasma::DataEngine::Data &properties)
         is_overlay_icon_name_changed = true;
     }
 
+    if (icon_theme_path != m_iconThemePath) {
+        m_iconThemePath = icon_theme_path;
+
+        if (m_customIconLoader) {
+            delete m_customIconLoader;
+            m_customIconLoader = 0;
+        }
+        const QString path = m_iconThemePath;
+        if (!path.isEmpty()) {
+            // FIXME: If last part of path is not "icons", this won't work!
+            QStringList tokens = path.split('/', QString::SkipEmptyParts);
+            if (tokens.length() >= 3 && tokens.takeLast() == QLatin1String("icons")) {
+                QString appName = tokens.takeLast();
+                QString prefix = QChar('/') % tokens.join("/");
+                // FIXME: Fix KIconLoader and KIconTheme so that we can use
+                // our own instance of KStandardDirs
+                KGlobal::dirs()->addResourceDir("data", prefix);
+                // We use a separate instance of KIconLoader to avoid
+                // adding all application dirs to KIconLoader::global(), to
+                // avoid potential icon name clashes between application
+                // icons
+                m_customIconLoader = new KIconLoader(appName, 0 /* dirs */, this);
+            } else {
+                kWarning() << "Wrong IconThemePath" << path << ": too short or does not end with 'icons'";
+            }
+        }
+
+        // Trigger updates
+        is_icon_name_changed = true;
+        is_att_icon_name_changed = true;
+        is_overlay_icon_name_changed = true;
+        emit changedIcons();
+    }
+
     // emit signals
     if (is_icon_name_changed) {
         emit changedIconName();
diff --git a/plasma/generic/applets/systemtray/protocols/dbussystemtray/dbussystemtraytask.h b/plasma/generic/applets/systemtray/protocols/dbussystemtray/dbussystemtraytask.h
index 127b301..9e88913 100644
--- a/plasma/generic/applets/systemtray/protocols/dbussystemtray/dbussystemtraytask.h
+++ b/plasma/generic/applets/systemtray/protocols/dbussystemtray/dbussystemtraytask.h
@@ -25,6 +25,7 @@
 
 #include <Plasma/DataEngine>
 
+class KIconLoader;
 class KJob;
 
 namespace Plasma
@@ -91,7 +92,8 @@ public:
     Q_INVOKABLE void activate1(int x, int y) const;
     Q_INVOKABLE void activate2(int x, int y) const;
     Q_INVOKABLE void activateVertScroll(int delta) const;
-    Q_INVOKABLE void activateHorzScroll(int delta) const ;
+    Q_INVOKABLE void activateHorzScroll(int delta) const;
+    Q_INVOKABLE QVariant customIcon(QVariant variant) const;
 
 signals:
     void changedIcons(); // if icons, icon names, movie path are changed
@@ -128,9 +130,13 @@ private:
     QString m_shortcut;
     QString m_moviePath;
     QString m_overlayIconName;
+    QString m_iconThemePath;
     QString m_tooltipTitle;
     QString m_tooltipText;
     QIcon   m_tooltipIcon;
+
+    KIconLoader *m_customIconLoader;
+
     Plasma::DataEngine *m_dataEngine;
     Plasma::Service *m_service;
     bool m_isMenu;
diff --git a/plasma/generic/dataengines/statusnotifieritem/statusnotifieritemsource.cpp b/plasma/generic/dataengines/statusnotifieritem/statusnotifieritemsource.cpp
index 61d85f8..8baec40 100644
--- a/plasma/generic/dataengines/statusnotifieritem/statusnotifieritemsource.cpp
+++ b/plasma/generic/dataengines/statusnotifieritem/statusnotifieritemsource.cpp
@@ -232,6 +232,7 @@ void StatusNotifierItemSource::refreshCallback(QDBusPendingCallWatcher *call)
                 }
             }
         }
+        setData("IconThemePath", properties["IconThemePath"]);
 
         setData("Category", properties["Category"]);
         setData("Status", properties["Status"]);


** Changed in: kde-workspace (Ubuntu)
       Status: Triaged => Fix Committed

-- 
You received this bug notification because you are a member of Kubuntu
Bugs, which is subscribed to kde-workspace in Ubuntu.
https://bugs.launchpad.net/bugs/1088772

Title:
  Broken icons in plasma tray

To manage notifications about this bug go to:
https://bugs.launchpad.net/ubuntu/+source/kde-workspace/+bug/1088772/+subscriptions




More information about the kubuntu-bugs mailing list