177 lines
7.4 KiB
Diff
177 lines
7.4 KiB
Diff
From aa1e466e5f7684a8b624c34d466dda9d10a331d2 Mon Sep 17 00:00:00 2001
|
|
From: Nate Graham <nate@kde.org>
|
|
Date: Sun, 6 Jul 2025 23:20:47 -0400
|
|
Subject: [PATCH 1/2] Improve UX of USB plug/unplug notifications when popup is
|
|
shown
|
|
|
|
1. When plugged or unplugged, revoke the opposite notification if it's
|
|
visible.
|
|
2. Set the urgency to low so it won't clutter up the notification
|
|
history.
|
|
---
|
|
devicenotifications/devicenotifications.cpp | 55 ++++++++++++++++-----
|
|
devicenotifications/devicenotifications.h | 5 ++
|
|
2 files changed, 48 insertions(+), 12 deletions(-)
|
|
|
|
diff --git a/devicenotifications/devicenotifications.cpp b/devicenotifications/devicenotifications.cpp
|
|
index cc462f58f5..f326691c11 100644
|
|
--- a/devicenotifications/devicenotifications.cpp
|
|
+++ b/devicenotifications/devicenotifications.cpp
|
|
@@ -15,6 +15,7 @@
|
|
|
|
#include <chrono>
|
|
|
|
+#include <knotification.h>
|
|
#include <wayland-client.h>
|
|
|
|
K_PLUGIN_CLASS_WITH_JSON(KdedDeviceNotifications, "devicenotifications.json")
|
|
@@ -375,13 +376,28 @@ void KdedDeviceNotifications::onDeviceAdded(const UdevDevice &device)
|
|
return;
|
|
}
|
|
|
|
- const QString text = !displayName.isEmpty() ? i18n("%1 has been plugged in.", displayName.toHtmlEscaped()) : i18n("A USB device has been plugged in.");
|
|
+ // If the user unplugged something and then immediately plugged it in again,
|
|
+ // there's no need to keep the unplug notification around.
|
|
+ if (m_usbDeviceRemovedNotification) {
|
|
+ m_usbDeviceRemovedNotification->close();
|
|
+ }
|
|
+
|
|
+ // Only show one of these at a time. We already suppressed creating a bunch
|
|
+ // in quick succession for the dock/hub use case, so any that are created
|
|
+ // over that time limit anyway are not necessary to stack up.
|
|
+ if (m_usbDeviceAddedNotification) {
|
|
+ m_usbDeviceAddedNotification->close();
|
|
+ }
|
|
+
|
|
+ const QString text = !displayName.isEmpty() ? i18n("%1 has been connected.", displayName.toHtmlEscaped()) : i18n("A USB device has been connected.");
|
|
+
|
|
+ m_usbDeviceAddedNotification = new KNotification(QStringLiteral("deviceAdded"));
|
|
+ m_usbDeviceAddedNotification->setFlags(KNotification::DefaultEvent);
|
|
+ m_usbDeviceAddedNotification->setIconName(QStringLiteral("drive-removable-media-usb"));
|
|
+ m_usbDeviceAddedNotification->setTitle(i18nc("@title:notifications", "USB Device Detected"));
|
|
+ m_usbDeviceAddedNotification->setText(text);
|
|
+ m_usbDeviceAddedNotification->sendEvent();
|
|
|
|
- KNotification::event(QStringLiteral("deviceAdded"),
|
|
- i18nc("@title:notifications", "USB Device Detected"),
|
|
- text,
|
|
- QStringLiteral("drive-removable-media-usb"),
|
|
- KNotification::DefaultEvent);
|
|
m_deviceAddedTimer.start();
|
|
}
|
|
|
|
@@ -401,13 +417,28 @@ void KdedDeviceNotifications::onDeviceRemoved(const UdevDevice &device)
|
|
return;
|
|
}
|
|
|
|
- const QString text = !displayName.isEmpty() ? i18n("%1 has been unplugged.", displayName.toHtmlEscaped()) : i18n("A USB device has been unplugged.");
|
|
+ // If the user plugged something in and then immediately unplugged it again,
|
|
+ // there's no need to keep the plug notification around.
|
|
+ if (m_usbDeviceAddedNotification) {
|
|
+ m_usbDeviceAddedNotification->close();
|
|
+ }
|
|
+
|
|
+ // Only show one of these at a time. We already suppressed removing a bunch
|
|
+ // in quick succession for the dock/hub use case, so any that are removed
|
|
+ // over that time limit anyway are not necessary to stack up.
|
|
+ if (m_usbDeviceRemovedNotification) {
|
|
+ m_usbDeviceRemovedNotification->close();
|
|
+ }
|
|
+
|
|
+ const QString text = !displayName.isEmpty() ? i18n("%1 has been disconnected.", displayName.toHtmlEscaped()) : i18n("A USB device has been disconnected.");
|
|
+
|
|
+ m_usbDeviceRemovedNotification = new KNotification(QStringLiteral("deviceRemoved"));
|
|
+ m_usbDeviceRemovedNotification->setFlags(KNotification::DefaultEvent);
|
|
+ m_usbDeviceRemovedNotification->setIconName(QStringLiteral("drive-removable-media-usb"));
|
|
+ m_usbDeviceRemovedNotification->setTitle(i18nc("@title:notifications", "USB Device Went Away"));
|
|
+ m_usbDeviceRemovedNotification->setText(text);
|
|
+ m_usbDeviceRemovedNotification->sendEvent();
|
|
|
|
- KNotification::event(QStringLiteral("deviceRemoved"),
|
|
- i18nc("@title:notifications", "USB Device Removed"),
|
|
- text,
|
|
- QStringLiteral("drive-removable-media-usb"),
|
|
- KNotification::DefaultEvent);
|
|
m_deviceRemovedTimer.start();
|
|
}
|
|
|
|
diff --git a/devicenotifications/devicenotifications.h b/devicenotifications/devicenotifications.h
|
|
index 11334008b0..ab7e6b3ff9 100644
|
|
--- a/devicenotifications/devicenotifications.h
|
|
+++ b/devicenotifications/devicenotifications.h
|
|
@@ -8,11 +8,13 @@
|
|
|
|
#include <QHash>
|
|
#include <QList>
|
|
+#include <QPointer>
|
|
#include <QSocketNotifier>
|
|
#include <QString>
|
|
#include <QTimer>
|
|
|
|
#include <KDEDModule>
|
|
+#include <KNotification>
|
|
|
|
#include <libudev.h>
|
|
|
|
@@ -98,4 +100,7 @@ private:
|
|
|
|
QTimer m_deviceAddedTimer;
|
|
QTimer m_deviceRemovedTimer;
|
|
+
|
|
+ QPointer<KNotification> m_usbDeviceAddedNotification;
|
|
+ QPointer<KNotification> m_usbDeviceRemovedNotification;
|
|
};
|
|
--
|
|
2.51.0
|
|
|
|
|
|
From 05f72383fd0b29105f3b5494759500d26b38ffc2 Mon Sep 17 00:00:00 2001
|
|
From: Nate Graham <nate@kde.org>
|
|
Date: Fri, 11 Jul 2025 11:25:23 -0600
|
|
Subject: [PATCH 2/2] Delete closed notifications too
|
|
|
|
Closing is async; make sure we actually delete them when we want them
|
|
gone.
|
|
---
|
|
devicenotifications/devicenotifications.cpp | 4 ++++
|
|
1 file changed, 4 insertions(+)
|
|
|
|
diff --git a/devicenotifications/devicenotifications.cpp b/devicenotifications/devicenotifications.cpp
|
|
index f326691c11..987d65d805 100644
|
|
--- a/devicenotifications/devicenotifications.cpp
|
|
+++ b/devicenotifications/devicenotifications.cpp
|
|
@@ -380,6 +380,7 @@ void KdedDeviceNotifications::onDeviceAdded(const UdevDevice &device)
|
|
// there's no need to keep the unplug notification around.
|
|
if (m_usbDeviceRemovedNotification) {
|
|
m_usbDeviceRemovedNotification->close();
|
|
+ m_usbDeviceRemovedNotification = nullptr;
|
|
}
|
|
|
|
// Only show one of these at a time. We already suppressed creating a bunch
|
|
@@ -387,6 +388,7 @@ void KdedDeviceNotifications::onDeviceAdded(const UdevDevice &device)
|
|
// over that time limit anyway are not necessary to stack up.
|
|
if (m_usbDeviceAddedNotification) {
|
|
m_usbDeviceAddedNotification->close();
|
|
+ m_usbDeviceAddedNotification = nullptr;
|
|
}
|
|
|
|
const QString text = !displayName.isEmpty() ? i18n("%1 has been connected.", displayName.toHtmlEscaped()) : i18n("A USB device has been connected.");
|
|
@@ -421,6 +423,7 @@ void KdedDeviceNotifications::onDeviceRemoved(const UdevDevice &device)
|
|
// there's no need to keep the plug notification around.
|
|
if (m_usbDeviceAddedNotification) {
|
|
m_usbDeviceAddedNotification->close();
|
|
+ m_usbDeviceAddedNotification = nullptr;
|
|
}
|
|
|
|
// Only show one of these at a time. We already suppressed removing a bunch
|
|
@@ -428,6 +431,7 @@ void KdedDeviceNotifications::onDeviceRemoved(const UdevDevice &device)
|
|
// over that time limit anyway are not necessary to stack up.
|
|
if (m_usbDeviceRemovedNotification) {
|
|
m_usbDeviceRemovedNotification->close();
|
|
+ m_usbDeviceRemovedNotification = nullptr;
|
|
}
|
|
|
|
const QString text = !displayName.isEmpty() ? i18n("%1 has been disconnected.", displayName.toHtmlEscaped()) : i18n("A USB device has been disconnected.");
|
|
--
|
|
2.51.0
|
|
|