Commit bb91c948 authored by Arjen Hiemstra's avatar Arjen Hiemstra
Browse files

Expose Workspace::showingDesktop and a setter as D-Bus api

This allows us to unify the X and Wayland codepaths that currently go
through window-system specific IPC. It also allows us to easily track
who called "setShowingDesktop" and cancel the effect when that client
disappears.

CCBUG: 449445
parent e0a6d029
......@@ -49,6 +49,8 @@ DBusInterface::DBusInterface(QObject *parent)
dbus.registerService(m_serviceName);
dbus.connect(QString(), QStringLiteral("/KWin"), QStringLiteral("org.kde.KWin"), QStringLiteral("reloadConfig"),
Workspace::self(), SLOT(slotReloadConfig()));
connect(Workspace::self(), &Workspace::showingDesktopChanged, this, &DBusInterface::onShowingDesktopChanged);
}
DBusInterface::~DBusInterface()
......@@ -56,6 +58,11 @@ DBusInterface::~DBusInterface()
QDBusConnection::sessionBus().unregisterService(m_serviceName);
}
bool DBusInterface::showingDesktop() const
{
return workspace()->showingDesktop();
}
// wrap void methods with no arguments to Workspace
#define WRAP(name) \
void DBusInterface::name() \
......@@ -229,6 +236,45 @@ QVariantMap DBusInterface::getWindowInfo(const QString &uuid)
}
}
void DBusInterface::showDesktop(bool show)
{
workspace()->setShowingDesktop(show, true);
auto m = message();
if (m.service().isEmpty()) {
return;
}
// Keep track of whatever D-Bus client asked to show the desktop. If
// they disappear from the bus, cancel the show desktop state so we do
// not end up in a state where we are stuck showing the desktop.
static QPointer<QDBusServiceWatcher> watcher;
if (show) {
if (watcher) {
// If we get a second call to `showDesktop(true)`, drop the previous
// watcher and watch the new client. That way, we simply always
// track the last state.
watcher->deleteLater();
}
watcher = new QDBusServiceWatcher(m.service(), QDBusConnection::sessionBus(), QDBusServiceWatcher::WatchForUnregistration, this);
connect(watcher, &QDBusServiceWatcher::serviceUnregistered, []() {
workspace()->setShowingDesktop(false, true);
watcher->deleteLater();
});
} else if (watcher) {
// Someone cancelled showing the desktop, so there's no more need to
// watch to cancel the show desktop state.
watcher->deleteLater();
}
}
void DBusInterface::onShowingDesktopChanged(bool show, bool /*animated*/)
{
Q_EMIT showingDesktopChanged(show);
}
CompositorDBusInterface::CompositorDBusInterface(Compositor *parent)
: QObject(parent)
, m_compositor(parent)
......
......@@ -45,6 +45,9 @@ public:
~DBusInterface() override;
public: // PROPERTIES
Q_PROPERTY(bool showingDesktop READ showingDesktop NOTIFY showingDesktopChanged)
bool showingDesktop() const;
public Q_SLOTS: // METHODS
Q_NOREPLY void cascadeDesktop();
int currentDesktop();
......@@ -86,6 +89,14 @@ public Q_SLOTS: // METHODS
*/
QVariantMap getWindowInfo(const QString &uuid);
Q_NOREPLY void showDesktop(bool show);
Q_SIGNALS:
void showingDesktopChanged(bool showing);
private Q_SLOTS:
void onShowingDesktopChanged(bool show, bool /*animated*/);
private:
QString m_serviceName;
QDBusMessage m_replyQueryWindowInfo;
......
......@@ -49,5 +49,14 @@
<arg type="s" direction="in"/>
<arg type="a{sv}" direction="out"/>
</method>
<property name="showingDesktop" type="b" access="read"/>
<method name="showDesktop">
<annotation name="org.freedesktop.DBus.Method.NoReply" value="true"/>
<arg name="showing" type="b" direction="in"/>
</method>
<signal name="showingDesktopChanged">
<arg name="showing" type="b" direction="out"/>
</signal>
</interface>
</node>
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