Keep notification independent of main window minimization
This commit is contained in:
1 parent
2caa653f02
commit
bc42df12f5
3 files changed
+26
-10
No files matched your search
@@ -13,8 +13,8 @@
|
||||
#include <QHideEvent>
|
||||
#include <QCloseEvent>
|
||||
|
||||
MessageNotification::MessageNotification(QWidget* parent)
|
||||
: QWidget(parent, Qt::Tool | Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint | Qt::WindowDoesNotAcceptFocus)
|
||||
MessageNotification::MessageNotification()
|
||||
: QWidget(nullptr, Qt::Tool | Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint | Qt::WindowDoesNotAcceptFocus)
|
||||
, m_activity(new UserActivityMonitor(this))
|
||||
{
|
||||
setObjectName("messageNotification");
|
||||
@@ -67,9 +67,10 @@ MessageNotification::~MessageNotification() {
|
||||
qPrintable(m_target), int(isVisible()), int(m_hideTimer.isActive()));
|
||||
}
|
||||
|
||||
void MessageNotification::showMessage(const QString& target, const QString& sender, const QString& channel, const QRect& trayGeometry) {
|
||||
void MessageNotification::showMessage(const QString& target, const QString& sender, const QString& channel,
|
||||
const QRect& trayGeometry, QScreen* preferredScreen) {
|
||||
QScreen* screen = trayGeometry.isEmpty() ? nullptr : QGuiApplication::screenAt(trayGeometry.center());
|
||||
if (!screen && parentWidget()) screen = parentWidget()->screen();
|
||||
if (!screen) screen = preferredScreen;
|
||||
if (!screen) screen = QGuiApplication::primaryScreen();
|
||||
if (!screen || screen->availableGeometry().isEmpty()) {
|
||||
GUI_ERROR("notification: no available screen target=%s", qPrintable(target));
|
||||
|
||||
@@ -6,14 +6,16 @@
|
||||
#include <QTimer>
|
||||
|
||||
class QLabel;
|
||||
class QScreen;
|
||||
class UserActivityMonitor;
|
||||
|
||||
class MessageNotification : public QWidget {
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit MessageNotification(QWidget* parent = nullptr);
|
||||
MessageNotification();
|
||||
~MessageNotification() override;
|
||||
void showMessage(const QString& target, const QString& sender, const QString& channel, const QRect& trayGeometry);
|
||||
void showMessage(const QString& target, const QString& sender, const QString& channel,
|
||||
const QRect& trayGeometry, QScreen* preferredScreen = nullptr);
|
||||
void dismiss(const char* reason);
|
||||
|
||||
signals:
|
||||
|
||||
@@ -43,8 +43,9 @@ public slots:
|
||||
requests, (unsigned long long)idle, delayMs, int(calledFromDBus()));
|
||||
if (delayMs) {
|
||||
const QDBusMessage reply = message().createReply(QVariant::fromValue(idle));
|
||||
const QDBusConnection bus = connection();
|
||||
setDelayedReply(true);
|
||||
QTimer::singleShot(delayMs, this, [reply] { QDBusConnection::sessionBus().send(reply); });
|
||||
QTimer::singleShot(delayMs, this, [reply, bus] { bus.send(reply); });
|
||||
}
|
||||
return idle;
|
||||
}
|
||||
@@ -60,6 +61,13 @@ private slots:
|
||||
qunsetenv("XDG_SESSION_TYPE");
|
||||
}
|
||||
|
||||
void cleanup() {
|
||||
qunsetenv("XDG_SESSION_TYPE");
|
||||
#ifdef UTUN_TEST_ACTIVITY_DBUS
|
||||
QDBusConnection::disconnectFromBus("notification-test-service");
|
||||
#endif
|
||||
}
|
||||
|
||||
void firstSystemActivityAndCancellation() {
|
||||
FakeSystemActivity activity;
|
||||
QSignalSpy spy(&activity, &UserActivityMonitor::activity);
|
||||
@@ -98,11 +106,15 @@ private slots:
|
||||
QWidget hiddenParent;
|
||||
QLineEdit otherWindow;
|
||||
otherWindow.show();
|
||||
QApplication::setActiveWindow(&otherWindow);
|
||||
MessageNotification notification(&hiddenParent);
|
||||
otherWindow.activateWindow();
|
||||
QTRY_COMPARE(QApplication::activeWindow(), &otherWindow);
|
||||
MessageNotification notification;
|
||||
notification.showMessage("42", "Alice", "Test channel", {});
|
||||
QVERIFY(notification.isVisible());
|
||||
QVERIFY(!notification.parentWidget()); // ОС не должна скрывать уведомление вместе с главным окном.
|
||||
QCOMPARE(QApplication::activeWindow(), &otherWindow);
|
||||
hiddenParent.showMinimized();
|
||||
QVERIFY(notification.isVisible());
|
||||
QTest::qWait(10200);
|
||||
QVERIFY(notification.isVisible()); // Без активности автоматического таймера нет.
|
||||
QElapsedTimer elapsed;
|
||||
@@ -144,7 +156,8 @@ private slots:
|
||||
|
||||
#ifdef UTUN_TEST_ACTIVITY_DBUS
|
||||
void gnomeIdleAndStaleReplies() {
|
||||
auto bus = QDBusConnection::sessionBus();
|
||||
// Разные соединения исключают прямой вызов внутри Qt, чтобы задержка действительно прошла через D-Bus.
|
||||
auto bus = QDBusConnection::connectToBus(QDBusConnection::SessionBus, "notification-test-service");
|
||||
QVERIFY(bus.registerService("org.gnome.Mutter.IdleMonitor"));
|
||||
FakeGnomeIdle idle;
|
||||
QVERIFY(bus.registerObject("/org/gnome/Mutter/IdleMonitor/Core", &idle, QDBusConnection::ExportAllSlots));
|
||||
|
||||
Reference in new issue
Block a user