diff --git a/Telegram/CMakeLists.txt b/Telegram/CMakeLists.txt
index 9d8dcff78..f5f02c7b9 100644
--- a/Telegram/CMakeLists.txt
+++ b/Telegram/CMakeLists.txt
@@ -823,6 +823,8 @@ PRIVATE
     platform/linux/linux_gsd_media_keys.h
     platform/linux/linux_libs.cpp
     platform/linux/linux_libs.h
+    platform/linux/linux_notification_service_watcher.cpp
+    platform/linux/linux_notification_service_watcher.h
     platform/linux/linux_wayland_integration.cpp
     platform/linux/linux_wayland_integration.h
     platform/linux/linux_xlib_helper.cpp
@@ -1116,6 +1118,8 @@ if (LINUX AND DESKTOP_APP_DISABLE_DBUS_INTEGRATION)
     remove_target_sources(Telegram ${src_loc}
         platform/linux/linux_gsd_media_keys.cpp
         platform/linux/linux_gsd_media_keys.h
+        platform/linux/linux_notification_service_watcher.cpp
+        platform/linux/linux_notification_service_watcher.h
         platform/linux/notifications_manager_linux.cpp
     )
 
diff --git a/Telegram/SourceFiles/platform/linux/linux_notification_service_watcher.cpp b/Telegram/SourceFiles/platform/linux/linux_notification_service_watcher.cpp
new file mode 100644
index 000000000..1aa0fb969
--- /dev/null
+++ b/Telegram/SourceFiles/platform/linux/linux_notification_service_watcher.cpp
@@ -0,0 +1,37 @@
+/*
+This file is part of Telegram Desktop,
+the official desktop application for the Telegram messaging service.
+
+For license and copyright information please follow this link:
+https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
+*/
+#include "platform/linux/linux_notification_service_watcher.h"
+
+#include "core/application.h"
+#include "main/main_domain.h"
+#include "window/notifications_manager.h"
+
+#include <QtDBus/QDBusConnection>
+
+namespace Platform {
+namespace internal {
+
+NotificationServiceWatcher::NotificationServiceWatcher()
+: _dbusWatcher(
+		qsl("org.freedesktop.Notifications"),
+		QDBusConnection::sessionBus(),
+		QDBusServiceWatcher::WatchForOwnerChange) {
+	const auto signal = &QDBusServiceWatcher::serviceOwnerChanged;
+	QObject::connect(&_dbusWatcher, signal, [=] {
+		crl::on_main([=] {
+			if (!Core::App().domain().started()) {
+				return;
+			}
+
+			Core::App().notifications().createManager();
+		});
+	});
+}
+
+} // namespace internal
+} // namespace Platform
diff --git a/Telegram/SourceFiles/platform/linux/linux_notification_service_watcher.h b/Telegram/SourceFiles/platform/linux/linux_notification_service_watcher.h
new file mode 100644
index 000000000..50295d089
--- /dev/null
+++ b/Telegram/SourceFiles/platform/linux/linux_notification_service_watcher.h
@@ -0,0 +1,24 @@
+/*
+This file is part of Telegram Desktop,
+the official desktop application for the Telegram messaging service.
+
+For license and copyright information please follow this link:
+https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
+*/
+#pragma once
+
+#include <QtDBus/QDBusServiceWatcher>
+
+namespace Platform {
+namespace internal {
+
+class NotificationServiceWatcher {
+public:
+	NotificationServiceWatcher();
+
+private:
+	QDBusServiceWatcher _dbusWatcher;
+};
+
+} // namespace internal
+} // namespace Platform
diff --git a/Telegram/SourceFiles/platform/linux/notifications_manager_linux.cpp b/Telegram/SourceFiles/platform/linux/notifications_manager_linux.cpp
index 771db12f6..931cdafd8 100644
--- a/Telegram/SourceFiles/platform/linux/notifications_manager_linux.cpp
+++ b/Telegram/SourceFiles/platform/linux/notifications_manager_linux.cpp
@@ -19,6 +19,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
 
 #include <QtCore/QVersionNumber>
 #include <QtDBus/QDBusConnection>
