Changeset View
Changeset View
Standalone View
Standalone View
applets/notifications/plugin/notificationshelper.cpp
Show First 20 Lines • Show All 70 Lines • ▼ Show 20 Line(s) | 68 | { | |||
---|---|---|---|---|---|
71 | 71 | | |||
72 | // Don't let QML ever delete this component | 72 | // Don't let QML ever delete this component | ||
73 | QQmlEngine::setObjectOwnership(win, QQmlEngine::CppOwnership); | 73 | QQmlEngine::setObjectOwnership(win, QQmlEngine::CppOwnership); | ||
74 | 74 | | |||
75 | connect(win, SIGNAL(notificationTimeout()), | 75 | connect(win, SIGNAL(notificationTimeout()), | ||
76 | this, SLOT(onPopupClosed())); | 76 | this, SLOT(onPopupClosed())); | ||
77 | 77 | | |||
78 | connect(popup, &QWindow::heightChanged, this, &NotificationsHelper::repositionPopups, Qt::UniqueConnection); | 78 | connect(popup, &QWindow::heightChanged, this, &NotificationsHelper::repositionPopups, Qt::UniqueConnection); | ||
79 | connect(popup, &QWindow::visibleChanged, this, &NotificationsHelper::onPopupShown, Qt::UniqueConnection); | | |||
80 | 79 | | |||
81 | popup->setProperty("initialPositionSet", false); | 80 | //We are sure that after visibleChanged the size is final | ||
82 | } | 81 | //and the first expose event didn't arrive yet | ||
83 | 82 | connect(popup, &QQuickWindow::visibleChanged, this, &NotificationsHelper::repositionPopups); | |||
84 | void NotificationsHelper::onPopupShown() | | |||
85 | { | | |||
86 | QWindow *popup = qobject_cast<QWindow*>(sender()); | | |||
87 | if (!popup || !popup->isVisible()) { | | |||
88 | return; | | |||
89 | } | | |||
90 | | ||||
91 | // Make sure Dialog lays everything out and gets proper geometry | | |||
92 | QMetaObject::invokeMethod(popup, "updateVisibility", Qt::DirectConnection, Q_ARG(bool, true)); | | |||
93 | | ||||
94 | // Now we can position the popups properly as the geometry is now known | | |||
95 | repositionPopups(); | | |||
96 | } | 83 | } | ||
97 | 84 | | |||
98 | void NotificationsHelper::processQueues() | 85 | void NotificationsHelper::processQueues() | ||
99 | { | 86 | { | ||
100 | if (m_busy) { | 87 | if (m_busy) { | ||
101 | return; | 88 | return; | ||
102 | } | 89 | } | ||
103 | 90 | | |||
▲ Show 20 Lines • Show All 42 Lines • ▼ Show 20 Line(s) | 124 | if (!popup) { | |||
146 | // to avoid looking up the notificationProperties map as above | 133 | // to avoid looking up the notificationProperties map as above | ||
147 | popup->setProperty("sourceName", sourceName); | 134 | popup->setProperty("sourceName", sourceName); | ||
148 | } | 135 | } | ||
149 | 136 | | |||
150 | // Populate the popup with data, this is the component's own QML method | 137 | // Populate the popup with data, this is the component's own QML method | ||
151 | QMetaObject::invokeMethod(popup, "populatePopup", Qt::DirectConnection, Q_ARG(QVariant, notificationData)); | 138 | QMetaObject::invokeMethod(popup, "populatePopup", Qt::DirectConnection, Q_ARG(QVariant, notificationData)); | ||
152 | Q_EMIT popupShown(popup); | 139 | Q_EMIT popupShown(popup); | ||
153 | 140 | | |||
154 | QTimer::singleShot(300, popup, &QWindow::show); | 141 | popup->setVisible(true); | ||
155 | 142 | | |||
156 | if (!m_dispatchTimer->isActive()) { | 143 | if (!m_dispatchTimer->isActive()) { | ||
157 | m_dispatchTimer->start(); | 144 | m_dispatchTimer->start(); | ||
158 | } | 145 | } | ||
159 | } | 146 | } | ||
160 | 147 | | |||
161 | void NotificationsHelper::processHide() | 148 | void NotificationsHelper::processHide() | ||
162 | { | 149 | { | ||
Show All 9 Lines | 154 | if (popup) { | |||
172 | if (!m_availablePopups.contains(popup)) { | 159 | if (!m_availablePopups.contains(popup)) { | ||
173 | // make extra sure that pointers in here aren't doubled | 160 | // make extra sure that pointers in here aren't doubled | ||
174 | m_availablePopups.append(popup); | 161 | m_availablePopups.append(popup); | ||
175 | } | 162 | } | ||
176 | m_mutex->unlock(); | 163 | m_mutex->unlock(); | ||
177 | 164 | | |||
178 | popup->hide(); | 165 | popup->hide(); | ||
179 | 166 | | |||
180 | // Make sure the popup gets placed correctly | | |||
181 | // next time it's put on screen | | |||
182 | popup->setProperty("initialPositionSet", false); | | |||
183 | | ||||
184 | QMetaObject::invokeMethod(popup, "clearPopup", Qt::DirectConnection); | 167 | QMetaObject::invokeMethod(popup, "clearPopup", Qt::DirectConnection); | ||
185 | } | 168 | } | ||
186 | 169 | | |||
187 | m_mutex->lockForRead(); | 170 | m_mutex->lockForRead(); | ||
188 | bool shouldReposition = !m_popupsOnScreen.isEmpty();// && m_showQueue.isEmpty(); | 171 | bool shouldReposition = !m_popupsOnScreen.isEmpty();// && m_showQueue.isEmpty(); | ||
189 | m_mutex->unlock(); | 172 | m_mutex->unlock(); | ||
190 | 173 | | |||
191 | if (shouldReposition) { | 174 | if (shouldReposition) { | ||
▲ Show 20 Lines • Show All 101 Lines • ▼ Show 20 Line(s) | |||||
293 | } | 276 | } | ||
294 | 277 | | |||
295 | void NotificationsHelper::repositionPopups() | 278 | void NotificationsHelper::repositionPopups() | ||
296 | { | 279 | { | ||
297 | int cumulativeHeight = m_offset; | 280 | int cumulativeHeight = m_offset; | ||
298 | 281 | | |||
299 | m_mutex->lockForWrite(); | 282 | m_mutex->lockForWrite(); | ||
300 | 283 | | |||
284 | QPoint pos; | ||||
285 | | ||||
301 | for (int i = 0; i < m_popupsOnScreen.size(); ++i) { | 286 | for (int i = 0; i < m_popupsOnScreen.size(); ++i) { | ||
302 | if (m_popupLocation == NotificationsHelper::TopLeft | 287 | if (m_popupLocation == NotificationsHelper::TopLeft | ||
303 | || m_popupLocation == NotificationsHelper::TopCenter | 288 | || m_popupLocation == NotificationsHelper::TopCenter | ||
304 | || m_popupLocation == NotificationsHelper::TopRight) { | 289 | || m_popupLocation == NotificationsHelper::TopRight) { | ||
305 | 290 | | |||
306 | int posY = m_plasmoidScreen.top() + cumulativeHeight; | 291 | pos.setY(m_plasmoidScreen.top() + cumulativeHeight); | ||
307 | | ||||
308 | if (m_popupsOnScreen[i]->isVisible() && m_popupsOnScreen[i]->property("initialPositionSet").toBool() == true && m_popupsOnScreen[i]->y() != 0) { | | |||
309 | //if it's visible, go through setProperty which animates it | | |||
310 | m_popupsOnScreen[i]->setProperty("y", posY); | | |||
311 | } else { | | |||
312 | // ...otherwise just set it directly | | |||
313 | m_popupsOnScreen[i]->setY(posY); | | |||
314 | m_popupsOnScreen[i]->setProperty("initialPositionSet", true); | | |||
315 | } | | |||
316 | } else { | | |||
317 | int posY = m_plasmoidScreen.bottom() - cumulativeHeight - m_popupsOnScreen[i]->contentItem()->height(); | | |||
318 | 292 | | |||
319 | if (m_popupsOnScreen[i]->isVisible() && m_popupsOnScreen[i]->property("initialPositionSet").toBool() == true && m_popupsOnScreen[i]->y() != 0) { | | |||
320 | m_popupsOnScreen[i]->setProperty("y", posY); | | |||
321 | } else { | 293 | } else { | ||
322 | m_popupsOnScreen[i]->setY(posY); | 294 | pos.setY(m_plasmoidScreen.bottom() - cumulativeHeight - m_popupsOnScreen[i]->height()); | ||
davidedmundson: I find it odd that we use the contentItem height not the window height which includes the frame… | |||||
mart: didn't change that, giving a try to it, may simplify things further | |||||
323 | m_popupsOnScreen[i]->setProperty("initialPositionSet", true); | | |||
324 | } | | |||
325 | } | 295 | } | ||
326 | 296 | | |||
327 | switch (m_popupLocation) { | 297 | switch (m_popupLocation) { | ||
328 | case Default: | 298 | case Default: | ||
329 | //This should not happen as the defualt handling is in NotificationApplet::onScreenPositionChanged | 299 | //This should not happen as the defualt handling is in NotificationApplet::onScreenPositionChanged | ||
330 | Q_ASSERT(false); | 300 | Q_ASSERT(false); | ||
331 | qWarning("Notication popupLocation is still \"default\". This should not happen"); | 301 | qWarning("Notication popupLocation is still \"default\". This should not happen"); | ||
332 | //fall through to top right | 302 | //fall through to top right | ||
333 | case TopRight: | 303 | case TopRight: | ||
334 | case BottomRight: | 304 | case BottomRight: | ||
335 | m_popupsOnScreen[i]->setX(m_plasmoidScreen.right() - m_popupsOnScreen[i]->contentItem()->width() - m_offset); | 305 | pos.setX(m_plasmoidScreen.right() - m_popupsOnScreen[i]->width() - m_offset); | ||
336 | break; | 306 | break; | ||
337 | case TopCenter: | 307 | case TopCenter: | ||
338 | case BottomCenter: | 308 | case BottomCenter: | ||
339 | m_popupsOnScreen[i]->setX(m_plasmoidScreen.x() + (m_plasmoidScreen.width() / 2) - (m_popupsOnScreen[i]->contentItem()->width() / 2)); | 309 | pos.setX(m_plasmoidScreen.x() + (m_plasmoidScreen.width() / 2) - (m_popupsOnScreen[i]->width() / 2)); | ||
340 | break; | 310 | break; | ||
341 | case TopLeft: | 311 | case TopLeft: | ||
342 | case BottomLeft: | 312 | case BottomLeft: | ||
343 | m_popupsOnScreen[i]->setX(m_plasmoidScreen.left() + m_offset); | 313 | pos.setX(m_plasmoidScreen.left() + m_offset); | ||
344 | break; | 314 | break; | ||
345 | case Left: | 315 | case Left: | ||
346 | case Center: | 316 | case Center: | ||
347 | case Right: | 317 | case Right: | ||
348 | // Fall-through to make the compiler happy | 318 | // Fall-through to make the compiler happy | ||
349 | break; | 319 | break; | ||
350 | } | 320 | } | ||
351 | 321 | m_popupsOnScreen[i]->setPosition(pos); | |||
352 | cumulativeHeight += (m_popupsOnScreen[i]->contentItem()->height() + m_offset); | 322 | cumulativeHeight += (m_popupsOnScreen[i]->height() + m_offset); | ||
353 | } | 323 | } | ||
354 | 324 | | |||
355 | m_mutex->unlock(); | 325 | m_mutex->unlock(); | ||
356 | } | 326 | } | ||
357 | 327 | | |||
358 | 328 | |
I find it odd that we use the contentItem height not the window height which includes the frame margins.
Especially given that whole other patch is about making sure the window is resized to the contentItem.