17#include <sys/socket.h>
19#include <QAbstractEventDispatcher>
20#include <QCoreApplication>
42Display::Display(QObject *parent)
46 d->display = wl_display_create();
47 d->loop = wl_display_get_event_loop(d->display);
52 wl_display_destroy_clients(d->display);
53 wl_display_destroy(d->display);
56bool Display::addSocketFileDescriptor(
int fileDescriptor,
const QString &name)
58 if (wl_display_add_socket_fd(d->display, fileDescriptor)) {
59 qCWarning(KWIN_CORE,
"Failed to add %d fd to display", fileDescriptor);
62 if (!name.isEmpty()) {
63 d->registerSocketName(name);
68bool Display::addSocketName(
const QString &name)
71 const char *socket = wl_display_add_socket_auto(d->display);
73 qCWarning(KWIN_CORE,
"Failed to find a free display socket");
76 d->registerSocketName(QString::fromUtf8(socket));
78 if (wl_display_add_socket(d->display, qPrintable(name))) {
79 qCWarning(KWIN_CORE,
"Failed to add %s socket to display", qPrintable(name));
82 d->registerSocketName(name);
87QStringList Display::socketNames()
const
89 return d->socketNames;
98 const int fileDescriptor = wl_event_loop_get_fd(d->loop);
99 if (fileDescriptor == -1) {
100 qCWarning(KWIN_CORE) <<
"Did not get the file descriptor for the event loop";
104 d->socketNotifier =
new QSocketNotifier(fileDescriptor, QSocketNotifier::Read,
this);
105 connect(d->socketNotifier, &QSocketNotifier::activated,
this, &Display::dispatchEvents);
107 QAbstractEventDispatcher *dispatcher = QCoreApplication::eventDispatcher();
108 connect(dispatcher, &QAbstractEventDispatcher::aboutToBlock,
this, &Display::flush);
116void Display::dispatchEvents()
118 if (wl_event_loop_dispatch(d->loop, 0) != 0) {
119 qCWarning(KWIN_CORE) <<
"Error on dispatching Wayland event loop";
125 wl_display_flush_clients(d->display);
128void Display::createShm()
130 Q_ASSERT(d->display);
134quint32 Display::nextSerial()
136 return wl_display_next_serial(d->display);
139quint32 Display::serial()
141 return wl_display_get_serial(d->display);
144bool Display::isRunning()
const
149Display::operator wl_display *()
154Display::operator wl_display *()
const
159QList<OutputInterface *> Display::outputs()
const
164QList<OutputDeviceV2Interface *> Display::outputDevices()
const
166 return d->outputdevicesV2;
169QList<OutputInterface *> Display::outputsIntersecting(
const QRect &rect)
const
171 QList<OutputInterface *>
outputs;
172 for (
auto *output : std::as_const(d->outputs)) {
173 if (output->handle()->geometry().intersects(rect)) {
183 uint64_t biggestArea = 0;
184 for (
auto *output : std::as_const(d->outputs)) {
185 const QRect intersect = output->
handle()->
geometry().intersected(rect);
186 const uint64_t area = intersect.width() * intersect.height();
187 if (area > biggestArea) {
189 returnOutput = output;
195QList<SeatInterface *> Display::seats()
const
203 auto it = std::find_if(d->clients.constBegin(), d->clients.constEnd(), [client](
ClientConnection *c) {
204 return c->client() == client;
206 if (it != d->clients.constEnd()) {
213 const int index = d->clients.indexOf(c);
214 Q_ASSERT(index != -1);
215 d->clients.remove(index);
216 Q_ASSERT(d->clients.indexOf(c) == -1);
223QList<ClientConnection *> Display::connections()
const
231 Q_ASSERT(d->display);
232 wl_client *c = wl_client_create(d->display, fd);
253 , m_listenFd(std::move(listenFd))
254 , m_closeFd(std::move(closeFd))
257 qCDebug(KWIN_CORE) <<
"Adding listen fd for" << appId;
259 auto closeSocketWatcher =
new QSocketNotifier(m_closeFd.
get(), QSocketNotifier::Read,
this);
260 connect(closeSocketWatcher, &QSocketNotifier::activated,
this, &SecurityContext::onCloseFdActivated);
267 auto listenFdListener =
new QSocketNotifier(m_listenFd.
get(), QSocketNotifier::Read,
this);
268 connect(listenFdListener, &QSocketNotifier::activated,
this, &SecurityContext::onListenFdActivated);
273 qCDebug(KWIN_CORE) <<
"Removing listen fd for " << m_appId;
276void SecurityContext::onListenFdActivated(QSocketDescriptor socketDescriptor)
278 int clientFd = accept4(socketDescriptor,
nullptr,
nullptr, SOCK_CLOEXEC);
280 qCWarning(KWIN_CORE) <<
"Failed to accept client from security listen FD";
287void SecurityContext::onCloseFdActivated()
296#include "moc_display.cpp"
Convenient Class which represents a wl_client.
void setSecurityContextAppId(const QString &appId)
void disconnected(KWin::ClientConnection *)
Class holding the Wayland server display loop.
void clientConnected(KWin::ClientConnection *)
ClientConnection * createClient(int fd)
void clientDisconnected(KWin::ClientConnection *)
QList< OutputInterface * > outputs() const
ClientConnection * getConnection(wl_client *client)
void runningChanged(bool)
void socketNamesChanged()
static DisplayPrivate * get(Display *display)
DisplayPrivate(Display *q)
void registerSocketName(const QString &socketName)
~SecurityContext() override
SecurityContext(Display *display, FileDescriptor &&listenFd, FileDescriptor &&closeFd, const QString &appId)
static LinuxDmaBufV1ClientBuffer * get(wl_resource *resource)
static ShmClientBuffer * get(wl_resource *resource)