Get linux notification inhibition state asynchronously

This is the last sync request in the D-Bus notifications
This commit is contained in:
Ilya Fedin 2022-07-26 05:32:33 +04:00 committed by John Preston
parent e9e5dedeed
commit d2e3c01c11

View file

@ -46,7 +46,6 @@ struct ServerInformation {
}; };
bool ServiceRegistered = false; bool ServiceRegistered = false;
bool InhibitionSupported = false;
std::optional<ServerInformation> CurrentServerInformation; std::optional<ServerInformation> CurrentServerInformation;
QStringList CurrentCapabilities; QStringList CurrentCapabilities;
@ -267,7 +266,13 @@ void GetCapabilities(Fn<void(const QStringList &)> callback) {
crl::on_main([=] { callback({}); }); crl::on_main([=] { callback({}); });
} }
void GetInhibitionSupported(Fn<void(bool)> callback) { void GetInhibited(Fn<void(bool)> callback) {
if (!Supported()
|| !CurrentCapabilities.contains(qsl("inhibitions"))) {
crl::on_main([=] { callback(false); });
return;
}
try { try {
const auto connection = Gio::DBus::Connection::get_sync( const auto connection = Gio::DBus::Connection::get_sync(
Gio::DBus::BusType::BUS_TYPE_SESSION); Gio::DBus::BusType::BUS_TYPE_SESSION);
@ -282,24 +287,23 @@ void GetInhibitionSupported(Fn<void(bool)> callback) {
}), }),
[=](const Glib::RefPtr<Gio::AsyncResult> &result) { [=](const Glib::RefPtr<Gio::AsyncResult> &result) {
try { try {
connection->call_finish(result); auto reply = connection->call_finish(result);
const auto value = GlibVariantCast<bool>(
GlibVariantCast<Glib::VariantBase>(
reply.get_child(0)));
crl::on_main([=] { crl::on_main([=] {
callback(true); callback(value);
}); });
return; return;
} catch (const Glib::Error &e) { } catch (const Glib::Error &e) {
static const auto DontLogErrors = { LOG(("Native Notification Error: %1").arg(
"org.freedesktop.DBus.Error.InvalidArgs", QString::fromStdString(e.what())));
"org.freedesktop.DBus.Error.UnknownMethod", } catch (const std::exception &e) {
}; LOG(("Native Notification Error: %1").arg(
QString::fromStdString(e.what())));
const auto errorName = Gio::DBus::ErrorUtils::get_remote_error(e);
if (!ranges::contains(DontLogErrors, errorName)) {
LOG(("Native Notification Error: %1").arg(
QString::fromStdString(e.what())));
}
} }
crl::on_main([=] { callback(false); }); crl::on_main([=] { callback(false); });
@ -315,45 +319,6 @@ void GetInhibitionSupported(Fn<void(bool)> callback) {
crl::on_main([=] { callback(false); }); crl::on_main([=] { callback(false); });
} }
bool Inhibited() {
if (!Supported()
|| !CurrentCapabilities.contains(qsl("inhibitions"))
|| !InhibitionSupported) {
return false;
}
try {
const auto connection = Gio::DBus::Connection::get_sync(
Gio::DBus::BusType::BUS_TYPE_SESSION);
// a hack for snap's activation restriction
DBus::StartServiceByName(
connection,
std::string(kService));
auto reply = connection->call_sync(
std::string(kObjectPath),
std::string(kPropertiesInterface),
"Get",
MakeGlibVariant(std::tuple{
Glib::ustring(std::string(kInterface)),
Glib::ustring("Inhibited"),
}),
std::string(kService));
return GlibVariantCast<bool>(
GlibVariantCast<Glib::VariantBase>(reply.get_child(0)));
} catch (const Glib::Error &e) {
LOG(("Native Notification Error: %1").arg(
QString::fromStdString(e.what())));
} catch (const std::exception &e) {
LOG(("Native Notification Error: %1").arg(
QString::fromStdString(e.what())));
}
return false;
}
bool IsQualifiedDaemon() { bool IsQualifiedDaemon() {
// A list of capabilities that offer feature parity // A list of capabilities that offer feature parity
// with custom notifications // with custom notifications
@ -373,7 +338,7 @@ bool IsQualifiedDaemon() {
return ranges::all_of(NeededCapabilities, [&](const auto &capability) { return ranges::all_of(NeededCapabilities, [&](const auto &capability) {
return CurrentCapabilities.contains(capability); return CurrentCapabilities.contains(capability);
}) && InhibitionSupported; });
} }
ServerInformation CurrentServerInformationValue() { ServerInformation CurrentServerInformationValue() {
@ -820,7 +785,7 @@ void Create(Window::Notifications::System *system) {
} }
}; };
const auto counter = std::make_shared<int>(3); const auto counter = std::make_shared<int>(2);
const auto oneReady = [=] { const auto oneReady = [=] {
if (!--*counter) { if (!--*counter) {
managerSetter(); managerSetter();
@ -833,7 +798,6 @@ void Create(Window::Notifications::System *system) {
if (!ServiceRegistered) { if (!ServiceRegistered) {
CurrentServerInformation = std::nullopt; CurrentServerInformation = std::nullopt;
CurrentCapabilities = QStringList{}; CurrentCapabilities = QStringList{};
InhibitionSupported = false;
managerSetter(); managerSetter();
return; return;
} }
@ -847,11 +811,6 @@ void Create(Window::Notifications::System *system) {
CurrentCapabilities = result; CurrentCapabilities = result;
oneReady(); oneReady();
}); });
GetInhibitionSupported([=](bool result) {
InhibitionSupported = result;
oneReady();
});
}; };
// There are some asserts that manager is not nullptr, // There are some asserts that manager is not nullptr,
@ -884,6 +843,10 @@ public:
void clearFromSession(not_null<Main::Session*> session); void clearFromSession(not_null<Main::Session*> session);
void clearNotification(NotificationId id); void clearNotification(NotificationId id);
bool inhibited() {
return _inhibited;
}
~Private(); ~Private();
private: private:
@ -895,6 +858,10 @@ private:
Window::Notifications::CachedUserpics _cachedUserpics; Window::Notifications::CachedUserpics _cachedUserpics;
Glib::RefPtr<Gio::DBus::Connection> _dbusConnection;
bool _inhibited = false;
uint _inhibitedSignalId = 0;
}; };
Manager::Private::Private(not_null<Manager*> manager, Type type) Manager::Private::Private(not_null<Manager*> manager, Type type)
@ -925,6 +892,49 @@ Manager::Private::Private(not_null<Manager*> manager, Type type)
LOG(("Notification daemon capabilities: %1") LOG(("Notification daemon capabilities: %1")
.arg(capabilities.join(", "))); .arg(capabilities.join(", ")));
} }
try {
_dbusConnection = Gio::DBus::Connection::get_sync(
Gio::DBus::BusType::BUS_TYPE_SESSION);
} catch (const Glib::Error &e) {
LOG(("Native Notification Error: %1").arg(
QString::fromStdString(e.what())));
return;
}
GetInhibited([=](bool result) {
_inhibited = result;
});
_inhibitedSignalId = _dbusConnection->signal_subscribe(
[=](
const Glib::RefPtr<Gio::DBus::Connection> &connection,
const Glib::ustring &sender_name,
const Glib::ustring &object_path,
const Glib::ustring &interface_name,
const Glib::ustring &signal_name,
Glib::VariantContainerBase parameters) {
try {
const auto interface = GlibVariantCast<Glib::ustring>(
parameters.get_child(0));
if (interface != std::string(kInterface)) {
return;
}
_inhibited = GlibVariantCast<bool>(
GlibVariantCast<
std::map<Glib::ustring, Glib::VariantBase>
>(parameters.get_child(1)).at("Inhibited"));
} catch (const std::exception &e) {
LOG(("Native Notification Error: %1").arg(
QString::fromStdString(e.what())));
}
},
std::string(kService),
std::string(kPropertiesInterface),
"PropertiesChanged",
std::string(kObjectPath));
} }
void Manager::Private::showNotification( void Manager::Private::showNotification(
@ -1074,6 +1084,12 @@ void Manager::Private::clearNotification(NotificationId id) {
Manager::Private::~Private() { Manager::Private::~Private() {
clearAll(); clearAll();
if (_dbusConnection) {
if (_inhibitedSignalId != 0) {
_dbusConnection->signal_unsubscribe(_inhibitedSignalId);
}
}
} }
Manager::Manager(not_null<Window::Notifications::System*> system) Manager::Manager(not_null<Window::Notifications::System*> system)
@ -1122,7 +1138,7 @@ void Manager::doClearFromSession(not_null<Main::Session*> session) {
} }
bool Manager::doSkipAudio() const { bool Manager::doSkipAudio() const {
return Inhibited(); return _private->inhibited();
} }
bool Manager::doSkipToast() const { bool Manager::doSkipToast() const {
@ -1130,7 +1146,7 @@ bool Manager::doSkipToast() const {
} }
bool Manager::doSkipFlashBounce() const { bool Manager::doSkipFlashBounce() const {
return Inhibited(); return _private->inhibited();
} }
} // namespace Notifications } // namespace Notifications