diff --git a/applets/notifications/package/contents/ui/NotificationItem.qml b/applets/notifications/package/contents/ui/NotificationItem.qml
--- a/applets/notifications/package/contents/ui/NotificationItem.qml
+++ b/applets/notifications/package/contents/ui/NotificationItem.qml
@@ -30,7 +30,7 @@
MouseArea {
id: notificationItem
width: parent.width
- implicitHeight: Math.max(appIconItem.visible || imageItem.visible ? units.iconSizes.large : 0, mainLayout.height)
+ implicitHeight: Math.max(appIconItem.valid || imageItem.nativeWidth > 0 ? units.iconSizes.large : 0, mainLayout.height)
// We need to clip here because we support displaying images through
// and if we don't clip, they will be painted over the borders of the dialog/item
@@ -153,7 +153,7 @@
left: parent.left
}
- visible: !imageItem.visible && valid
+ visible: imageItem.nativeWidth == 0 && valid
animated: false
}
@@ -170,7 +170,7 @@
anchors {
top: parent.top
- left: appIconItem.visible || imageItem.visible ? appIconItem.right : parent.left
+ left: appIconItem.valid || imageItem.nativeWidth > 0 ? appIconItem.right : parent.left
right: parent.right
leftMargin: units.smallSpacing
}
@@ -244,7 +244,7 @@
// If there is a big notification followed by a small one, the height
// of the popup does not always shrink back, so this forces it to
// height=0 when those are invisible. -1 means "default to implicitHeight"
- Layout.maximumHeight: bodyText.visible || actionsColumn.visible ? -1 : 0
+ Layout.maximumHeight: bodyText.length > 0 || notificationItem.actions.count > 0 ? -1 : 0
PlasmaExtras.ScrollArea {
id: bodyTextScrollArea
diff --git a/applets/notifications/package/contents/ui/NotificationPopup.qml b/applets/notifications/package/contents/ui/NotificationPopup.qml
--- a/applets/notifications/package/contents/ui/NotificationPopup.qml
+++ b/applets/notifications/package/contents/ui/NotificationPopup.qml
@@ -53,33 +53,34 @@
function populatePopup(notification) {
notificationProperties = notification
notificationTimer.interval = notification.expireTimeout
- notificationTimer.restart()
-
+ notificationTimer.restart();
+ //temporarly disable height binding, avoids an useless window resize when removing the old actions
+ heightBinding.when = false;
// notification.actions is a JS array, but we can easily append that to our model
notificationItem.actions.clear()
notificationItem.actions.append(notificationProperties.actions)
+ //enable height binding again, finally do the resize
+ heightBinding.when = true;
}
function clearPopup() {
notificationProperties = {}
notificationItem.actions.clear()
}
- Behavior on y {
- NumberAnimation {
- duration: units.longDuration
- easing.type: Easing.OutQuad
- }
- }
-
mainItem: NotificationItem {
id: notificationItem
hoverEnabled: true
LayoutMirroring.enabled: Qt.application.layoutDirection === Qt.RightToLeft
LayoutMirroring.childrenInherit: true
- height: implicitHeight
+ //the binding needs to be disabled when re-populating actions, to minimize resizes
+ Binding on height {
+ id: heightBinding
+ value: notificationItem.implicitHeight
+ when: true
+ }
Timer {
id: notificationTimer
diff --git a/applets/notifications/plugin/notificationshelper.h b/applets/notifications/plugin/notificationshelper.h
--- a/applets/notifications/plugin/notificationshelper.h
+++ b/applets/notifications/plugin/notificationshelper.h
@@ -71,7 +71,6 @@
// void plasmoidScreenChanged();
private Q_SLOTS:
- void onPopupShown();
void onPopupClosed();
void processQueues();
void processShow();
diff --git a/applets/notifications/plugin/notificationshelper.cpp b/applets/notifications/plugin/notificationshelper.cpp
--- a/applets/notifications/plugin/notificationshelper.cpp
+++ b/applets/notifications/plugin/notificationshelper.cpp
@@ -76,23 +76,10 @@
this, SLOT(onPopupClosed()));
connect(popup, &QWindow::heightChanged, this, &NotificationsHelper::repositionPopups, Qt::UniqueConnection);
- connect(popup, &QWindow::visibleChanged, this, &NotificationsHelper::onPopupShown, Qt::UniqueConnection);
- popup->setProperty("initialPositionSet", false);
-}
-
-void NotificationsHelper::onPopupShown()
-{
- QWindow *popup = qobject_cast(sender());
- if (!popup || !popup->isVisible()) {
- return;
- }
-
- // Make sure Dialog lays everything out and gets proper geometry
- QMetaObject::invokeMethod(popup, "updateVisibility", Qt::DirectConnection, Q_ARG(bool, true));
-
- // Now we can position the popups properly as the geometry is now known
- repositionPopups();
+ //We are sure that after visibleChanged the size is final
+ //and the first expose event didn't arrive yet
+ connect(popup, &QQuickWindow::visibleChanged, this, &NotificationsHelper::repositionPopups);
}
void NotificationsHelper::processQueues()
@@ -151,7 +138,8 @@
QMetaObject::invokeMethod(popup, "populatePopup", Qt::DirectConnection, Q_ARG(QVariant, notificationData));
Q_EMIT popupShown(popup);
- QTimer::singleShot(300, popup, &QWindow::show);
+ //use setproperty so the Dialog reimplementation will be used
+ popup->setProperty("visible", true);
if (!m_dispatchTimer->isActive()) {
m_dispatchTimer->start();
@@ -177,10 +165,6 @@
popup->hide();
- // Make sure the popup gets placed correctly
- // next time it's put on screen
- popup->setProperty("initialPositionSet", false);
-
QMetaObject::invokeMethod(popup, "clearPopup", Qt::DirectConnection);
}
@@ -298,30 +282,17 @@
m_mutex->lockForWrite();
+ QPoint pos;
+
for (int i = 0; i < m_popupsOnScreen.size(); ++i) {
if (m_popupLocation == NotificationsHelper::TopLeft
|| m_popupLocation == NotificationsHelper::TopCenter
|| m_popupLocation == NotificationsHelper::TopRight) {
- int posY = m_plasmoidScreen.top() + cumulativeHeight;
+ pos.setY(m_plasmoidScreen.top() + cumulativeHeight);
- if (m_popupsOnScreen[i]->isVisible() && m_popupsOnScreen[i]->property("initialPositionSet").toBool() == true && m_popupsOnScreen[i]->y() != 0) {
- //if it's visible, go through setProperty which animates it
- m_popupsOnScreen[i]->setProperty("y", posY);
- } else {
- // ...otherwise just set it directly
- m_popupsOnScreen[i]->setY(posY);
- m_popupsOnScreen[i]->setProperty("initialPositionSet", true);
- }
} else {
- int posY = m_plasmoidScreen.bottom() - cumulativeHeight - m_popupsOnScreen[i]->contentItem()->height();
-
- if (m_popupsOnScreen[i]->isVisible() && m_popupsOnScreen[i]->property("initialPositionSet").toBool() == true && m_popupsOnScreen[i]->y() != 0) {
- m_popupsOnScreen[i]->setProperty("y", posY);
- } else {
- m_popupsOnScreen[i]->setY(posY);
- m_popupsOnScreen[i]->setProperty("initialPositionSet", true);
- }
+ pos.setY(m_plasmoidScreen.bottom() - cumulativeHeight - m_popupsOnScreen[i]->height());
}
switch (m_popupLocation) {
@@ -332,24 +303,24 @@
//fall through to top right
case TopRight:
case BottomRight:
- m_popupsOnScreen[i]->setX(m_plasmoidScreen.right() - m_popupsOnScreen[i]->contentItem()->width() - m_offset);
+ pos.setX(m_plasmoidScreen.right() - m_popupsOnScreen[i]->width() - m_offset);
break;
case TopCenter:
case BottomCenter:
- m_popupsOnScreen[i]->setX(m_plasmoidScreen.x() + (m_plasmoidScreen.width() / 2) - (m_popupsOnScreen[i]->contentItem()->width() / 2));
+ pos.setX(m_plasmoidScreen.x() + (m_plasmoidScreen.width() / 2) - (m_popupsOnScreen[i]->width() / 2));
break;
case TopLeft:
case BottomLeft:
- m_popupsOnScreen[i]->setX(m_plasmoidScreen.left() + m_offset);
+ pos.setX(m_plasmoidScreen.left() + m_offset);
break;
case Left:
case Center:
case Right:
// Fall-through to make the compiler happy
break;
}
-
- cumulativeHeight += (m_popupsOnScreen[i]->contentItem()->height() + m_offset);
+ m_popupsOnScreen[i]->setPosition(pos);
+ cumulativeHeight += (m_popupsOnScreen[i]->height() + m_offset);
}
m_mutex->unlock();