diff --git a/src/Gui/NotificationArea.cpp b/src/Gui/NotificationArea.cpp
index 53e27c644f..8e81a502cc 100644
--- a/src/Gui/NotificationArea.cpp
+++ b/src/Gui/NotificationArea.cpp
@@ -234,7 +234,7 @@ void NotificationAreaObserver::SendLog(const std::string& notifiername, const st
.trimmed();// remove any leading and trailing whitespace character ('\n')
// avoid processing empty strings
- if(simplifiedstring.isEmpty())
+ if (simplifiedstring.isEmpty())
return;
if (level == Base::LogStyle::TranslatedNotification) {
@@ -827,7 +827,7 @@ void NotificationArea::pushNotification(const QString& notifiername, const QStri
auto timer_thread = pImp->inhibitTimer.thread();
auto current_thread = QThread::currentThread();
- if(timer_thread == current_thread)
+ if (timer_thread == current_thread)
pImp->inhibitTimer.start(pImp->inhibitNotificationTime);
}
@@ -939,7 +939,8 @@ void NotificationArea::showInNotificationArea()
iconstr = QStringLiteral(":/icons/info.svg");
}
- QString tmpmessage = convertFromPlainText(item->msg, Qt::WhiteSpaceMode::WhiteSpaceNormal);
+ QString tmpmessage =
+ convertFromPlainText(item->msg, Qt::WhiteSpaceMode::WhiteSpaceNormal);
msgw +=
QString::fromLatin1(
@@ -990,11 +991,17 @@ void NotificationArea::showInNotificationArea()
msgw += QString::fromLatin1("
");
+ // Calculate the main window QRect in global screen coordinates.
+ auto mainwindow = getMainWindow();
+ auto mainwindowrect = mainwindow->rect();
+ auto globalmainwindowrect =
+ QRect(mainwindow->mapToGlobal(mainwindowrect.topLeft()), mainwindowrect.size());
NotificationBox::showText(this->mapToGlobal(QPoint()),
msgw,
pImp->notificationExpirationTime,
pImp->minimumOnScreenTime,
+ globalmainwindowrect,
pImp->notificationWidth);
}
}
diff --git a/src/Gui/NotificationBox.cpp b/src/Gui/NotificationBox.cpp
index 41bfe05d16..79e528d069 100644
--- a/src/Gui/NotificationBox.cpp
+++ b/src/Gui/NotificationBox.cpp
@@ -73,6 +73,8 @@ public:
bool notificationLabelChanged(const QString& text);
/// Place the notification at the given position
void placeNotificationLabel(const QPoint& pos);
+ /// Set the windowrect defining an area to which the label should be constrained
+ void setTipRect(const QRect &restrictionarea);
/// The instance
static qobject_delete_later_unique_ptr instance;
@@ -91,6 +93,8 @@ private:
int minShowTime;
QTimer hideTimer;
QTimer expireTimer;
+
+ QRect restrictionArea;
};
qobject_delete_later_unique_ptr NotificationLabel::instance = nullptr;
@@ -263,25 +267,36 @@ void NotificationLabel::placeNotificationLabel(const QPoint& pos)
p += offset;
- QRect screenRect = screen->geometry();
+ QRect actinglimit = screen->geometry();
- if (p.x() + this->width() > screenRect.x() + screenRect.width())
- p.rx() -= 4 + this->width();
- if (p.y() + this->height() > screenRect.y() + screenRect.height())
- p.ry() -= 24 + this->height();
- if (p.y() < screenRect.y())
- p.setY(screenRect.y());
- if (p.x() + this->width() > screenRect.x() + screenRect.width())
- p.setX(screenRect.x() + screenRect.width() - this->width());
- if (p.x() < screenRect.x())
- p.setX(screenRect.x());
- if (p.y() + this->height() > screenRect.y() + screenRect.height())
- p.setY(screenRect.y() + screenRect.height() - this->height());
+ if(!restrictionArea.isNull())
+ actinglimit = restrictionArea;
+
+ const int standard_x_padding = 4;
+ const int standard_y_padding = 24;
+
+ if (p.x() + this->width() > actinglimit.x() + actinglimit.width())
+ p.rx() -= standard_x_padding + this->width();
+ if (p.y() + standard_y_padding + this->height() > actinglimit.y() + actinglimit.height())
+ p.ry() -= standard_y_padding + this->height();
+ if (p.y() < actinglimit.y())
+ p.setY(actinglimit.y());
+ if (p.x() + this->width() > actinglimit.x() + actinglimit.width())
+ p.setX(actinglimit.x() + actinglimit.width() - this->width());
+ if (p.x() < actinglimit.x())
+ p.setX(actinglimit.x());
+ if (p.y() + this->height() > actinglimit.y() + actinglimit.height())
+ p.setY(actinglimit.y() + actinglimit.height() - this->height());
}
this->move(p);
}
+void NotificationLabel::setTipRect(const QRect &restrictionarea)
+{
+ restrictionArea = restrictionarea;
+}
+
bool NotificationLabel::notificationLabelChanged(const QString& text)
{
return NotificationLabel::instance->text() != text;
@@ -290,7 +305,7 @@ bool NotificationLabel::notificationLabelChanged(const QString& text)
/***************************** NotificationBox **********************************/
void NotificationBox::showText(const QPoint& pos, const QString& text, int displayTime,
- unsigned int minShowTime, int width)
+ unsigned int minShowTime, const QRect &restrictionarea, int width)
{
// a label does already exist
if (NotificationLabel::instance && NotificationLabel::instance->isVisible()) {
@@ -301,6 +316,7 @@ void NotificationBox::showText(const QPoint& pos, const QString& text, int displ
else {
// If the label has changed, reuse the one that is showing (removes flickering)
if (NotificationLabel::instance->notificationLabelChanged(text)) {
+ NotificationLabel::instance->setTipRect(restrictionarea);
NotificationLabel::instance->reuseNotification(text, displayTime, pos, width);
NotificationLabel::instance->placeNotificationLabel(pos);
}
@@ -310,12 +326,16 @@ void NotificationBox::showText(const QPoint& pos, const QString& text, int displ
// no label can be reused, create new label:
if (!text.isEmpty()) {
+ // Note: The Label takes no parent, as on windows, we can't use the widget as parent
+ // otherwise the window will be raised when the tooltip will be shown. We do not use
+ // it on Linux either for consistency.
new NotificationLabel(text,
pos,
displayTime,
minShowTime,
width);// sets NotificationLabel::instance to itself
+ NotificationLabel::instance->setTipRect(restrictionarea);
NotificationLabel::instance->placeNotificationLabel(pos);
NotificationLabel::instance->setObjectName(QLatin1String("NotificationBox_label"));
diff --git a/src/Gui/NotificationBox.h b/src/Gui/NotificationBox.h
index 0008d5ad7e..4ddcd93083 100644
--- a/src/Gui/NotificationBox.h
+++ b/src/Gui/NotificationBox.h
@@ -54,11 +54,16 @@ public:
* an event, see class documentation above)
* @param minShowTime Time during which the notification can only be made disappear by popping
* it out (clicking inside it).
- * @param width Fixes the width of the notification. Default value makes the width to be system determined (dependent on
- * the text).
+ * @param restrictionarea Try to keep the NotificationBox within this area. If this area is not
+ * provided, the whole screen is used as restriction area. This are must be provided in global
+ * screen coordinates.
+ * @param width Fixes the width of the notification. Default value makes the width to be system
+ * determined (dependent on the text). If a fixed width is provided it is enforced over the
+ * restrictionarea.
*/
static void showText(const QPoint& pos, const QString& text, int displayTime = -1,
- unsigned int minShowTime = 0, int width = 0);
+ unsigned int minShowTime = 0, const QRect& restrictionarea = {},
+ int width = 0);
/// Hides a notification.
static inline void hideText()
{