summaryrefslogtreecommitdiffstats
path: root/Telegram/SourceFiles/platform/linux/linux_notification_service_watcher.cpp
blob: 8c5223b5600bc9d472704b1c3141b5ed89e11cc2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
/*
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 "base/platform/linux/base_linux_glibmm_helper.h"
#include "base/platform/linux/base_linux_dbus_utilities.h"

#include <glibmm.h>
#include <giomm.h>

namespace Platform {
namespace internal {
namespace {

constexpr auto kNotificationService = "org.freedesktop.Notifications"_cs;

bool IsNotificationServiceActivatable() {
	static const auto Result = [] {
		try {
			const auto connection = Gio::DBus::Connection::get_sync(
				Gio::DBus::BusType::BUS_TYPE_SESSION);

			return ranges::contains(
				base::Platform::DBus::ListActivatableNames(connection),
				Glib::ustring(std::string(kNotificationService)));
		} catch (...) {
		}

		return false;
	}();

	return Result;
}

} // namespace

class NotificationServiceWatcher::Private {
public:
	Glib::RefPtr<Gio::DBus::Connection> dbusConnection;
	uint signalId = 0;
};

NotificationServiceWatcher::NotificationServiceWatcher()
: _private(std::make_unique<Private>()) {
	try {
		_private->dbusConnection = Gio::DBus::Connection::get_sync(
			Gio::DBus::BusType::BUS_TYPE_SESSION);

		_private->signalId = base::Platform::DBus::RegisterServiceWatcher(
			_private->dbusConnection,
			std::string(kNotificationService),
			[](
				const Glib::ustring &service,
				const Glib::ustring &oldOwner,
				const Glib::ustring &newOwner) {
				if (!Core::App().domain().started()
					|| (IsNotificationServiceActivatable()
						&& newOwner.empty())) {
					return;
				}

				crl::on_main([] {
					Core::App().notifications().createManager();
				});
			});
	} catch (...) {
	}
}

NotificationServiceWatcher::~NotificationServiceWatcher() {
	if (_private->dbusConnection && _private->signalId != 0) {
		_private->dbusConnection->signal_unsubscribe(_private->signalId);
	}
}

} // namespace internal
} // namespace Platform