+#include <QtDBus/QDBusConnectionInterface>
 #include <QtDBus/QDBusMessage>
 #include <QtDBus/QDBusReply>
 #include <QtDBus/QDBusError>
@@ -41,112 +42,89 @@ constexpr auto kPropertiesInterface = "org.freedesktop.DBus.Properties"_cs;
 constexpr auto kImageDataType = "(iiibii@ay)"_cs;
 constexpr auto kNotifyArgsType = "(susssasa{sv}i)"_cs;
 
-bool NotificationsSupported = false;
+bool ServiceRegistered = false;
 bool InhibitedNotSupported = false;
+std::vector<QString> CurrentServerInformation;
+QStringList CurrentCapabilities;
 
-void ComputeSupported(bool wait = false) {
-	const auto message = QDBusMessage::createMethodCall(
-		kService.utf16(),
-		kObjectPath.utf16(),
-		kInterface.utf16(),
-		qsl("GetServerInformation"));
+bool GetServiceRegistered() {
+	const auto interface = QDBusConnection::sessionBus().interface();
+	const auto activatable = IsNotificationServiceActivatable();
 
-	auto async = QDBusConnection::sessionBus().asyncCall(message);
-	auto watcher = new QDBusPendingCallWatcher(async);
-
-	QObject::connect(
-		watcher,
-		&QDBusPendingCallWatcher::finished,
-		[=](QDBusPendingCallWatcher *call) {
-			QDBusPendingReply<
-				QString,
-				QString,
-				QString,
-				QString> reply = *call;
-
-			if (reply.isValid()) {
-				NotificationsSupported = true;
-			}
-
-			call->deleteLater();
-		});
-
-	if (wait) {
-		watcher->waitForFinished();
-	}
-}
-
-void GetSupported() {
-	static auto Checked = false;
-	if (Checked) {
-		return;
-	}
-	Checked = true;
-
-	if (Core::App().settings().nativeNotifications() && !IsWayland()) {
-		ComputeSupported(true);
-	} else {
-		ComputeSupported();
-	}
-}
-
-std::vector<QString> ComputeServerInformation() {
-	std::vector<QString> serverInformation;
-
-	const auto message = QDBusMessage::createMethodCall(
-		kService.utf16(),
-		kObjectPath.utf16(),
-		kInterface.utf16(),
-		qsl("GetServerInformation"));
-
-	const auto reply = QDBusConnection::sessionBus().call(message);
-
-	if (reply.type() == QDBusMessage::ReplyMessage) {
-		ranges::transform(
-			reply.arguments(),
-			ranges::back_inserter(serverInformation),
-			&QVariant::toString
-		);
-	} else if (reply.type() == QDBusMessage::ErrorMessage) {
-		LOG(("Native notification error: %1").arg(reply.errorMessage()));
-	} else {
-		LOG(("Native notification error: "
-			"invalid reply from GetServerInformation"));
-	}
-
-	return serverInformation;
+	return interface
+		? interface->isServiceRegistered(kService.utf16()) || activatable
+		: activatable;
 }
 
 std::vector<QString> GetServerInformation() {
-	static const auto Result = ComputeServerInformation();
-	return Result;
+	std::vector<QString> result;
+
+	const auto message = QDBusMessage::createMethodCall(
+		kService.utf16(),
+		kObjectPath.utf16(),
+		kInterface.utf16(),
+		qsl("GetServerInformation"));
+
+	// We may be launched earlier than notification daemon
+	while (true) {
+		const auto reply = QDBusConnection::sessionBus().call(message);
+
+		if (reply.type() == QDBusMessage::ReplyMessage) {
+			ranges::transform(
+				reply.arguments(),
+				ranges::back_inserter(result),
+				&QVariant::toString);
+		} else if (reply.type() == QDBusMessage::ErrorMessage) {
+			LOG(("Native notification error: %1").arg(reply.errorMessage()));
+
+			if (reply.errorName()
+				== qsl("org.freedesktop.DBus.Error.NoReply")) {
+				continue;
+			}
+		} else {
+			LOG(("Native notification error: "
+				"invalid reply from GetServerInformation"));
+		}
+
+		break;
+	}
+
+	return result;
 }
 
-QStringList ComputeCapabilities() {
+QStringList GetCapabilities() {
 	const auto message = QDBusMessage::createMethodCall(
 		kService.utf16(),
 		kObjectPath.utf16(),
 		kInterface.utf16(),
 		qsl("GetCapabilities"));
 
-	const QDBusReply<QStringList> reply = QDBusConnection::sessionBus().call(
-		message);
+	// We may be launched earlier than notification daemon
+	while (true) {
+		const QDBusReply<QStringList> reply = QDBusConnection::sessionBus()
+			.call(message);
+
+		if (reply.isValid()) {
+			return reply.value();
+		}
 
-	if (reply.isValid()) {
-		return reply.value();
-	} else {
 		LOG(("Native notification error: %1").arg(reply.error().message()));
+
+		if (reply.error().type() != QDBusError::NoReply) {
+			break;
+		}
 	}
 
 	return {};
 }
 
-QStringList GetCapabilities() {
-	static const auto Result = ComputeCapabilities();
-	return Result;
-}
-
 bool Inhibited() {
+	if (!Supported()
+		|| !CurrentCapabilities.contains(qsl("inhibitions"))
+		|| InhibitedNotSupported) {
+		return false;
+	}
+
 	auto message = QDBusMessage::createMethodCall(
 		kService.utf16(),
 		kObjectPath.utf16(),
@@ -277,8 +255,7 @@ NotificationData::NotificationData(
 	bool hideReplyButton)
 : _manager(manager)
 , _title(title)
-, _imageKey(GetImageKey(ParseSpecificationVersion(
-	GetServerInformation())))
+, _imageKey(GetImageKey(ParseSpecificationVersion(CurrentServerInformation)))
 , _id(id) {
 	GError *error = nullptr;
 
@@ -293,7 +270,7 @@ NotificationData::NotificationData(
 		return;
 	}
 
-	const auto capabilities = GetCapabilities();
+	const auto capabilities = CurrentCapabilities;
 
 	if (capabilities.contains(qsl("body-markup"))) {
 		_body = subtitle.isEmpty()
@@ -613,30 +590,33 @@ void NotificationData::notificationReplied(uint id, const QString &text) {
 } // namespace
 
 bool SkipAudio() {
-	if (Supported()
-		&& GetCapabilities().contains(qsl("inhibitions"))
-		&& !InhibitedNotSupported) {
-		return Inhibited();
-	}
-
-	return false;
+	return Inhibited();
 }
 
 bool SkipToast() {
-	return SkipAudio();
+	return Inhibited();
 }
 
 bool SkipFlashBounce() {
-	return SkipAudio();
+	return Inhibited();
 }
 
 bool Supported() {
-	return NotificationsSupported;
+	return ServiceRegistered;
 }
 
 std::unique_ptr<Window::Notifications::Manager> Create(
 		Window::Notifications::System *system) {
-	GetSupported();
+	ServiceRegistered = GetServiceRegistered();
+	InhibitedNotSupported = false;
+
+	if (Supported()) {
+		CurrentServerInformation = GetServerInformation();
+		CurrentCapabilities = GetCapabilities();
+	} else {
+		CurrentServerInformation = {};
+		CurrentCapabilities = QStringList{};
+	}
 
 	if ((Core::App().settings().nativeNotifications() && Supported())
 		|| IsWayland()) {
@@ -683,8 +663,8 @@ Manager::Private::Private(not_null<Manager*> manager, Type type)
 		return;
 	}
 
-	const auto serverInformation = GetServerInformation();
-	const auto capabilities = GetCapabilities();
+	const auto serverInformation = CurrentServerInformation;
+	const auto capabilities = CurrentCapabilities;
 
 	if (!serverInformation.empty()) {
 		LOG(("Notification daemon product name: %1")
diff --git a/Telegram/SourceFiles/platform/linux/specific_linux.cpp b/Telegram/SourceFiles/platform/linux/specific_linux.cpp
index 5eac9bd28..251d5db7b 100644
--- a/Telegram/SourceFiles/platform/linux/specific_linux.cpp
+++ b/Telegram/SourceFiles/platform/linux/specific_linux.cpp
@@ -25,6 +25,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
 #include "core/application.h"
 
 #ifndef DESKTOP_APP_DISABLE_DBUS_INTEGRATION
+#include "platform/linux/linux_notification_service_watcher.h"
 #include "platform/linux/linux_gsd_media_keys.h"
 #endif // !DESKTOP_APP_DISABLE_DBUS_INTEGRATION
 
@@ -87,6 +88,8 @@ constexpr auto kXCBFrameExtentsAtomName = "_GTK_FRAME_EXTENTS"_cs;
 QStringList PlatformThemes;
 
 #ifndef DESKTOP_APP_DISABLE_DBUS_INTEGRATION
+std::unique_ptr<internal::NotificationServiceWatcher> NSWInstance;
+
 QStringList ListDBusActivatableNames() {
 	static const auto Result = [&] {
 		const auto message = QDBusMessage::createMethodCall(
@@ -632,6 +635,17 @@ bool CanOpenDirectoryWithPortal() {
 	return false;
 }
 
+bool IsNotificationServiceActivatable() {
+#ifndef DESKTOP_APP_DISABLE_DBUS_INTEGRATION
+	static const auto Result = ListDBusActivatableNames().contains(
+		qsl("org.freedesktop.Notifications"));
+
+	return Result;
+#endif // !DESKTOP_APP_DISABLE_DBUS_INTEGRATION
+
+	return false;
+}
+
 QString AppRuntimeDirectory() {
 	static const auto Result = [&] {
 		auto runtimeDir = QStandardPaths::writableLocation(
@@ -1231,9 +1245,21 @@ void start() {
 	if (const auto waylandIntegration = WaylandIntegration::Instance()) {
 		waylandIntegration->waitForInterfaceAnnounce();
 	}
+
+#ifndef DESKTOP_APP_DISABLE_DBUS_INTEGRATION
+	if (!IsNotificationServiceActivatable()) {
+		NSWInstance = std::make_unique<
+			internal::NotificationServiceWatcher>();
+	}
+#endif // !DESKTOP_APP_DISABLE_DBUS_INTEGRATION
 }
 
 void finish() {
+#ifndef DESKTOP_APP_DISABLE_DBUS_INTEGRATION
+	if (NSWInstance) {
+		NSWInstance = nullptr;
+	}
+#endif // !DESKTOP_APP_DISABLE_DBUS_INTEGRATION
 }
 
 } // namespace ThirdParty
diff --git a/Telegram/SourceFiles/platform/linux/specific_linux.h b/Telegram/SourceFiles/platform/linux/specific_linux.h
index 80584a23d..2f279c5d4 100644
--- a/Telegram/SourceFiles/platform/linux/specific_linux.h
+++ b/Telegram/SourceFiles/platform/linux/specific_linux.h
@@ -25,6 +25,7 @@ bool UseGtkIntegration();
 bool IsGtkIntegrationForced();
 bool UseXDGDesktopPortal();
 bool CanOpenDirectoryWithPortal();
+bool IsNotificationServiceActivatable();
 
 QString AppRuntimeDirectory();
 QString GetLauncherBasename();