diff --git a/applets/systemtray/package/contents/ui/items/StatusNotifierItem.qml b/applets/systemtray/package/contents/ui/items/StatusNotifierItem.qml --- a/applets/systemtray/package/contents/ui/items/StatusNotifierItem.qml +++ b/applets/systemtray/package/contents/ui/items/StatusNotifierItem.qml @@ -27,7 +27,7 @@ text: model.Title mainText: model.ToolTipTitle !== "" ? model.ToolTipTitle : model.Title subText: model.ToolTipSubTitle - icon: model.ToolTipIcon !== "" ? model.ToolTipIcon : model.Icon ? model.Icon : model.IconName + icon: model.ToolTipIcon !== "" ? model.ToolTipIcon : model.IconName ? model.IconName : model.IconPixmap textFormat: Text.AutoText PlasmaCore.IconItem { @@ -37,17 +37,54 @@ source: { if (model.status === PlasmaCore.Types.NeedsAttentionStatus) { - if (model.AttentionIcon) { - return model.AttentionIcon - } if (model.AttentionIconName) { return model.AttentionIconName } + if (model.AttentionIconPixmap) { + return model.AttentionIconPixmap + } } - return model.Icon ? model.Icon : model.IconName + return model.IconName ? model.IconName : model.IconPixmap } active: taskIcon.containsMouse } + // IconItem.overlays only supports names so we need a second item for the overlay, using the same + // positioning that KIconLoader::drawOverlays uses that IconItem uses internally + PlasmaCore.IconItem { + id: overlayIconItem + parent: iconItem.parent + source: { + if (model.OverlayIconName) { + return model.OverlayIconName + } + if (model.OverlayIconPixmap) { + return model.OverlayIconPixmap + } + return ""; + } + width: { + if (iconItem.width < units.iconSizes.medium) { + return units.iconSizes.small / 2; + } + if (iconItem.width <= units.iconSizes.large) { + return units.iconSizes.small + } + if (iconItem.width <= 96) { + return units.iconSizes.smallMedium + } + if (iconItem.width < 256) { + return units.iconSizes.medium + } + return units.iconSizes.large; + } + height: width + anchors { + right: iconItem.right + bottom: iconItem.bottom + bottomMargin: Math.floor(0.05 * iconItem.width) + rightMargin: anchors.bottomMargin + } + } onContextMenu: { openContextMenu(plasmoid.nativeInterface.popupPosition(taskIcon, mouse.x, mouse.y)) diff --git a/applets/systemtray/systemtraymodel.h b/applets/systemtray/systemtraymodel.h --- a/applets/systemtray/systemtraymodel.h +++ b/applets/systemtray/systemtraymodel.h @@ -87,17 +87,18 @@ public: enum class Role { DataEngineSource = static_cast(BaseModel::BaseRole::LastBaseRole) + 100, - AttentionIcon, AttentionIconName, + AttentionIconPixmap, AttentionMovieName, Category, - Icon, IconName, + IconPixmap, IconThemePath, IconsChanged, Id, ItemIsMenu, OverlayIconName, + OverlayIconPixmap, Status, StatusChanged, Title, diff --git a/applets/systemtray/systemtraymodel.cpp b/applets/systemtray/systemtraymodel.cpp --- a/applets/systemtray/systemtraymodel.cpp +++ b/applets/systemtray/systemtraymodel.cpp @@ -235,17 +235,18 @@ QHash roles = BaseModel::roleNames(); roles.insert(static_cast(Role::DataEngineSource), QByteArrayLiteral("DataEngineSource")); - roles.insert(static_cast(Role::AttentionIcon), QByteArrayLiteral("AttentionIcon")); roles.insert(static_cast(Role::AttentionIconName), QByteArrayLiteral("AttentionIconName")); + roles.insert(static_cast(Role::AttentionIconPixmap), QByteArrayLiteral("AttentionIconPixmap")); roles.insert(static_cast(Role::AttentionMovieName), QByteArrayLiteral("AttentionMovieName")); roles.insert(static_cast(Role::Category), QByteArrayLiteral("Category")); - roles.insert(static_cast(Role::Icon), QByteArrayLiteral("Icon")); roles.insert(static_cast(Role::IconName), QByteArrayLiteral("IconName")); + roles.insert(static_cast(Role::IconPixmap), QByteArrayLiteral("IconPixmap")); roles.insert(static_cast(Role::IconThemePath), QByteArrayLiteral("IconThemePath")); roles.insert(static_cast(Role::IconsChanged), QByteArrayLiteral("IconsChanged")); roles.insert(static_cast(Role::Id), QByteArrayLiteral("Id")); roles.insert(static_cast(Role::ItemIsMenu), QByteArrayLiteral("ItemIsMenu")); roles.insert(static_cast(Role::OverlayIconName), QByteArrayLiteral("OverlayIconName")); + roles.insert(static_cast(Role::OverlayIconPixmap), QByteArrayLiteral("OverlayIconPixmap")); roles.insert(static_cast(Role::Status), QByteArrayLiteral("Status")); roles.insert(static_cast(Role::StatusChanged), QByteArrayLiteral("StatusChanged")); roles.insert(static_cast(Role::Title), QByteArrayLiteral("Title")); @@ -326,17 +327,18 @@ } dataItem->setData(sourceName, static_cast(Role::DataEngineSource)); - updateItemData(dataItem, data, Role::AttentionIcon); updateItemData(dataItem, data, Role::AttentionIconName); + updateItemData(dataItem, data, Role::AttentionIconPixmap); updateItemData(dataItem, data, Role::AttentionMovieName); updateItemData(dataItem, data, Role::Category); - updateItemData(dataItem, data, Role::Icon); + updateItemData(dataItem, data, Role::IconPixmap); updateItemData(dataItem, data, Role::IconName); updateItemData(dataItem, data, Role::IconThemePath); updateItemData(dataItem, data, Role::IconsChanged); updateItemData(dataItem, data, Role::Id); updateItemData(dataItem, data, Role::ItemIsMenu); updateItemData(dataItem, data, Role::OverlayIconName); + updateItemData(dataItem, data, Role::OverlayIconPixmap); updateItemData(dataItem, data, Role::Status); updateItemData(dataItem, data, Role::StatusChanged); updateItemData(dataItem, data, Role::Title); diff --git a/applets/systemtray/tests/statusnotifier/statusnotifiertest.cpp b/applets/systemtray/tests/statusnotifier/statusnotifiertest.cpp --- a/applets/systemtray/tests/statusnotifier/statusnotifiertest.cpp +++ b/applets/systemtray/tests/statusnotifier/statusnotifiertest.cpp @@ -63,6 +63,7 @@ connect(updateButton, &QPushButton::clicked, this, &StatusNotifierTest::updateNotifier); connect(jobEnabledCheck, &QCheckBox::toggled, this, &StatusNotifierTest::enableJob); updateUi(); + iconName->setText(QStringLiteral("plasma")); show(); raise(); log(QStringLiteral("started")); @@ -126,7 +127,6 @@ statusPassive->setEnabled(!statusAuto->isChecked()); statusNeedsAttention->setEnabled(!statusAuto->isChecked()); - iconName->setText(d->systemNotifier->iconName()); tooltipText->setText(d->systemNotifier->toolTipTitle()); tooltipSubtext->setText(d->systemNotifier->toolTipSubTitle()); @@ -163,7 +163,12 @@ } d->systemNotifier->setStatus(s); - d->systemNotifier->setIconByName(iconName->text()); + iconPixmapCheckbox->isChecked() ? d->systemNotifier->setIconByPixmap(QIcon::fromTheme(iconName->text())) + : d->systemNotifier->setIconByName(iconName->text()); + overlayIconPixmapCheckbox->isChecked() ? d->systemNotifier->setOverlayIconByPixmap(QIcon::fromTheme(overlayIconName->text())) + : d->systemNotifier->setOverlayIconByName(overlayIconName->text()); + attentionIconPixmapCheckbox->isChecked() ? d->systemNotifier->setAttentionIconByPixmap(QIcon::fromTheme(attentionIconName->text())) + : d->systemNotifier->setAttentionIconByName(attentionIconName->text()); d->systemNotifier->setToolTip(iconName->text(), tooltipText->text(), tooltipSubtext->text()); diff --git a/applets/systemtray/tests/statusnotifier/statusnotifiertest.ui b/applets/systemtray/tests/statusnotifier/statusnotifiertest.ui --- a/applets/systemtray/tests/statusnotifier/statusnotifiertest.ui +++ b/applets/systemtray/tests/statusnotifier/statusnotifiertest.ui @@ -6,8 +6,8 @@ 0 0 - 434 - 572 + 471 + 692 @@ -21,14 +21,13 @@ - - + .. - 1 + 0 @@ -110,10 +109,7 @@ - - - - + <b>ToolTip</b> @@ -126,16 +122,80 @@ - - - Update + + + + + + Icon + + + + + + + AttentionIcon + + + + + + + OverlayIcon + + + + + + + + + + + + Use Pixmap + + + + + + + + + + + + + + Use Pixmap + + + + + + + + + + + + + + Use Pixmap + + + + + + + diff --git a/dataengines/statusnotifieritem/statusnotifieritemsource.cpp b/dataengines/statusnotifieritem/statusnotifieritemsource.cpp --- a/dataengines/statusnotifieritem/statusnotifieritemsource.cpp +++ b/dataengines/statusnotifieritem/statusnotifieritemsource.cpp @@ -87,17 +87,21 @@ //this means it does not re-evaluate what bindings exist (watchedRoleIds) - and we get properties that don't bind and thus system tray icons //by setting everything up-front so that we have all role names when we call the first checkForUpdate() + // TODO Plasma 6 remove combined "*Icon" properties and only expose the raw "*IconName" and "*IconPixmap" properties setData(QStringLiteral("AttentionIcon"), QIcon()); setData(QStringLiteral("AttentionIconName"), QString()); + setData(QStringLiteral("AttentionIconPixmap"), QIcon()); setData(QStringLiteral("AttentionMovieName"), QString()); setData(QStringLiteral("Category"), QString()); setData(QStringLiteral("Icon"), QIcon()); setData(QStringLiteral("IconName"), QString()); + setData(QStringLiteral("IconPixmap"), QIcon()); setData(QStringLiteral("IconsChanged"), false); setData(QStringLiteral("IconThemePath"), QString()); setData(QStringLiteral("Id"), QString()); setData(QStringLiteral("ItemIsMenu"), false); setData(QStringLiteral("OverlayIconName"), QString()); + setData(QStringLiteral("OverlayIconPixmap"), QIcon()); setData(QStringLiteral("StatusChanged"), false); setData(QStringLiteral("Status"), QString()); setData(QStringLiteral("TitleChanged"), false); @@ -273,58 +277,59 @@ { KDbusImageVector image; QIcon icon; - QString iconName; - + QString overlayIconName = properties[QStringLiteral("OverlayIconName")].toString(); + setData(QStringLiteral("OverlayIconName"), overlayIconName); properties[QStringLiteral("OverlayIconPixmap")].value() >> image; if (image.isEmpty()) { - QString iconName = properties[QStringLiteral("OverlayIconName")].toString(); - setData(QStringLiteral("OverlayIconName"), iconName); - if (!iconName.isEmpty()) { - overlayNames << iconName; - overlay = QIcon(new KIconEngine(iconName, iconLoader())); + if (!overlayIconName.isEmpty()) { + overlayNames << overlayIconName; + overlay = QIcon(new KIconEngine(overlayIconName, iconLoader())); + setData(QStringLiteral("OverlayIconPixmap"), QVariant()); } } else { overlay = imageVectorToPixmap(image); + setData(QStringLiteral("OverlayIconPixmap"), overlay); } - + QString iconName = properties[QStringLiteral("IconName")].toString(); + setData(QStringLiteral("IconName"), iconName); properties[QStringLiteral("IconPixmap")].value() >> image; if (image.isEmpty()) { - iconName = properties[QStringLiteral("IconName")].toString(); if (!iconName.isEmpty()) { icon = QIcon(new KIconEngine(iconName, iconLoader(), overlayNames)); - if (overlayNames.isEmpty() && !overlay.isNull()) { overlayIcon(&icon, &overlay); } } + setData(QStringLiteral("IconPixmap"), QVariant()); } else { icon = imageVectorToPixmap(image); + setData(QStringLiteral("IconPixmap"), icon); if (!icon.isNull() && !overlay.isNull()) { overlayIcon(&icon, &overlay); } } setData(QStringLiteral("Icon"), icon.isNull() ? QVariant() : icon); - setData(QStringLiteral("IconName"), iconName); } //Attention icon { KDbusImageVector image; QIcon attentionIcon; - + QString attentionIconName = properties[QStringLiteral("AttentionIconName")].toString(); + setData(QStringLiteral("AttentionIconName"), attentionIconName); properties[QStringLiteral("AttentionIconPixmap")].value() >> image; if (image.isEmpty()) { QString iconName = properties[QStringLiteral("AttentionIconName")].toString(); - setData(QStringLiteral("AttentionIconName"), iconName); if (!iconName.isEmpty()) { attentionIcon = QIcon(new KIconEngine(iconName, iconLoader(), overlayNames)); - if (overlayNames.isEmpty() && !overlay.isNull()) { overlayIcon(&attentionIcon, &overlay); } } + setData(QStringLiteral("AttentionIconPixmap"), QVariant()); } else { attentionIcon = imageVectorToPixmap(image); + setData(QStringLiteral("AttentionIconPixmap"), attentionIcon); if (!attentionIcon.isNull() && !overlay.isNull()) { overlayIcon(&attentionIcon, &overlay); } @@ -377,7 +382,6 @@ } } } - checkForUpdate(); call->deleteLater(); }