diff --git a/contrib/src/qt/0001-QWindowsSystemTrayIcon-fix-notification-icon-dpi-han.patch b/contrib/src/qt/0001-QWindowsSystemTrayIcon-fix-notification-icon-dpi-han.patch
new file mode 100644
index 0000000000000000000000000000000000000000..853f503de8e7748afdd1383e4ed75878a3e26231
--- /dev/null
+++ b/contrib/src/qt/0001-QWindowsSystemTrayIcon-fix-notification-icon-dpi-han.patch
@@ -0,0 +1,61 @@
+From 241f6e9dcf1bba7c384f7f9752b9281122540589 Mon Sep 17 00:00:00 2001
+From: Fatih Uzunoglu <fuzun54@outlook.com>
+Date: Sat, 22 Feb 2025 20:37:29 +0200
+Subject: [PATCH] QWindowsSystemTrayIcon: fix notification icon dpi handling
+
+Using fixed 256x256 does not make any sense. It is not recommended,
+and Windows downscales the bitmap without linear transformation
+leading to pixelated results.
+
+We should use the recommended `SM_CXICON`x`SM_CYICON`, which is
+expected to be scaled as per the screen DPI since the application
+is made DPI aware.
+---
+ .../windows/qwindowssystemtrayicon.cpp        | 31 +++++++++++++++++--
+ 1 file changed, 29 insertions(+), 2 deletions(-)
+
+diff --git a/src/plugins/platforms/windows/qwindowssystemtrayicon.cpp b/src/plugins/platforms/windows/qwindowssystemtrayicon.cpp
+index 11eb3507f9f..df3e35f21b0 100644
+--- a/src/plugins/platforms/windows/qwindowssystemtrayicon.cpp
++++ b/src/plugins/platforms/windows/qwindowssystemtrayicon.cpp
+@@ -226,8 +226,35 @@ void QWindowsSystemTrayIcon::showMessage(const QString &title, const QString &me
+ 
+     tnd.uID = q_uNOTIFYICONID;
+ 
+-    const auto size = icon.actualSize(QSize(256, 256));
+-    QPixmap pm = icon.pixmap(size);
++    // Qt makes the application DPI aware, `GetSystemMetrics()` is expected to take the screen
++    // dpi into account:
++    QSize size(GetSystemMetrics(SM_CXICON), GetSystemMetrics(SM_CYICON));
++
++    // This is not official, but Windows 11 seems to display the icon at 50x50 with standard DPI,
++    // which is contrary to the recommended `SM_CXICON`/`SM_CYICON` that is 32x32 with standard
++    // DPI. We can pick the higher of 50x50 and `SM_CXICON`/`SMCYICON` to prevent upscaling.
++    const int min = std::ceil(50 * std::max((size.width() / 32.0), (size.height() / 32.0)));
++    if (size.width() < min || size.height() < min) {
++        const auto ratio = static_cast<qreal>(size.width()) / size.height();
++        // Do not spoil the aspect ratio:
++        if (ratio > 1.0) {
++            size.setWidth(std::ceil(min * ratio));
++            size.setHeight(min);
++        } else if (ratio < 1.0) {
++            size.setHeight(std::ceil(min / ratio));
++            size.setWidth(min);
++        } else {
++            size.setHeight(min);
++            size.setWidth(min);
++        }
++    }
++
++    // Use 1.0 as the DPR, because `QIcon` uses the screen (application) DPR (if not supplied),
++    // and we don't want the size to be manipulated based on that because the fed size already
++    // considers the screen DPR (as explained in the note above): `QIcon::pixmap()`: "The pixmap
++    // might be smaller than requested, but never larger, unless the device-pixel ratio of the
++    // returned pixmap is larger than 1."
++    QPixmap pm = icon.pixmap(size, 1.0);
+     if (m_hMessageIcon) {
+         DestroyIcon(m_hMessageIcon);
+         m_hMessageIcon = nullptr;
+-- 
+2.48.1
+
diff --git a/contrib/src/qt/rules.mak b/contrib/src/qt/rules.mak
index 3c44998e035f8b42331c3cce729ca6f0383c543f..f435d704ae9d24bcc50949681394b9602fbe887b 100644
--- a/contrib/src/qt/rules.mak
+++ b/contrib/src/qt/rules.mak
@@ -54,6 +54,7 @@ qt: qtbase-everywhere-src-$(QTBASE_VERSION_FULL).tar.xz .sum-qt
 	$(APPLY) $(SRC)/qt/0001-disable-precompiled-headers-when-forcing-WINVER-inte.patch
 	$(APPLY) $(SRC)/qt/0001-Use-DirectWrite-font-database-only-with-Windows-10-a.patch
 	$(APPLY) $(SRC)/qt/0003-Do-not-link-D3D9.patch
+	$(APPLY) $(SRC)/qt/0001-QWindowsSystemTrayIcon-fix-notification-icon-dpi-han.patch
 	$(MOVE)
 
 ifdef HAVE_WIN32