Commit fe371b77 authored by Martin Flöser's avatar Martin Flöser

[screenlocker] Support OnScreenDisplay messages

KSld connects to the DBus signals for the OnScreenDisplay and forwards
them to the greeter application through the private Wayland protocol.
The idea here is to not have the greeter connect to the DBus as in future
it would be preferable if the greeter cannot connect to DBus.

The lookandfeel package might expose an object called "onScreenDisplay".
Whenever an OSD message is recieved by the greeter it looks for such an
object and updates the osd specific properties.

The default breeze lookandfeel package integrates the OsdItem from the
same lookandfeel package.

REVIEW: 122452
parent f962d7fb
......@@ -431,6 +431,24 @@ void UnlockApp::setNoLock(bool noLock)
m_noLock = noLock;
}
static void osdProgress(void *data, org_kde_ksld *org_kde_ksld, const char *icon, int32_t percent, const char *text)
{
Q_UNUSED(org_kde_ksld)
reinterpret_cast<UnlockApp*>(data)->osdProgress(QString::fromUtf8(icon), percent, QString::fromUtf8(text));
}
static void osdText(void *data, org_kde_ksld *org_kde_ksld, const char *icon, const char *text)
{
Q_UNUSED(org_kde_ksld)
reinterpret_cast<UnlockApp*>(data)->osdText(QString::fromUtf8(icon), QString::fromUtf8(text));
}
static const struct org_kde_ksld_listener s_listener {
osdProgress,
osdText
};
void UnlockApp::setKsldSocket(int socket)
{
using namespace KWayland::Client;
......@@ -447,6 +465,9 @@ void UnlockApp::setKsldSocket(int socket)
}
m_ksldInterface = reinterpret_cast<org_kde_ksld*>(wl_registry_bind(*m_ksldRegistry, name, &org_kde_ksld_interface, version));
queue->addProxy(m_ksldInterface);
if (version >= 2) {
org_kde_ksld_add_listener(m_ksldInterface, &s_listener, this);
}
for (auto v : m_views) {
org_kde_ksld_x11window(m_ksldInterface, v->winId());
wl_display_flush(m_ksldConnection->display());
......@@ -469,5 +490,34 @@ void UnlockApp::setKsldSocket(int socket)
m_ksldConnection->initConnection();
}
void UnlockApp::osdProgress(const QString &icon, int percent, const QString &additionalText)
{
for (auto v : m_views) {
auto osd = v->rootObject()->findChild<QQuickItem*>(QStringLiteral("onScreenDisplay"));
if (!osd) {
continue;
}
osd->setProperty("osdValue", percent);
osd->setProperty("osdAdditionalText", additionalText);
osd->setProperty("showingProgress", true);
osd->setProperty("icon", icon);
QMetaObject::invokeMethod(osd, "show");
}
}
void UnlockApp::osdText(const QString &icon, const QString &additionalText)
{
for (auto v : m_views) {
auto osd = v->rootObject()->findChild<QQuickItem*>(QStringLiteral("onScreenDisplay"));
if (!osd) {
continue;
}
osd->setProperty("showingProgress", false);
osd->setProperty("osdValue", additionalText);
osd->setProperty("icon", icon);
QMetaObject::invokeMethod(osd, "show");
}
}
} // namespace
......@@ -58,6 +58,9 @@ public:
void setNoLock(bool noLock);
void setKsldSocket(int socket);
void osdProgress(const QString &icon, int percent, const QString &additionalText);
void osdText(const QString &icon, const QString &additionalText);
public Q_SLOTS:
void desktopResized();
......
<?xml version="1.0" encoding="UTF-8"?>
<protocol name="ksld">
<interface name="org_kde_ksld" version="1">
<interface name="org_kde_ksld" version="2">
<request name="x11window">
<arg name="id" type="uint"/>
</request>
<event name="osdProgress" since="2">
<arg name="icon" type="string"/>
<arg name="percent" type="int"/>
<arg name="text" type="string"/>
</event>
<event name="osdText" since="2">
<arg name="icon" type="string"/>
<arg name="text" type="string"/>
</event>
</interface>
</protocol>
......@@ -20,11 +20,13 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "waylandserver.h"
// ksld
#include <config-ksmserver.h>
// Wayland
#include <wayland-server.h>
#include <wayland-ksld-server-protocol.h>
// KWayland
#include <KWayland/Server/display.h>
// Wayland
#include <wayland-server.h>
// Qt
#include <QDBusConnection>
// system
#include <unistd.h>
#include <fcntl.h>
......@@ -34,9 +36,24 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
namespace ScreenLocker
{
static const QString s_plasmaShellService = QStringLiteral("org.kde.plasmashell");
static const QString s_osdServicePath = QStringLiteral("/org/kde/osdService");
static const QString s_osdServiceInterface = QStringLiteral("org.kde.osdService");
WaylandServer::WaylandServer(QObject *parent)
: QObject(parent)
{
// connect to osd service
QDBusConnection::sessionBus().connect(s_plasmaShellService,
s_osdServicePath,
s_osdServiceInterface,
QStringLiteral("osdProgress"),
this, SLOT(osdProgress(QString,int,QString)));
QDBusConnection::sessionBus().connect(s_plasmaShellService,
s_osdServicePath,
s_osdServiceInterface,
QStringLiteral("osdText"),
this, SLOT(osdText(QString,QString)));
}
WaylandServer::~WaylandServer()
......@@ -67,7 +84,7 @@ int WaylandServer::start()
close(socketPair[1]);
return -1;
}
m_interface = wl_global_create(*m_display.data(), &org_kde_ksld_interface, 1, this, bind);
m_interface = wl_global_create(*m_display.data(), &org_kde_ksld_interface, 2, this, bind);
return socketPair[1];
}
......@@ -89,7 +106,7 @@ void WaylandServer::bind(wl_client *client, void *data, uint32_t version, uint32
wl_client_post_no_memory(client);
return;
}
wl_resource *r = s->m_allowedClient->createResource(&org_kde_ksld_interface, qMin(version, 1u), id);
wl_resource *r = s->m_allowedClient->createResource(&org_kde_ksld_interface, qMin(version, 2u), id);
if (!r) {
wl_client_post_no_memory(client);
return;
......@@ -99,12 +116,13 @@ void WaylandServer::bind(wl_client *client, void *data, uint32_t version, uint32
x11WindowCallback
};
wl_resource_set_implementation(r, &s_interface, s, unbind);
s->addResource(r);
s->m_allowedClient->flush();
}
void WaylandServer::unbind(wl_resource *resource)
{
Q_UNUSED(resource)
reinterpret_cast<WaylandServer*>(wl_resource_get_user_data(resource))->removeResource(resource);
}
void WaylandServer::x11WindowCallback(wl_client *client, wl_resource *resource, uint32_t id)
......@@ -116,4 +134,36 @@ void WaylandServer::x11WindowCallback(wl_client *client, wl_resource *resource,
emit s->x11WindowAdded(id);
}
void WaylandServer::addResource(wl_resource *r)
{
m_resources.append(r);
}
void WaylandServer::removeResource(wl_resource *r)
{
m_resources.removeAll(r);
}
void WaylandServer::osdProgress(const QString &icon, int percent, const QString &additionalText)
{
for (auto r : m_resources) {
if (wl_resource_get_version(r) < 2) {
continue;
}
org_kde_ksld_send_osdProgress(r, icon.toUtf8().constData(), percent, additionalText.toUtf8().constData());
m_allowedClient->flush();
}
}
void WaylandServer::osdText(const QString &icon, const QString &additionalText)
{
for (auto r : m_resources) {
if (wl_resource_get_version(r) < 2) {
continue;
}
org_kde_ksld_send_osdText(r, icon.toUtf8().constData(), additionalText.toUtf8().constData());
m_allowedClient->flush();
}
}
}
......@@ -50,13 +50,20 @@ public:
Q_SIGNALS:
void x11WindowAdded(quint32 window);
private Q_SLOTS:
void osdProgress(const QString &icon, int percent, const QString &additionalText);
void osdText(const QString &icon, const QString &additionalText);
private:
static void bind(wl_client *client, void *data, uint32_t version, uint32_t id);
static void unbind(wl_resource *resource);
static void x11WindowCallback(wl_client *client, wl_resource *resource, uint32_t id);
void addResource(wl_resource *r);
void removeResource(wl_resource *r);
QScopedPointer<KWayland::Server::Display> m_display;
KWayland::Server::ClientConnection *m_allowedClient = nullptr;
wl_global *m_interface = nullptr;
QList<wl_resource*> m_resources;
};
}
......
Markdown is supported
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