summaryrefslogtreecommitdiffstats
path: root/src/compositor/compositor_api/qwaylandcompositor.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/compositor/compositor_api/qwaylandcompositor.cpp')
-rw-r--r--src/compositor/compositor_api/qwaylandcompositor.cpp364
1 files changed, 234 insertions, 130 deletions
diff --git a/src/compositor/compositor_api/qwaylandcompositor.cpp b/src/compositor/compositor_api/qwaylandcompositor.cpp
index 52ffb9166..e6f5955b8 100644
--- a/src/compositor/compositor_api/qwaylandcompositor.cpp
+++ b/src/compositor/compositor_api/qwaylandcompositor.cpp
@@ -1,42 +1,6 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
-** Copyright (C) 2017 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWaylandCompositor module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2017 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include "qtwaylandcompositorglobal_p.h"
#include "qwaylandcompositor.h"
@@ -72,12 +36,12 @@
#include "extensions/qwaylandqtwindowmanager.h"
-#include "qwaylandxkb_p.h"
#include "qwaylandsharedmemoryformathelper_p.h"
#include <QtCore/QCoreApplication>
#include <QtCore/QStringList>
#include <QtCore/QSocketNotifier>
+#include <QStandardPaths>
#include <QtGui/QDesktopServices>
#include <QtGui/QScreen>
@@ -99,6 +63,7 @@ QT_BEGIN_NAMESPACE
Q_LOGGING_CATEGORY(qLcWaylandCompositor, "qt.waylandcompositor")
Q_LOGGING_CATEGORY(qLcWaylandCompositorHardwareIntegration, "qt.waylandcompositor.hardwareintegration")
Q_LOGGING_CATEGORY(qLcWaylandCompositorInputMethods, "qt.waylandcompositor.inputmethods")
+Q_LOGGING_CATEGORY(qLcWaylandCompositorTextInput, "qt.waylandcompositor.textinput")
namespace QtWayland {
@@ -125,16 +90,27 @@ public:
QWaylandKeyboardPrivate *keyb = QWaylandKeyboardPrivate::get(seat->keyboard());
+#if defined(Q_OS_QNX)
+ // The QNX platform plugin delivers scan codes that haven't been adjusted to be
+ // xkbcommon compatible. xkbcommon requires that the scan codes be bumped up by
+ // 8 because that's how evdev/XKB deliver scan codes. You might think that it
+ // would've been better to remove this (odd) requirement from xkbcommon on QNX
+ // but it turns out that conforming to it has much less impact.
+ static int offset = QGuiApplication::platformName() == QStringLiteral("qnx") ? 8 : 0;
+ ke->nativeScanCode += offset;
+#endif
uint32_t code = ke->nativeScanCode;
+ if (code == 0)
+ code = seat->keyboard()->keyToScanCode(ke->key);
bool isDown = ke->keyType == QEvent::KeyPress;
#if QT_CONFIG(xkbcommon)
- QString text;
- Qt::KeyboardModifiers modifiers = QWaylandXkb::modifiers(keyb->xkbState());
+ xkb_state *xkbState = keyb->xkbState();
- const xkb_keysym_t sym = xkb_state_key_get_one_sym(keyb->xkbState(), code);
- int qtkey;
- std::tie(qtkey, text) = QWaylandXkb::keysymToQtKey(sym, modifiers);
+ const xkb_keysym_t sym = xkb_state_key_get_one_sym(xkbState, code);
+ Qt::KeyboardModifiers modifiers = QXkbCommon::modifiers(xkbState, sym);
+ int qtkey = QXkbCommon::keysymToQtKey(sym, modifiers, xkbState, code);
+ QString text = QXkbCommon::lookupString(xkbState, code);
ke->key = qtkey;
ke->modifiers = modifiers;
@@ -160,14 +136,29 @@ public:
QWaylandCompositorPrivate::QWaylandCompositorPrivate(QWaylandCompositor *compositor)
{
+ // Create XDG_RUNTIME_DIR, if it does not already exist
+ QStandardPaths::writableLocation(QStandardPaths::RuntimeLocation);
+
if (QGuiApplication::platformNativeInterface())
display = static_cast<wl_display*>(QGuiApplication::platformNativeInterface()->nativeResourceForIntegration("server_wl_display"));
- if (!display)
+
+ if (!display) {
display = wl_display_create();
+ ownsDisplay = true;
+ }
+
eventHandler.reset(new QtWayland::WindowSystemEventHandler(compositor));
timer.start();
QWindowSystemInterfacePrivate::installWindowSystemEventHandler(eventHandler.data());
+
+#if QT_CONFIG(xkbcommon)
+ mXkbContext.reset(xkb_context_new(XKB_CONTEXT_NO_FLAGS));
+ if (!mXkbContext) {
+ qWarning("Failed to create a XKB context: keymap will not be supported");
+ return;
+ }
+#endif
}
void QWaylandCompositorPrivate::init()
@@ -179,8 +170,10 @@ void QWaylandCompositorPrivate::init()
const int socketArg = arguments.indexOf(QLatin1String("--wayland-socket-name"));
if (socketArg != -1 && socketArg + 1 < arguments.size())
socket_name = arguments.at(socketArg + 1).toLocal8Bit();
+ if (socket_name.isEmpty())
+ socket_name = qgetenv("WAYLAND_DISPLAY");
}
- wl_compositor::init(display, 3);
+ wl_compositor::init(display, 4);
wl_subcompositor::init(display, 1);
#if QT_CONFIG(wayland_datadevice)
@@ -189,41 +182,44 @@ void QWaylandCompositorPrivate::init()
buffer_manager = new QtWayland::BufferManager(q);
wl_display_init_shm(display);
- QVector<wl_shm_format> formats = QWaylandSharedMemoryFormatHelper::supportedWaylandFormats();
- foreach (wl_shm_format format, formats)
- wl_display_add_shm_format(display, format);
+
+ for (QWaylandCompositor::ShmFormat format : shmFormats)
+ wl_display_add_shm_format(display, wl_shm_format(format));
if (!socket_name.isEmpty()) {
if (wl_display_add_socket(display, socket_name.constData()))
- qFatal("Fatal: Failed to open server socket\n");
+ qFatal("Fatal: Failed to open server socket: \"%s\". XDG_RUNTIME_DIR is: \"%s\"\n", socket_name.constData(), getenv("XDG_RUNTIME_DIR"));
} else {
const char *autoSocketName = wl_display_add_socket_auto(display);
if (!autoSocketName)
- qFatal("Fatal: Failed to open server socket\n");
+ qFatal("Fatal: Failed to open default server socket. XDG_RUNTIME_DIR is: \"%s\"\n", getenv("XDG_RUNTIME_DIR"));
socket_name = autoSocketName;
emit q->socketNameChanged(socket_name);
}
-#if WAYLAND_VERSION_MAJOR >= 1 && (WAYLAND_VERSION_MAJOR != 1 || WAYLAND_VERSION_MINOR >= 10)
connectToExternalSockets();
-#endif
loop = wl_display_get_event_loop(display);
int fd = wl_event_loop_get_fd(loop);
QSocketNotifier *sockNot = new QSocketNotifier(fd, QSocketNotifier::Read, q);
- QObject::connect(sockNot, SIGNAL(activated(int)), q, SLOT(processWaylandEvents()));
+ QObject::connect(sockNot, SIGNAL(activated(QSocketDescriptor)), q, SLOT(processWaylandEvents()));
QAbstractEventDispatcher *dispatcher = QGuiApplicationPrivate::eventDispatcher;
QObject::connect(dispatcher, SIGNAL(aboutToBlock()), q, SLOT(processWaylandEvents()));
+ QObject::connect(static_cast<QGuiApplication *>(QGuiApplication::instance()),
+ &QGuiApplication::applicationStateChanged,
+ q,
+ &QWaylandCompositor::applicationStateChanged);
+
initializeHardwareIntegration();
initializeSeats();
initialized = true;
- Q_FOREACH (QPointer<QObject> object, polish_objects) {
+ for (const QPointer<QObject> &object : std::exchange(polish_objects, {})) {
if (object) {
QEvent polishEvent(QEvent::Polish);
QCoreApplication::sendEvent(object.data(), &polishEvent);
@@ -235,20 +231,22 @@ void QWaylandCompositorPrivate::init()
QWaylandCompositorPrivate::~QWaylandCompositorPrivate()
{
- qDeleteAll(clients);
+ // Take copies, since the lists will get modified as elements are deleted
+ const auto clientsToDelete = clients;
+ qDeleteAll(clientsToDelete);
- qDeleteAll(outputs);
+ const auto outputsToDelete = outputs;
+ qDeleteAll(outputsToDelete);
#if QT_CONFIG(wayland_datadevice)
delete data_device_manager;
#endif
-#if QT_CONFIG(opengl)
// Some client buffer integrations need to clean up before the destroying the wl_display
- client_buffer_integration.reset();
-#endif
+ qDeleteAll(client_buffer_integrations);
- wl_display_destroy(display);
+ if (ownsDisplay)
+ wl_display_destroy(display);
}
void QWaylandCompositorPrivate::preInit()
@@ -290,21 +288,19 @@ void QWaylandCompositorPrivate::addPolishObject(QObject *object)
if (initialized) {
QCoreApplication::postEvent(object, new QEvent(QEvent::Polish));
} else {
- polish_objects.append(object);
+ polish_objects.push_back(object);
}
}
-#if WAYLAND_VERSION_MAJOR >= 1 && (WAYLAND_VERSION_MAJOR != 1 || WAYLAND_VERSION_MINOR >= 10)
void QWaylandCompositorPrivate::connectToExternalSockets()
{
// Clear out any backlog of user-supplied external socket descriptors
- for (int fd : qAsConst(externally_added_socket_fds)) {
+ for (int fd : std::as_const(externally_added_socket_fds)) {
if (wl_display_add_socket_fd(display, fd) != 0)
qWarning() << "Failed to integrate user-supplied socket fd into the Wayland event loop";
}
externally_added_socket_fds.clear();
}
-#endif
void QWaylandCompositorPrivate::compositor_create_surface(wl_compositor::Resource *resource, uint32_t id)
{
@@ -353,9 +349,28 @@ QWaylandSurface *QWaylandCompositorPrivate::createDefaultSurface()
return new QWaylandSurface();
}
+class SharedMemoryClientBufferIntegration : public QtWayland::ClientBufferIntegration
+{
+public:
+ void initializeHardware(wl_display *display) override;
+ QtWayland::ClientBuffer *createBufferFor(wl_resource *buffer) override;
+};
+
+void SharedMemoryClientBufferIntegration::initializeHardware(wl_display *)
+{
+}
+
+QtWayland::ClientBuffer *SharedMemoryClientBufferIntegration::createBufferFor(wl_resource *buffer)
+{
+ if (wl_shm_buffer_get(buffer))
+ return new QtWayland::SharedMemoryBuffer(buffer);
+ return nullptr;
+}
void QWaylandCompositorPrivate::initializeHardwareIntegration()
{
+ client_buffer_integrations.prepend(new SharedMemoryClientBufferIntegration); // TODO: clean up the opengl dependency
+
#if QT_CONFIG(opengl)
Q_Q(QWaylandCompositor);
if (use_hw_integration_extension)
@@ -364,16 +379,14 @@ void QWaylandCompositorPrivate::initializeHardwareIntegration()
loadClientBufferIntegration();
loadServerBufferIntegration();
- if (client_buffer_integration)
- client_buffer_integration->initializeHardware(display);
- if (server_buffer_integration)
- server_buffer_integration->initializeHardware(q);
+ for (auto *integration : std::as_const(client_buffer_integrations))
+ integration->initializeHardware(display);
#endif
}
void QWaylandCompositorPrivate::initializeSeats()
{
- for (QWaylandSeat *seat : qAsConst(seats))
+ for (QWaylandSeat *seat : std::as_const(seats))
seat->initialize();
}
@@ -382,33 +395,47 @@ void QWaylandCompositorPrivate::loadClientBufferIntegration()
#if QT_CONFIG(opengl)
Q_Q(QWaylandCompositor);
QStringList keys = QtWayland::ClientBufferIntegrationFactory::keys();
- QString targetKey;
+ QStringList targetKeys;
QByteArray clientBufferIntegration = qgetenv("QT_WAYLAND_HARDWARE_INTEGRATION");
if (clientBufferIntegration.isEmpty())
clientBufferIntegration = qgetenv("QT_WAYLAND_CLIENT_BUFFER_INTEGRATION");
- if (keys.contains(QString::fromLocal8Bit(clientBufferIntegration.constData()))) {
- targetKey = QString::fromLocal8Bit(clientBufferIntegration.constData());
- } else if (keys.contains(QString::fromLatin1("wayland-egl"))) {
- targetKey = QString::fromLatin1("wayland-egl");
- } else if (!keys.isEmpty()) {
- targetKey = keys.first();
+
+ for (auto b : clientBufferIntegration.split(';')) {
+ QString s = QString::fromLocal8Bit(b);
+ if (keys.contains(s))
+ targetKeys.append(s);
}
- if (!targetKey.isEmpty()) {
- client_buffer_integration.reset(QtWayland::ClientBufferIntegrationFactory::create(targetKey, QStringList()));
- if (client_buffer_integration) {
- client_buffer_integration->setCompositor(q);
- if (hw_integration)
- hw_integration->setClientBufferIntegration(targetKey);
+ if (targetKeys.isEmpty()) {
+ if (keys.contains(QString::fromLatin1("wayland-egl"))) {
+ targetKeys.append(QString::fromLatin1("wayland-egl"));
+ } else if (!keys.isEmpty()) {
+ targetKeys.append(keys.first());
}
}
- //BUG: if there is no client buffer integration, bad things will happen when opengl is used
+
+ QString hwIntegrationName;
+
+ for (auto targetKey : std::as_const(targetKeys)) {
+ auto *integration = QtWayland::ClientBufferIntegrationFactory::create(targetKey, QStringList());
+ if (integration) {
+ integration->setCompositor(q);
+ client_buffer_integrations.append(integration);
+ if (hwIntegrationName.isEmpty())
+ hwIntegrationName = targetKey;
+ }
+ }
+
+ if (hw_integration && !hwIntegrationName.isEmpty())
+ hw_integration->setClientBufferIntegrationName(hwIntegrationName);
+
#endif
}
void QWaylandCompositorPrivate::loadServerBufferIntegration()
{
#if QT_CONFIG(opengl)
+ Q_Q(QWaylandCompositor);
QStringList keys = QtWayland::ServerBufferIntegrationFactory::keys();
QString targetKey;
QByteArray serverBufferIntegration = qgetenv("QT_WAYLAND_SERVER_BUFFER_INTEGRATION");
@@ -417,14 +444,41 @@ void QWaylandCompositorPrivate::loadServerBufferIntegration()
}
if (!targetKey.isEmpty()) {
server_buffer_integration.reset(QtWayland::ServerBufferIntegrationFactory::create(targetKey, QStringList()));
- if (hw_integration)
- hw_integration->setServerBufferIntegration(targetKey);
+ if (server_buffer_integration) {
+ qCDebug(qLcWaylandCompositorHardwareIntegration)
+ << "Loaded server buffer integration:" << targetKey;
+ if (!server_buffer_integration->initializeHardware(q)) {
+ qCWarning(qLcWaylandCompositorHardwareIntegration)
+ << "Failed to initialize hardware for server buffer integration:" << targetKey;
+ server_buffer_integration.reset();
+ }
+ } else {
+ qCWarning(qLcWaylandCompositorHardwareIntegration)
+ << "Failed to load server buffer integration:" << targetKey;
+ }
}
+
+ if (server_buffer_integration && hw_integration)
+ hw_integration->setServerBufferIntegrationName(targetKey);
#endif
}
+QWaylandSeat *QWaylandCompositorPrivate::seatFor(QInputEvent *inputEvent)
+{
+ QWaylandSeat *dev = nullptr;
+ for (int i = 0; i < seats.size(); i++) {
+ QWaylandSeat *candidate = seats.at(i);
+ if (candidate->isOwner(inputEvent)) {
+ dev = candidate;
+ break;
+ }
+ }
+ return dev;
+}
+
/*!
\qmltype WaylandCompositor
+ \instantiates QWaylandCompositor
\inqmlmodule QtWayland.Compositor
\since 5.8
\brief Manages the Wayland display server.
@@ -456,35 +510,37 @@ void QWaylandCompositorPrivate::loadServerBufferIntegration()
*/
/*!
- \qmlsignal void QtWaylandCompositor::WaylandCompositor::surfaceRequested(WaylandClient client, int id, int version)
+ \qmlsignal void QtWayland.Compositor::WaylandCompositor::surfaceRequested(WaylandClient client, int id, int version)
+
+ This signal is emitted when a \a client has created a surface with id \a id.
+ The interface \a version is also available.
- This signal is emitted when a client has created a surface.
- The slot connecting to this signal may create and initialize
- a WaylandSurface instance in the scope of the slot.
- Otherwise a default surface is created.
+ The slot connecting to this signal may create and initialize a WaylandSurface
+ instance in the scope of the slot. Otherwise a default surface is created.
*/
/*!
\fn void QWaylandCompositor::surfaceRequested(QWaylandClient *client, uint id, int version)
- This signal is emitted when a client has created a surface.
- The slot connecting to this signal may create and initialize
- a QWaylandSurface instance in the scope of the slot.
- Otherwise a default surface is created.
+ This signal is emitted when a \a client has created a surface with id \a id.
+ The interface \a version is also available.
+
+ The slot connecting to this signal may create and initialize a QWaylandSurface
+ instance in the scope of the slot. Otherwise a default surface is created.
Connections to this signal must be of Qt::DirectConnection connection type.
*/
/*!
- \qmlsignal void QtWaylandCompositor::WaylandCompositor::surfaceCreated(QWaylandSurface *surface)
+ \qmlsignal void QtWayland.Compositor::WaylandCompositor::surfaceCreated(WaylandSurface surface)
- This signal is emitted when a new WaylandSurface instance has been created.
+ This signal is emitted when a new WaylandSurface instance \a surface has been created.
*/
/*!
\fn void QWaylandCompositor::surfaceCreated(QWaylandSurface *surface)
- This signal is emitted when a new QWaylandSurface instance has been created.
+ This signal is emitted when a new QWaylandSurface instance \a surface has been created.
*/
/*!
@@ -523,7 +579,7 @@ void QWaylandCompositor::create()
}
/*!
- * \qmlproperty bool QtWaylandCompositor::WaylandCompositor::created
+ * \qmlproperty bool QtWayland.Compositor::WaylandCompositor::created
*
* This property is true if WaylandCompositor has been initialized,
* otherwise it's false.
@@ -542,7 +598,7 @@ bool QWaylandCompositor::isCreated() const
}
/*!
- * \qmlproperty string QtWaylandCompositor::WaylandCompositor::socketName
+ * \qmlproperty string QtWayland.Compositor::WaylandCompositor::socketName
*
* This property holds the socket name used by WaylandCompositor to communicate with
* clients. It must be set before the component is completed.
@@ -585,10 +641,10 @@ QByteArray QWaylandCompositor::socketName() const
}
/*!
- * \qmlmethod QtWaylandCompositor::WaylandCompositor::addSocketDescriptor(fd)
+ * \qmlmethod QtWayland.Compositor::WaylandCompositor::addSocketDescriptor(fd)
* \since 5.12
*
- * Listen for client connections on a file descriptor referring to a
+ * Listen for client connections on a file descriptor, \a fd, referring to a
* server socket already bound and listening.
*
* Does not take ownership of the file descriptor; it must be closed
@@ -600,7 +656,7 @@ QByteArray QWaylandCompositor::socketName() const
*/
/*!
- * Listen for client connections on a file descriptor referring to a
+ * Listen for client connections on a file descriptor, \a fd, referring to a
* server socket already bound and listening.
*
* Does not take ownership of the file descriptor; it must be closed
@@ -614,15 +670,10 @@ QByteArray QWaylandCompositor::socketName() const
*/
void QWaylandCompositor::addSocketDescriptor(int fd)
{
-#if WAYLAND_VERSION_MAJOR >= 1 && (WAYLAND_VERSION_MAJOR != 1 || WAYLAND_VERSION_MINOR >= 10)
Q_D(QWaylandCompositor);
d->externally_added_socket_fds.append(fd);
if (isCreated())
d->connectToExternalSockets();
-#else
- Q_UNUSED(fd);
- qWarning() << "QWaylandCompositor::addSocketDescriptor() does nothing on libwayland versions prior to 1.10.0";
-#endif
}
/*!
@@ -653,7 +704,7 @@ QList<QWaylandClient *>QWaylandCompositor::clients() const
}
/*!
- * \qmlmethod QtWaylandCompositor::WaylandCompositor::destroyClientForSurface(surface)
+ * \qmlmethod QtWayland.Compositor::WaylandCompositor::destroyClientForSurface(surface)
*
* Destroys the client for the WaylandSurface \a surface.
*/
@@ -667,7 +718,7 @@ void QWaylandCompositor::destroyClientForSurface(QWaylandSurface *surface)
}
/*!
- * \qmlmethod QtWaylandCompositor::WaylandCompositor::destroyClient(client)
+ * \qmlmethod QtWayland.Compositor::WaylandCompositor::destroyClient(client)
*
* Destroys the given WaylandClient \a client.
*/
@@ -694,7 +745,7 @@ QList<QWaylandSurface *> QWaylandCompositor::surfacesForClient(QWaylandClient* c
{
Q_D(const QWaylandCompositor);
QList<QWaylandSurface *> surfs;
- foreach (QWaylandSurface *surface, d->all_surfaces) {
+ for (QWaylandSurface *surface : d->all_surfaces) {
if (surface->client() == client)
surfs.append(surface);
}
@@ -716,7 +767,7 @@ QList<QWaylandSurface *> QWaylandCompositor::surfaces() const
QWaylandOutput *QWaylandCompositor::outputFor(QWindow *window) const
{
Q_D(const QWaylandCompositor);
- foreach (QWaylandOutput *output, d->outputs) {
+ for (QWaylandOutput *output : d->outputs) {
if (output->window() == window)
return output;
}
@@ -725,7 +776,7 @@ QWaylandOutput *QWaylandCompositor::outputFor(QWindow *window) const
}
/*!
- * \qmlproperty WaylandOutput QtWaylandCompositor::WaylandCompositor::defaultOutput
+ * \qmlproperty WaylandOutput QtWayland.Compositor::WaylandCompositor::defaultOutput
*
* This property contains the first in the list of outputs added to the
* WaylandCompositor, or null if no outputs have been added.
@@ -826,7 +877,7 @@ QWaylandTouch *QWaylandCompositor::createTouchDevice(QWaylandSeat *seat)
}
/*!
- * \qmlproperty bool QtWaylandCompositor::WaylandCompositor::retainedSelection
+ * \qmlproperty bool QtWayland.Compositor::WaylandCompositor::retainedSelection
*
* This property holds whether retained selection is enabled.
*/
@@ -872,7 +923,7 @@ void QWaylandCompositor::overrideSelection(const QMimeData *data)
}
/*!
- * \qmlproperty WaylandSeat QtWaylandCompositor::WaylandCompositor::defaultSeat
+ * \qmlproperty WaylandSeat QtWayland.Compositor::WaylandCompositor::defaultSeat
*
* This property contains the default seat for this
* WaylandCompositor.
@@ -893,27 +944,17 @@ QWaylandSeat *QWaylandCompositor::defaultSeat() const
}
/*!
- * \internal
- *
- * Currently, Qt only supports a single seat, so this exists for
- * future proofing the APIs.
+ * Select the seat for a given input event \a inputEvent.
+ * Currently, Qt only supports a single seat.
*/
QWaylandSeat *QWaylandCompositor::seatFor(QInputEvent *inputEvent)
{
Q_D(QWaylandCompositor);
- QWaylandSeat *dev = nullptr;
- for (int i = 0; i < d->seats.size(); i++) {
- QWaylandSeat *candidate = d->seats.at(i);
- if (candidate->isOwner(inputEvent)) {
- dev = candidate;
- break;
- }
- }
- return dev;
+ return d->seatFor(inputEvent);
}
/*!
- * \qmlproperty bool QtWaylandCompositor::WaylandCompositor::useHardwareIntegrationExtension
+ * \qmlproperty bool QtWayland.Compositor::WaylandCompositor::useHardwareIntegrationExtension
*
* This property holds whether the hardware integration extension should be enabled for
* this WaylandCompositor.
@@ -998,4 +1039,67 @@ void QWaylandCompositor::grabSurface(QWaylandSurfaceGrabber *grabber, const QWay
}
}
+/*!
+ * \qmlproperty list<enum> QtWayland.Compositor::WaylandCompositor::additionalShmFormats
+ *
+ * This property holds the list of additional wl_shm formats advertised as supported by the
+ * compositor.
+ *
+ * By default, only the required ShmFormat_ARGB8888 and ShmFormat_XRGB8888 are listed and this
+ * list will empty. Additional formats may require conversion internally and can thus affect
+ * performance.
+ *
+ * This property must be set before the compositor component is completed. Subsequent changes
+ * will have no effect.
+ *
+ * \since 6.0
+ */
+
+/*!
+ * \property QWaylandCompositor::additionalShmFormats
+ *
+ * This property holds the list of additional wl_shm formats advertised as supported by the
+ * compositor.
+ *
+ * By default, only the required ShmFormat_ARGB8888 and ShmFormat_XRGB8888 are listed and this
+ * list will empty.
+ *
+ * This property must be set before the compositor is \l{create()}{created}. Subsequent changes
+ * will have no effect.
+ *
+ * \since 6.0
+ */
+void QWaylandCompositor::setAdditionalShmFormats(const QVector<ShmFormat> &additionalShmFormats)
+{
+ Q_D(QWaylandCompositor);
+ if (d->initialized)
+ qCWarning(qLcWaylandCompositorHardwareIntegration) << "Setting QWaylandCompositor::additionalShmFormats after initialization has no effect";
+
+ d->shmFormats = additionalShmFormats;
+ emit additionalShmFormatsChanged();
+}
+
+QVector<QWaylandCompositor::ShmFormat> QWaylandCompositor::additionalShmFormats() const
+{
+ Q_D(const QWaylandCompositor);
+ return d->shmFormats;
+}
+
+void QWaylandCompositor::applicationStateChanged(Qt::ApplicationState state)
+{
+#if QT_CONFIG(xkbcommon)
+ if (state == Qt::ApplicationInactive) {
+ auto *seat = defaultSeat();
+ if (seat != nullptr) {
+ QWaylandKeyboardPrivate *keyb = QWaylandKeyboardPrivate::get(seat->keyboard());
+ keyb->resetKeyboardState();
+ }
+ }
+#else
+ Q_UNUSED(state);
+#endif
+}
+
QT_END_NAMESPACE
+
+#include "moc_qwaylandcompositor.cpp"