Commit 1cfea605 authored by Kai Uwe Broulik's avatar Kai Uwe Broulik 🍇
Browse files

ScreenCast: Inhibit notifications when screen casting

parent b7ead495
......@@ -17,6 +17,7 @@ set(xdg_desktop_portal_kde_SRCS
filechooser.cpp
inhibit.cpp
notification.cpp
notificationinhibition.cpp
print.cpp
request.cpp
session.cpp
......
/*
* Copyright (c) 2020 Kai Uwe Broulik <kde@broulik.de>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#include "notificationinhibition.h"
#include <QDBusConnection>
#include <QDBusMessage>
#include <QDBusPendingCall>
#include <QDBusPendingCallWatcher>
#include <QDBusPendingReply>
#include <QLoggingCategory>
#include <QPointer>
Q_LOGGING_CATEGORY(XdgDesktopPortalKdeNotificationInhibition, "xdp-kde-notificationinhibition")
static const auto s_notificationService = QStringLiteral("org.freedesktop.Notifications");
static const auto s_notificationPath = QStringLiteral("/org/freedesktop/Notifications");
static const auto s_notificationInterface = QStringLiteral("org.freedesktop.Notifications");
NotificationInhibition::NotificationInhibition(const QString &appId, const QString &reason, QObject *parent)
: QObject(parent)
{
QDBusMessage msg = QDBusMessage::createMethodCall(s_notificationService,
s_notificationPath,
s_notificationInterface,
QStringLiteral("Inhibit"));
msg.setArguments({
appId,
reason,
QVariantMap()
});
QPointer<NotificationInhibition> guardedThis(this);
QDBusPendingCall pendingCall = QDBusConnection::sessionBus().asyncCall(msg);
QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pendingCall);
connect(watcher, &QDBusPendingCallWatcher::finished, [guardedThis, appId, reason](QDBusPendingCallWatcher *watcher) {
QDBusPendingReply<uint> reply = *watcher;
watcher->deleteLater();
if (reply.isError()) {
qCDebug(XdgDesktopPortalKdeNotificationInhibition) << "Failed to inhibit: " << reply.error().message();
return;
}
const auto cookie = reply.value();
// In case the inhibition was revoked again before the async DBus reply arrived
if (guardedThis) {
qCDebug(XdgDesktopPortalKdeNotificationInhibition) << "Inhibiting notifications for" << appId
<< "with reason" << reason
<< "and cookie" << cookie;
guardedThis->m_cookie = cookie;
} else {
uninhibit(cookie);
}
});
}
NotificationInhibition::~NotificationInhibition()
{
if (m_cookie) {
uninhibit(m_cookie);
}
}
void NotificationInhibition::uninhibit(uint cookie)
{
qCDebug(XdgDesktopPortalKdeNotificationInhibition) << "Removing inhibition with cookie" << cookie;
QDBusMessage msg = QDBusMessage::createMethodCall(s_notificationService,
s_notificationPath,
s_notificationInterface,
QStringLiteral("UnInhibit"));
msg.setArguments({cookie});
QDBusConnection::sessionBus().call(msg, QDBus::NoBlock);
}
/*
* Copyright (c) 2020 Kai Uwe Broulik <kde@broulik.de>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef XDG_DESKTOP_PORTAL_KDE_NOTIFICATIONINHIBITION_H
#define XDG_DESKTOP_PORTAL_KDE_NOTIFICATIONINHIBITION_H
#include <QObject>
class NotificationInhibition : public QObject
{
Q_OBJECT
public:
explicit NotificationInhibition(const QString &appId,
const QString &reason,
QObject *parent = nullptr);
~NotificationInhibition() override;
private:
static void uninhibit(uint cookie);
uint m_cookie = 0;
};
#endif // XDG_DESKTOP_PORTAL_KDE_NOTIFICATIONINHIBITION_H
......@@ -18,12 +18,17 @@
* Jan Grulich <jgrulich@redhat.com>
*/
#include "notificationinhibition.h"
#include "screencast.h"
#include "screenchooserdialog.h"
#include "session.h"
#include "utils.h"
#include "waylandintegration.h"
#include <KConfigGroup>
#include <KLocalizedString>
#include <KSharedConfig>
#include <QLoggingCategory>
Q_LOGGING_CATEGORY(XdgDesktopPortalKdeScreenCast, "xdp-kde-screencast")
......@@ -37,6 +42,19 @@ ScreenCastPortal::~ScreenCastPortal()
{
}
bool ScreenCastPortal::inhibitionsEnabled() const
{
if (!WaylandIntegration::isStreamingAvailable()) {
return false;
}
auto cfg = KSharedConfig::openConfig(QStringLiteral("plasmanotifyrc"));
KConfigGroup grp(cfg, "DoNotDisturb");
return grp.readEntry("WhenScreenSharing", true);
}
uint ScreenCastPortal::CreateSession(const QDBusObjectPath &handle,
const QDBusObjectPath &session_handle,
const QString &app_id,
......@@ -161,6 +179,10 @@ uint ScreenCastPortal::Start(const QDBusObjectPath &handle,
results.insert(QStringLiteral("streams"), streams);
if (inhibitionsEnabled()) {
new NotificationInhibition(app_id, i18nc("Do not disturb mode is enabled because...", "Screen sharing in progress"), session);
}
return 0;
}
......
......@@ -82,6 +82,9 @@ public Q_SLOTS:
const QString &parent_window,
const QVariantMap &options,
QVariantMap &results);
private:
bool inhibitionsEnabled() const;
};
#endif // XDG_DESKTOP_PORTAL_KDE_SCREENCAST_H
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment