9#include <QtWaylandCompositor/qwaylandclient.h>
10#include <QtWaylandCompositor/qwaylandseat.h>
11#include <QtWaylandCompositor/qwaylandoutput.h>
12#include <QtWaylandCompositor/qwaylandview.h>
13#include <QtWaylandCompositor/qwaylandclient.h>
14#include <QtWaylandCompositor/qwaylandkeyboard.h>
15#include <QtWaylandCompositor/qwaylandpointer.h>
16#include <QtWaylandCompositor/qwaylandtouch.h>
17#include <QtWaylandCompositor/qwaylandsurfacegrabber.h>
19#include <QtWaylandCompositor/private/qwaylandkeyboard_p.h>
20#include <QtWaylandCompositor/private/qwaylandsurface_p.h>
22#if QT_CONFIG(wayland_datadevice)
41#include <QtCore/QCoreApplication>
42#include <QtCore/QStringList>
43#include <QtCore/QSocketNotifier>
44#include <QStandardPaths>
46#include <QtGui/QDesktopServices>
47#include <QtGui/QScreen>
49#include <QtGui/qpa/qwindowsysteminterface_p.h>
50#include <QtGui/qpa/qplatformnativeinterface.h>
51#include <QtGui/private/qguiapplication_p.h>
54# include <QOpenGLTextureBlitter>
55# include <QOpenGLTexture>
56# include <QOpenGLContext>
57# include <QOpenGLFramebufferObject>
64Q_LOGGING_CATEGORY(qLcWaylandCompositorHardwareIntegration, "qt.waylandcompositor.hardwareintegration")
65Q_LOGGING_CATEGORY(qLcWaylandCompositorInputMethods, "qt.waylandcompositor.inputmethods")
78 handleKeyEvent(keyEvent);
100 ke->nativeScanCode +=
offset;
102 uint32_t code = ke->nativeScanCode;
104 code = seat->keyboard()->keyToScanCode(ke->key);
107#if QT_CONFIG(xkbcommon)
108 xkb_state *xkbState = keyb->xkbState();
110 const xkb_keysym_t sym = xkb_state_key_get_one_sym(xkbState, code);
117 ke->nativeVirtualKey = sym;
118 ke->nativeModifiers = keyb->xkbModsMask();
122 keyb->keyEvent(code, isDown ? WL_KEYBOARD_KEY_STATE_PRESSED : WL_KEYBOARD_KEY_STATE_RELEASED);
127 keyb->maybeUpdateKeymap();
128 keyb->updateModifierState(code, isDown ? WL_KEYBOARD_KEY_STATE_PRESSED : WL_KEYBOARD_KEY_STATE_RELEASED);
155#if QT_CONFIG(xkbcommon)
156 mXkbContext.reset(xkb_context_new(XKB_CONTEXT_NO_FLAGS));
158 qWarning(
"Failed to create a XKB context: keymap will not be supported");
176 wl_compositor::init(
display, 4);
177 wl_subcompositor::init(
display, 1);
179#if QT_CONFIG(wayland_datadevice)
191 qFatal(
"Fatal: Failed to open server socket: \"%s\". XDG_RUNTIME_DIR is: \"%s\"\n",
socket_name.
constData(), getenv(
"XDG_RUNTIME_DIR"));
193 const char *autoSocketName = wl_display_add_socket_auto(
display);
195 qFatal(
"Fatal: Failed to open default server socket. XDG_RUNTIME_DIR is: \"%s\"\n", getenv(
"XDG_RUNTIME_DIR"));
204 int fd = wl_event_loop_get_fd(
loop);
215 &QWaylandCompositor::applicationStateChanged);
222 for (
const QPointer<QObject> &
object : std::exchange(
polish_objects, {})) {
229 emit q->createdChanged();
235 const auto clientsToDelete =
clients;
238 const auto outputsToDelete =
outputs;
241#if QT_CONFIG(wayland_datadevice)
242 delete data_device_manager;
268 q->surfaceAboutToBeDestroyed(surface);
283 q->retainedSelectionReceived(
data);
299 if (wl_display_add_socket_fd(
display,
fd) != 0)
300 qWarning() <<
"Failed to integrate user-supplied socket fd into the Wayland event loop";
309 emit q->surfaceRequested(client,
id, resource->version());
313 struct wl_resource *surfResource = wl_client_get_object(client->
client(),
id);
320 surface->
initialize(
q, client,
id, resource->version());
324 emit q->surfaceCreated(surface);
339 emit q->subsurfaceChanged(childSurface, parentSurface);
365 if (wl_shm_buffer_get(
buffer))
376 if (use_hw_integration_extension)
383 integration->initializeHardware(
display);
400 if (clientBufferIntegration.
isEmpty())
401 clientBufferIntegration =
qgetenv(
"QT_WAYLAND_CLIENT_BUFFER_INTEGRATION");
403 for (
auto b : clientBufferIntegration.
split(
';')) {
405 if (
keys.contains(
s))
406 targetKeys.append(
s);
409 if (targetKeys.isEmpty()) {
412 }
else if (!
keys.isEmpty()) {
413 targetKeys.append(
keys.first());
419 for (
auto targetKey : std::as_const(targetKeys)) {
422 integration->setCompositor(
q);
424 if (hwIntegrationName.isEmpty())
425 hwIntegrationName = targetKey;
429 if (hw_integration && !hwIntegrationName.isEmpty())
430 hw_integration->setClientBufferIntegrationName(hwIntegrationName);
445 if (!targetKey.isEmpty()) {
447 if (server_buffer_integration) {
448 qCDebug(qLcWaylandCompositorHardwareIntegration)
449 <<
"Loaded server buffer integration:" << targetKey;
450 if (!server_buffer_integration->initializeHardware(
q)) {
451 qCWarning(qLcWaylandCompositorHardwareIntegration)
452 <<
"Failed to initialize hardware for server buffer integration:" << targetKey;
453 server_buffer_integration.reset();
456 qCWarning(qLcWaylandCompositorHardwareIntegration)
457 <<
"Failed to load server buffer integration:" << targetKey;
461 if (server_buffer_integration && hw_integration)
462 hw_integration->setServerBufferIntegrationName(targetKey);
471 if (candidate->
isOwner(inputEvent)) {
549QWaylandCompositor::QWaylandCompositor(
QObject *parent)
566QWaylandCompositor::~QWaylandCompositor()
574void QWaylandCompositor::create()
594bool QWaylandCompositor::isCreated()
const
597 return d->initialized;
625 if (
d->socket_name ==
name)
628 if (
d->initialized) {
629 qWarning(
"%s: Changing socket name after initializing the compositor is not supported.\n",
Q_FUNC_INFO);
633 d->socket_name =
name;
637QByteArray QWaylandCompositor::socketName()
const
640 return d->socket_name;
671void QWaylandCompositor::addSocketDescriptor(
int fd)
674 d->externally_added_socket_fds.append(
fd);
676 d->connectToExternalSockets();
682struct wl_display *QWaylandCompositor::display()
const
691uint32_t QWaylandCompositor::nextSerial()
694 return wl_display_next_serial(
d->display);
700QList<QWaylandClient *>QWaylandCompositor::clients()
const
715void QWaylandCompositor::destroyClientForSurface(
QWaylandSurface *surface)
717 destroyClient(surface->
client());
736 wmExtension->sendQuitMessage(client);
738 wl_client_destroy(client->
client());
744QList<QWaylandSurface *> QWaylandCompositor::surfacesForClient(
QWaylandClient* client)
const
747 QList<QWaylandSurface *> surfs;
749 if (surface->client() == client)
750 surfs.append(surface);
758QList<QWaylandSurface *> QWaylandCompositor::surfaces()
const
761 return d->all_surfaces;
802 return d->defaultOutput();
808 if (
d->outputs.size() &&
d->outputs.first() ==
output)
810 bool alreadyAdded =
d->outputs.removeOne(
output);
812 emit defaultOutputChanged();
820QList<QWaylandOutput *> QWaylandCompositor::outputs()
const
829uint QWaylandCompositor::currentTimeMsecs()
const
832 return d->timer.elapsed();
838void QWaylandCompositor::processWaylandEvents()
841 int ret = wl_event_loop_dispatch(
d->loop, 0);
843 fprintf(stderr,
"wl_event_loop_dispatch error: %d\n",
ret);
844 wl_display_flush_clients(
d->display);
890void QWaylandCompositor::setRetainedSelectionEnabled(
bool enabled)
901bool QWaylandCompositor::retainedSelectionEnabled()
const
904 return d->retainSelection;
910void QWaylandCompositor::retainedSelectionReceived(
QMimeData *)
917void QWaylandCompositor::overrideSelection(
const QMimeData *
data)
920#if QT_CONFIG(wayland_datadevice)
921 d->data_device_manager->overrideSelection(*
data);
942 return d->seats.first();
953 return d->seatFor(inputEvent);
973bool QWaylandCompositor::useHardwareIntegrationExtension()
const
977 return d->use_hw_integration_extension;
983void QWaylandCompositor::setUseHardwareIntegrationExtension(
bool use)
987 if (use ==
d->use_hw_integration_extension)
991 qWarning(
"Setting QWaylandCompositor::useHardwareIntegrationExtension after initialization has no effect");
993 d->use_hw_integration_extension = use;
994 useHardwareIntegrationExtensionChanged();
997 qWarning() <<
"Hardware integration not supported without OpenGL support";
1012 if (
buffer.isSharedMemory()) {
1015#if QT_CONFIG(opengl)
1023 glViewport(0, 0,
buffer.size().width(),
buffer.size().height());
1035 emit grabber->success(fbo.toImage());
1072void QWaylandCompositor::setAdditionalShmFormats(
const QVector<ShmFormat> &additionalShmFormats)
1076 qCWarning(qLcWaylandCompositorHardwareIntegration) <<
"Setting QWaylandCompositor::additionalShmFormats after initialization has no effect";
1078 d->shmFormats = additionalShmFormats;
1079 emit additionalShmFormatsChanged();
1082QVector<QWaylandCompositor::ShmFormat> QWaylandCompositor::additionalShmFormats()
const
1085 return d->shmFormats;
1090#if QT_CONFIG(xkbcommon)
1092 auto *seat = defaultSeat();
1093 if (seat !=
nullptr) {
1095 keyb->resetKeyboardState();
1105#include "moc_qwaylandcompositor.cpp"
const char * constData() const noexcept
Returns a pointer to the const data stored in the byte array.
QList< QByteArray > split(char sep) const
Splits the byte array into subarrays wherever sep occurs, and returns the list of those arrays.
bool isEmpty() const noexcept
Returns true if the byte array has size 0; otherwise returns false.
static QAbstractEventDispatcher * eventDispatcher
static bool sendEvent(QObject *receiver, QEvent *event)
Sends event event directly to receiver receiver, using the notify() function.
static QCoreApplication * instance() noexcept
Returns a pointer to the application's QCoreApplication (or QGuiApplication/QApplication) instance.
static void postEvent(QObject *receiver, QEvent *event, int priority=Qt::NormalEventPriority)
void start() noexcept
\typealias QElapsedTimer::Duration Synonym for std::chrono::nanoseconds.
static QPlatformNativeInterface * platformNativeInterface()
void applicationStateChanged(Qt::ApplicationState state)
QString platformName
The name of the underlying platform plugin.
qsizetype size() const noexcept
bool empty() const noexcept
bool removeOne(const AT &t)
const_reference at(qsizetype i) const noexcept
void prepend(rvalue_ref t)
void append(parameter_type t)
The QMatrix4x4 class represents a 4x4 transformation matrix in 3D space.
static QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *member, Qt::ConnectionType=Qt::AutoConnection)
\threadsafe
static QOpenGLContext * currentContext()
Returns the last context which called makeCurrent in the current thread, or \nullptr,...
The QOpenGLFramebufferObject class encapsulates an OpenGL framebuffer object.
The QOpenGLTextureBlitter class provides a convenient way to draw textured quads via OpenGL.
bool create()
Initializes the graphics resources used by the blitter.
Origin
\value OriginBottomLeft Indicates that the data in the texture follows the OpenGL convention of coord...
void blit(GLuint texture, const QMatrix4x4 &targetTransform, Origin sourceOrigin)
Performs the blit with the source texture texture.
void release()
Unbinds the graphics resources used by the blitter.
void bind(GLenum target=GL_TEXTURE_2D)
Binds the graphics resources used by the blitter.
T * data() const noexcept
Returns the value of the pointer referenced by this object.
void reset(T *other=nullptr) noexcept(noexcept(Cleanup::cleanup(std::declval< T * >())))
Deletes the existing object it is pointing to (if any), and sets its pointer to other.
static QString writableLocation(StandardLocation type)
\macro QT_RESTRICTED_CAST_FROM_ASCII
static QString fromLatin1(QByteArrayView ba)
This is an overloaded member function, provided for convenience. It differs from the above function o...
static QString fromLocal8Bit(QByteArrayView ba)
This is an overloaded member function, provided for convenience. It differs from the above function o...
\inmodule QtWaylandCompositor
\qmltype WaylandClient \instantiates QWaylandClient \inqmlmodule QtWayland.Compositor
static QWaylandClient * fromWlClient(QWaylandCompositor *compositor, wl_client *wlClient)
Returns the QWaylandClient corresponding to the Wayland client wlClient and compositor.
wl_client * client() const
Returns the Wayland client of this QWaylandClient.
static QWaylandQtWindowManager * findIn(QWaylandObject *container)
If any instance of the interface has been registered with container, this is returned.
QList< QWaylandOutput * > outputs
~QWaylandCompositorPrivate() override
void initializeHardwareIntegration()
QList< QWaylandSeat * > seats
void subcompositor_get_subsurface(wl_subcompositor::Resource *resource, uint32_t id, struct ::wl_resource *surface, struct ::wl_resource *parent) override
void addPolishObject(QObject *object)
virtual QWaylandSeat * seatFor(QInputEvent *inputEvent)
void compositor_create_surface(wl_compositor::Resource *resource, uint32_t id) override
QList< QWaylandClient * > clients
QList< QtWayland::ClientBufferIntegration * > client_buffer_integrations
void feedRetainedSelectionData(QMimeData *data)
QtWayland::ServerBufferIntegration * serverBufferIntegration() const
QList< int > externally_added_socket_fds
void destroySurface(QWaylandSurface *surface)
void connectToExternalSockets()
QWaylandCompositorPrivate(QWaylandCompositor *compositor)
std::vector< QPointer< QObject > > polish_objects
void unregisterSurface(QWaylandSurface *surface)
QtWayland::BufferManager * buffer_manager
QList< QWaylandSurface * > all_surfaces
QVector< QWaylandCompositor::ShmFormat > shmFormats
void loadClientBufferIntegration()
void loadServerBufferIntegration()
QScopedPointer< QWindowSystemEventHandler > eventHandler
virtual QWaylandSurface * createDefaultSurface()
void compositor_create_region(wl_compositor::Resource *resource, uint32_t id) override
\qmltype WaylandCompositor \instantiates QWaylandCompositor \inqmlmodule QtWayland....
static QWaylandKeyboardPrivate * get(QWaylandKeyboard *keyboard)
\inmodule QtWaylandCompositor
\inmodule QtWaylandCompositor
\qmltype WaylandOutput \instantiates QWaylandOutput \inqmlmodule QtWayland.Compositor
\inmodule QtWaylandCompositor
\qmltype WaylandSeat \instantiates QWaylandSeat \inqmlmodule QtWayland.Compositor
virtual bool isOwner(QInputEvent *inputEvent) const
\inmodule QtWaylandCompositor
static bool hasUninitializedSurface()
static QWaylandSurfacePrivate * get(QWaylandSurface *surface)
\qmltype WaylandSurface \instantiates QWaylandSurface \inqmlmodule QtWayland.Compositor
static QWaylandSurface * fromResource(::wl_resource *resource)
Returns the QWaylandSurface corresponding to the Wayland resource resource.
QWaylandClient * client
\qmlproperty WaylandClient QtWayland.Compositor::WaylandSurface::client
Q_INVOKABLE void initialize(QWaylandCompositor *compositor, QWaylandClient *client, uint id, int version)
\qmlmethod void QtWayland.Compositor::WaylandSurface::initialize(WaylandCompositor compositor,...
\inmodule QtWaylandCompositor
virtual bool sendEvent(QWindowSystemInterfacePrivate::WindowSystemEvent *event)
static void installWindowSystemEventHandler(QWindowSystemEventHandler *handler)
static QString lookupString(struct xkb_state *state, xkb_keycode_t code)
static Qt::KeyboardModifiers modifiers(struct xkb_state *state, xkb_keysym_t keysym=XKB_KEY_VoidSymbol)
static int keysymToQtKey(xkb_keysym_t keysym, Qt::KeyboardModifiers modifiers)
static QStringList keys()
static ClientBufferIntegration * create(const QString &name, const QStringList &args)
static QStringList keys()
static ServerBufferIntegration * create(const QString &name, const QStringList &args)
void handleKeyEvent(QWindowSystemInterfacePrivate::KeyEvent *ke)
bool sendEvent(QWindowSystemInterfacePrivate::WindowSystemEvent *e) override
WindowSystemEventHandler(QWaylandCompositor *c)
QtWayland::ClientBuffer * createBufferFor(wl_resource *buffer) override
void initializeHardware(wl_display *display) override
EGLImageKHR int int EGLuint64KHR * modifiers
qDeleteAll(list.begin(), list.end())
QList< QVariant > arguments
struct wl_display * display
Combined button and popup list for selecting options.
QList< QString > QStringList
Constructs a string list that contains the given string, str.
#define Q_LOGGING_CATEGORY(name,...)
#define qCWarning(category,...)
#define qCDebug(category,...)
static QOpenGLCompositor * compositor
GLboolean GLboolean GLboolean b
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLenum GLenum GLsizei const GLuint GLboolean enabled
GLenum GLuint GLintptr offset
GLint GLsizei GLsizei GLenum format
GLdouble GLdouble GLdouble GLdouble q
#define Q_ASSERT_X(cond, x, msg)
static char * toLocal8Bit(char *out, QStringView in, QStringConverter::State *state)
QLatin1StringView QLatin1String
#define QStringLiteral(str)
Q_CORE_EXPORT QByteArray qgetenv(const char *varName)
QT_BEGIN_NAMESPACE typedef uchar * output
qsizetype indexOf(const AT &t, qsizetype from=0) const noexcept