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>
45#include <QtGui/QDesktopServices>
46#include <QtGui/QScreen>
48#include <QtGui/qpa/qwindowsysteminterface_p.h>
49#include <QtGui/qpa/qplatformnativeinterface.h>
50#include <QtGui/private/qguiapplication_p.h>
53# include <QOpenGLTextureBlitter>
54# include <QOpenGLTexture>
55# include <QOpenGLContext>
56# include <QOpenGLFramebufferObject>
63Q_LOGGING_CATEGORY(qLcWaylandCompositorHardwareIntegration, "qt.waylandcompositor.hardwareintegration")
64Q_LOGGING_CATEGORY(qLcWaylandCompositorInputMethods, "qt.waylandcompositor.inputmethods")
65#if QT_WAYLAND_TEXT_INPUT_V4_WIP
105 code = seat->keyboard()->keyToScanCode(ke->
key);
108#if QT_CONFIG(xkbcommon)
109 xkb_state *xkbState = keyb->xkbState();
111 const xkb_keysym_t sym = xkb_state_key_get_one_sym(xkbState, code);
123 keyb->
keyEvent(code, isDown ? WL_KEYBOARD_KEY_STATE_PRESSED : WL_KEYBOARD_KEY_STATE_RELEASED);
129 keyb->
updateModifierState(code, isDown ? WL_KEYBOARD_KEY_STATE_PRESSED : WL_KEYBOARD_KEY_STATE_RELEASED);
153#if QT_CONFIG(xkbcommon)
154 mXkbContext.reset(xkb_context_new(XKB_CONTEXT_NO_FLAGS));
156 qWarning(
"Failed to create a XKB context: keymap will not be supported");
172 wl_compositor::init(
display, 4);
173 wl_subcompositor::init(
display, 1);
175#if QT_CONFIG(wayland_datadevice)
187 qFatal(
"Fatal: Failed to open server socket: \"%s\". XDG_RUNTIME_DIR is: \"%s\"\n",
socket_name.
constData(), getenv(
"XDG_RUNTIME_DIR"));
189 const char *autoSocketName = wl_display_add_socket_auto(
display);
191 qFatal(
"Fatal: Failed to open default server socket. XDG_RUNTIME_DIR is: \"%s\"\n", getenv(
"XDG_RUNTIME_DIR"));
200 int fd = wl_event_loop_get_fd(
loop);
211 &QWaylandCompositor::applicationStateChanged);
225 emit q->createdChanged();
231 const auto clientsToDelete =
clients;
234 const auto outputsToDelete =
outputs;
237#if QT_CONFIG(wayland_datadevice)
238 delete data_device_manager;
264 q->surfaceAboutToBeDestroyed(surface);
279 q->retainedSelectionReceived(
data);
295 if (wl_display_add_socket_fd(
display,
fd) != 0)
296 qWarning() <<
"Failed to integrate user-supplied socket fd into the Wayland event loop";
305 emit q->surfaceRequested(client,
id, resource->version());
309 struct wl_resource *surfResource = wl_client_get_object(client->
client(),
id);
316 surface->
initialize(
q, client,
id, resource->version());
320 emit q->surfaceCreated(surface);
335 emit q->subsurfaceChanged(childSurface, parentSurface);
361 if (wl_shm_buffer_get(
buffer))
372 if (use_hw_integration_extension)
379 integration->initializeHardware(
display);
396 if (clientBufferIntegration.
isEmpty())
397 clientBufferIntegration =
qgetenv(
"QT_WAYLAND_CLIENT_BUFFER_INTEGRATION");
399 for (
auto b : clientBufferIntegration.
split(
';')) {
401 if (
keys.contains(
s))
402 targetKeys.append(
s);
405 if (targetKeys.isEmpty()) {
408 }
else if (!
keys.isEmpty()) {
409 targetKeys.append(
keys.first());
415 for (
auto targetKey : std::as_const(targetKeys)) {
418 integration->setCompositor(
q);
420 if (hwIntegrationName.
isEmpty())
421 hwIntegrationName = targetKey;
425 if (hw_integration && !hwIntegrationName.
isEmpty())
426 hw_integration->setClientBufferIntegrationName(hwIntegrationName);
443 if (server_buffer_integration) {
444 qCDebug(qLcWaylandCompositorHardwareIntegration)
445 <<
"Loaded server buffer integration:" << targetKey;
446 if (!server_buffer_integration->initializeHardware(
q)) {
447 qCWarning(qLcWaylandCompositorHardwareIntegration)
448 <<
"Failed to initialize hardware for server buffer integration:" << targetKey;
449 server_buffer_integration.reset();
452 qCWarning(qLcWaylandCompositorHardwareIntegration)
453 <<
"Failed to load server buffer integration:" << targetKey;
457 if (server_buffer_integration && hw_integration)
458 hw_integration->setServerBufferIntegrationName(targetKey);
467 if (candidate->
isOwner(inputEvent)) {
562QWaylandCompositor::~QWaylandCompositor()
570void QWaylandCompositor::create()
590bool QWaylandCompositor::isCreated()
const
593 return d->initialized;
621 if (
d->socket_name ==
name)
624 if (
d->initialized) {
625 qWarning(
"%s: Changing socket name after initializing the compositor is not supported.\n",
Q_FUNC_INFO);
629 d->socket_name =
name;
633QByteArray QWaylandCompositor::socketName()
const
636 return d->socket_name;
667void QWaylandCompositor::addSocketDescriptor(
int fd)
670 d->externally_added_socket_fds.append(
fd);
672 d->connectToExternalSockets();
678struct wl_display *QWaylandCompositor::display()
const
687uint32_t QWaylandCompositor::nextSerial()
690 return wl_display_next_serial(
d->display);
711void QWaylandCompositor::destroyClientForSurface(
QWaylandSurface *surface)
713 destroyClient(surface->
client());
734 wl_client_destroy(client->
client());
745 if (surface->client() == client)
757 return d->all_surfaces;
798 return d->defaultOutput();
804 if (
d->outputs.size() &&
d->outputs.first() ==
output)
806 bool alreadyAdded =
d->outputs.removeOne(
output);
808 emit defaultOutputChanged();
825uint QWaylandCompositor::currentTimeMsecs()
const
828 return d->timer.elapsed();
834void QWaylandCompositor::processWaylandEvents()
837 int ret = wl_event_loop_dispatch(
d->loop, 0);
839 fprintf(stderr,
"wl_event_loop_dispatch error: %d\n",
ret);
840 wl_display_flush_clients(
d->display);
886void QWaylandCompositor::setRetainedSelectionEnabled(
bool enabled)
897bool QWaylandCompositor::retainedSelectionEnabled()
const
900 return d->retainSelection;
906void QWaylandCompositor::retainedSelectionReceived(
QMimeData *)
913void QWaylandCompositor::overrideSelection(
const QMimeData *
data)
916#if QT_CONFIG(wayland_datadevice)
917 d->data_device_manager->overrideSelection(*
data);
938 return d->seats.first();
949 return d->seatFor(inputEvent);
969bool QWaylandCompositor::useHardwareIntegrationExtension()
const
973 return d->use_hw_integration_extension;
979void QWaylandCompositor::setUseHardwareIntegrationExtension(
bool use)
983 if (use ==
d->use_hw_integration_extension)
987 qWarning(
"Setting QWaylandCompositor::useHardwareIntegrationExtension after initialization has no effect");
989 d->use_hw_integration_extension = use;
990 useHardwareIntegrationExtensionChanged();
993 qWarning() <<
"Hardware integration not supported without OpenGL support";
1008 if (
buffer.isSharedMemory()) {
1011#if QT_CONFIG(opengl)
1019 glViewport(0, 0,
buffer.size().width(),
buffer.size().height());
1068void QWaylandCompositor::setAdditionalShmFormats(
const QVector<ShmFormat> &additionalShmFormats)
1072 qCWarning(qLcWaylandCompositorHardwareIntegration) <<
"Setting QWaylandCompositor::additionalShmFormats after initialization has no effect";
1074 d->shmFormats = additionalShmFormats;
1075 emit additionalShmFormatsChanged();
1081 return d->shmFormats;
1086#if QT_CONFIG(xkbcommon)
1088 auto *seat = defaultSeat();
1089 if (seat !=
nullptr) {
1091 keyb->resetKeyboardState();
1101#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)
static QStringList arguments()
void start() noexcept
Starts this timer.
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.
\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...
bool isEmpty() const
Returns true if the string has no characters; otherwise returns false.
\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....
void updateModifierState(uint code, uint32_t state)
void keyEvent(uint code, uint32_t state)
static QWaylandKeyboardPrivate * get(QWaylandKeyboard *keyboard)
\inmodule QtWaylandCompositor
\inmodule QtWaylandCompositor
\qmltype WaylandOutput \instantiates QWaylandOutput \inqmlmodule QtWayland.Compositor
\inmodule QtWaylandCompositor
void sendQuitMessage(QWaylandClient *client)
\qmltype WaylandSeat \instantiates QWaylandSeat \inqmlmodule QtWayland.Compositor
virtual bool isOwner(QInputEvent *inputEvent) const
\inmodule QtWaylandCompositor
void success(const QImage &image)
static bool hasUninitializedSurface()
static QWaylandSurfacePrivate * get(QWaylandSurface *surface)
QList< QPointer< QWaylandSurface > > subsurfaceChildren
void initSubsurface(QWaylandSurface *parent, struct ::wl_client *client, int id, int version)
\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)
QWaylandCompositor * compositor
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.
#define Q_LOGGING_CATEGORY(name,...)
#define qCWarning(category,...)
#define qCDebug(category,...)
static QOpenGLCompositor * compositor
GLboolean GLboolean GLboolean b
GLenum GLenum GLsizei const GLuint GLboolean enabled
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
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
IUIAutomationTreeWalker __RPC__deref_out_opt IUIAutomationElement ** parent