diff options
Diffstat (limited to 'src/compositor')
69 files changed, 1191 insertions, 629 deletions
diff --git a/src/compositor/compositor.pro b/src/compositor/compositor.pro index fe58df7ec..251d757e2 100644 --- a/src/compositor/compositor.pro +++ b/src/compositor/compositor.pro @@ -5,7 +5,7 @@ QT = core gui-private qtHaveModule(quick): QT += quick -contains(QT_CONFIG, opengl):MODULE_DEFINES = QT_COMPOSITOR_WAYLAND_GL +contains(QT_CONFIG, opengl):MODULE_DEFINES = QT_WAYLAND_COMPOSITOR_GL CONFIG -= precompile_header CONFIG += link_pkgconfig @@ -23,7 +23,7 @@ INCLUDEPATH += ../shared HEADERS += ../shared/qwaylandmimehelper_p.h \ ../shared/qwaylandinputmethodeventbuilder_p.h \ - ../shared/qwaylandshmformathelper_p.h + ../shared/qwaylandsharedmemoryformathelper_p.h SOURCES += ../shared/qwaylandmimehelper.cpp \ ../shared/qwaylandinputmethodeventbuilder.cpp diff --git a/src/compositor/compositor_api/compositor_api.pri b/src/compositor/compositor_api/compositor_api.pri index 1724ec965..e803d14c0 100644 --- a/src/compositor/compositor_api/compositor_api.pri +++ b/src/compositor/compositor_api/compositor_api.pri @@ -6,8 +6,8 @@ HEADERS += \ compositor_api/qwaylandclient.h \ compositor_api/qwaylandsurface.h \ compositor_api/qwaylandsurface_p.h \ - compositor_api/qwaylandinput.h \ - compositor_api/qwaylandinput_p.h \ + compositor_api/qwaylandseat.h \ + compositor_api/qwaylandseat_p.h \ compositor_api/qwaylandkeyboard.h \ compositor_api/qwaylandkeyboard_p.h \ compositor_api/qwaylandpointer.h \ @@ -30,7 +30,7 @@ SOURCES += \ compositor_api/qwaylandcompositor.cpp \ compositor_api/qwaylandclient.cpp \ compositor_api/qwaylandsurface.cpp \ - compositor_api/qwaylandinput.cpp \ + compositor_api/qwaylandseat.cpp \ compositor_api/qwaylandkeyboard.cpp \ compositor_api/qwaylandpointer.cpp \ compositor_api/qwaylandtouch.cpp \ @@ -45,7 +45,9 @@ SOURCES += \ QT += core-private -qtHaveModule(quick) { +qtHaveModule(quick):contains(QT_CONFIG, opengl) { + DEFINES += QT_WAYLAND_COMPOSITOR_QUICK + SOURCES += \ compositor_api/qwaylandquickcompositor.cpp \ compositor_api/qwaylandquicksurface.cpp \ diff --git a/src/compositor/compositor_api/qwaylandbufferref.cpp b/src/compositor/compositor_api/qwaylandbufferref.cpp index 624deaff9..7cc17fcbe 100644 --- a/src/compositor/compositor_api/qwaylandbufferref.cpp +++ b/src/compositor/compositor_api/qwaylandbufferref.cpp @@ -205,8 +205,8 @@ QWaylandBufferRef::BufferType QWaylandBufferRef::bufferType() const if (d->nullOrDestroyed()) return BufferType_Null; - if (isShm()) - return BufferType_Shm; + if (isSharedMemory()) + return BufferType_SharedMemory; return BufferType_Egl; } @@ -222,12 +222,12 @@ QWaylandBufferRef::BufferFormatEgl QWaylandBufferRef::bufferFormatEgl() const /*! * Returns true if the buffer is a shared memory buffer. Otherwise returns false. */ -bool QWaylandBufferRef::isShm() const +bool QWaylandBufferRef::isSharedMemory() const { if (d->nullOrDestroyed()) return false; - return d->buffer->isShm(); + return d->buffer->isSharedMemory(); } /*! @@ -241,7 +241,7 @@ QImage QWaylandBufferRef::image() const return d->buffer->image(); } -#ifdef QT_COMPOSITOR_WAYLAND_GL +#ifdef QT_WAYLAND_COMPOSITOR_GL GLuint QWaylandBufferRef::textureForPlane(int plane) const { if (d->nullOrDestroyed()) @@ -249,7 +249,6 @@ GLuint QWaylandBufferRef::textureForPlane(int plane) const return d->buffer->textureForPlane(plane); } -#endif /*! * Binds the buffer to the current OpenGL texture. This may @@ -267,10 +266,11 @@ void QWaylandBufferRef::bindToTexture() const void QWaylandBufferRef::updateTexture() const { - if (d->nullOrDestroyed() || d->buffer->isShm()) + if (d->nullOrDestroyed() || d->buffer->isSharedMemory()) return; d->buffer->updateTexture(); } +#endif QT_END_NAMESPACE diff --git a/src/compositor/compositor_api/qwaylandbufferref.h b/src/compositor/compositor_api/qwaylandbufferref.h index 50c85b965..77f817aba 100644 --- a/src/compositor/compositor_api/qwaylandbufferref.h +++ b/src/compositor/compositor_api/qwaylandbufferref.h @@ -39,7 +39,7 @@ #include <QImage> -#ifdef QT_COMPOSITOR_WAYLAND_GL +#ifdef QT_WAYLAND_COMPOSITOR_GL #include <QtGui/qopengl.h> #endif @@ -77,7 +77,7 @@ public: enum BufferType { BufferType_Null, - BufferType_Shm, + BufferType_SharedMemory, BufferType_Egl }; @@ -94,14 +94,14 @@ public: BufferType bufferType() const; BufferFormatEgl bufferFormatEgl() const; - bool isShm() const; + bool isSharedMemory() const; QImage image() const; -#ifdef QT_COMPOSITOR_WAYLAND_GL - GLuint textureForPlane(int plane) const; -#endif +#ifdef QT_WAYLAND_COMPOSITOR_GL + GLuint textureForPlane(int plane) const; void bindToTexture() const; void updateTexture() const; +#endif private: class QWaylandBufferRefPrivate *const d; diff --git a/src/compositor/compositor_api/qwaylandclient.cpp b/src/compositor/compositor_api/qwaylandclient.cpp index fbf8c1275..23c3745d7 100644 --- a/src/compositor/compositor_api/qwaylandclient.cpp +++ b/src/compositor/compositor_api/qwaylandclient.cpp @@ -164,6 +164,24 @@ QWaylandClient *QWaylandClient::fromWlClient(QWaylandCompositor *compositor, wl_ } /*! + * \qmlproperty object QtWaylandCompositor::WaylandClient::compositor + * + * This property holds the compositor of this WaylandClient. + */ + +/*! + * \property QWaylandClient::compositor + * + * This property holds the compositor of this QWaylandClient. + */ +QWaylandCompositor *QWaylandClient::compositor() const +{ + Q_D(const QWaylandClient); + + return d->compositor; +} + +/*! * Returns the Wayland client of this QWaylandClient. */ wl_client *QWaylandClient::client() const diff --git a/src/compositor/compositor_api/qwaylandclient.h b/src/compositor/compositor_api/qwaylandclient.h index 26e7b95e5..50e7baf72 100644 --- a/src/compositor/compositor_api/qwaylandclient.h +++ b/src/compositor/compositor_api/qwaylandclient.h @@ -55,6 +55,7 @@ class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandClient : public QObject Q_OBJECT Q_DECLARE_PRIVATE(QWaylandClient) + Q_PROPERTY(QWaylandCompositor *compositor READ compositor CONSTANT) Q_PROPERTY(qint64 userId READ userId CONSTANT) Q_PROPERTY(qint64 groupId READ groupId CONSTANT) Q_PROPERTY(qint64 processId READ processId CONSTANT) @@ -63,6 +64,8 @@ public: static QWaylandClient *fromWlClient(QWaylandCompositor *compositor, wl_client *wlClient); + QWaylandCompositor *compositor() const; + wl_client *client() const; qint64 userId() const; diff --git a/src/compositor/compositor_api/qwaylandcompositor.cpp b/src/compositor/compositor_api/qwaylandcompositor.cpp index 795cb6a59..391b39416 100644 --- a/src/compositor/compositor_api/qwaylandcompositor.cpp +++ b/src/compositor/compositor_api/qwaylandcompositor.cpp @@ -39,7 +39,7 @@ #include "qwaylandcompositor_p.h" #include <QtWaylandCompositor/qwaylandclient.h> -#include <QtWaylandCompositor/qwaylandinput.h> +#include <QtWaylandCompositor/qwaylandseat.h> #include <QtWaylandCompositor/qwaylandoutput.h> #include <QtWaylandCompositor/qwaylandview.h> #include <QtWaylandCompositor/qwaylandclient.h> @@ -58,12 +58,15 @@ #include "hardware_integration/qwlclientbufferintegrationfactory_p.h" #include "hardware_integration/qwlserverbufferintegration_p.h" #include "hardware_integration/qwlserverbufferintegrationfactory_p.h" + +#ifdef QT_WAYLAND_COMPOSITOR_GL #include "hardware_integration/qwlhwintegration_p.h" +#endif -#include "extensions/qwaylandwindowmanagerextension.h" +#include "extensions/qwaylandqtwindowmanager.h" #include "qwaylandxkb_p.h" -#include "qwaylandshmformathelper_p.h" +#include "qwaylandsharedmemoryformathelper_p.h" #include <QtCore/QCoreApplication> #include <QtCore/QStringList> @@ -76,8 +79,8 @@ #include <QtGui/qpa/qplatformnativeinterface.h> #include <QtGui/private/qguiapplication_p.h> -#ifdef QT_COMPOSITOR_WAYLAND_GL -# include <QtGui/private/qopengltextureblitter_p.h> +#ifdef QT_WAYLAND_COMPOSITOR_GL +# include <QOpenGLTextureBlitter> # include <QOpenGLContext> # include <QOpenGLFramebufferObject> # include <QMatrix4x4> @@ -97,7 +100,7 @@ public: { if (e->type == QWindowSystemInterfacePrivate::Key) { QWindowSystemInterfacePrivate::KeyEvent *ke = static_cast<QWindowSystemInterfacePrivate::KeyEvent *>(e); - QWaylandKeyboardPrivate *keyb = QWaylandKeyboardPrivate::get(compositor->defaultInputDevice()->keyboard()); + QWaylandKeyboardPrivate *keyb = QWaylandKeyboardPrivate::get(compositor->defaultSeat()->keyboard()); uint32_t code = ke->nativeScanCode; bool isDown = ke->keyType == QEvent::KeyPress; @@ -138,7 +141,7 @@ public: QWaylandCompositorPrivate::QWaylandCompositorPrivate(QWaylandCompositor *compositor) : display(0) -#if defined (QT_COMPOSITOR_WAYLAND_GL) +#if defined (QT_WAYLAND_COMPOSITOR_GL) , use_hw_integration_extension(true) , client_buffer_integration(0) , server_buffer_integration(0) @@ -172,7 +175,7 @@ void QWaylandCompositorPrivate::init() data_device_manager = new QtWayland::DataDeviceManager(q); wl_display_init_shm(display); - QVector<wl_shm_format> formats = QWaylandShmFormatHelper::supportedWaylandFormats(); + QVector<wl_shm_format> formats = QWaylandSharedMemoryFormatHelper::supportedWaylandFormats(); foreach (wl_shm_format format, formats) wl_display_add_shm_format(display, format); @@ -197,7 +200,7 @@ void QWaylandCompositorPrivate::init() QObject::connect(dispatcher, SIGNAL(aboutToBlock()), q, SLOT(processWaylandEvents())); initializeHardwareIntegration(); - initializeDefaultInputDevice(); + initializeDefaultSeat(); initialized = true; @@ -287,7 +290,7 @@ void QWaylandCompositorPrivate::compositor_create_surface(wl_compositor::Resourc { Q_Q(QWaylandCompositor); QWaylandClient *client = QWaylandClient::fromWlClient(q, resource->client()); - emit q->createSurface(client, id, resource->version()); + emit q->surfaceRequested(client, id, resource->version()); #ifndef QT_NO_DEBUG Q_ASSERT_X(!QWaylandSurfacePrivate::hasUninitializedSurface(), "QWaylandCompositor", QStringLiteral("Found uninitialized QWaylandSurface after emitting QWaylandCompositor::createSurface for id %1. All surfaces has to be initialized immediately after creation. See QWaylandSurface::initialize.").arg(id).toLocal8Bit().constData()); #endif @@ -332,7 +335,7 @@ QWaylandSurface *QWaylandCompositorPrivate::createDefaultSurface() void QWaylandCompositorPrivate::initializeHardwareIntegration() { -#ifdef QT_COMPOSITOR_WAYLAND_GL +#ifdef QT_WAYLAND_COMPOSITOR_GL Q_Q(QWaylandCompositor); if (use_hw_integration_extension) hw_integration.reset(new QtWayland::HardwareIntegration(q)); @@ -347,17 +350,17 @@ void QWaylandCompositorPrivate::initializeHardwareIntegration() #endif } -void QWaylandCompositorPrivate::initializeDefaultInputDevice() +void QWaylandCompositorPrivate::initializeDefaultSeat() { Q_Q(QWaylandCompositor); - QWaylandInputDevice *device = q->createInputDevice(); - inputDevices.append(device); - q->defaultInputDeviceChanged(device, nullptr); + QWaylandSeat *device = q->createSeat(); + seats.append(device); + q->defaultSeatChanged(device, nullptr); } void QWaylandCompositorPrivate::loadClientBufferIntegration() { -#ifdef QT_COMPOSITOR_WAYLAND_GL +#ifdef QT_WAYLAND_COMPOSITOR_GL Q_Q(QWaylandCompositor); QStringList keys = QtWayland::ClientBufferIntegrationFactory::keys(); QString targetKey; @@ -386,7 +389,7 @@ void QWaylandCompositorPrivate::loadClientBufferIntegration() void QWaylandCompositorPrivate::loadServerBufferIntegration() { -#ifdef QT_COMPOSITOR_WAYLAND_GL +#ifdef QT_WAYLAND_COMPOSITOR_GL QStringList keys = QtWayland::ServerBufferIntegrationFactory::keys(); QString targetKey; QByteArray serverBufferIntegration = qgetenv("QT_WAYLAND_SERVER_BUFFER_INTEGRATION"); @@ -408,12 +411,12 @@ void QWaylandCompositorPrivate::loadServerBufferIntegration() \brief Manages the Wayland display server. The WaylandCompositor manages the connections to the clients, as well as the different - \l{WaylandOutput}{outputs} and \l{QWaylandInputDevice}{input devices}. + \l{WaylandOutput}{outputs} and \l{QWaylandSeat}{seats}. Normally, a compositor application will have a single WaylandCompositor instance, which can have several outputs as children. When a client requests the compositor to create a surface, the request is handled by - the onCreateSurface handler. + the onSurfaceRequested handler. Extensions that are supported by the compositor should be instantiated and added to the extensions property. @@ -427,7 +430,7 @@ void QWaylandCompositorPrivate::loadServerBufferIntegration() \brief The QWaylandCompositor class manages the Wayland display server. The QWaylandCompositor manages the connections to the clients, as well as the different \l{QWaylandOutput}{outputs} - and \l{QWaylandInputDevice}{input devices}. + and \l{QWaylandSeat}{seats}. Normally, a compositor application will have a single WaylandCompositor instance, which can have several outputs as children. @@ -568,9 +571,9 @@ void QWaylandCompositor::destroyClient(QWaylandClient *client) if (!client) return; - QWaylandWindowManagerExtension *wmExtension = QWaylandWindowManagerExtension::findIn(this); + QWaylandQtWindowManager *wmExtension = QWaylandQtWindowManager::findIn(this); if (wmExtension) - wmExtension->sendQuitMessage(client->client()); + wmExtension->sendQuitMessage(client); wl_client_destroy(client->client()); } @@ -682,33 +685,33 @@ void QWaylandCompositor::processWaylandEvents() /*! * \internal */ -QWaylandInputDevice *QWaylandCompositor::createInputDevice() +QWaylandSeat *QWaylandCompositor::createSeat() { - return new QWaylandInputDevice(this); + return new QWaylandSeat(this); } /*! * \internal */ -QWaylandPointer *QWaylandCompositor::createPointerDevice(QWaylandInputDevice *inputDevice) +QWaylandPointer *QWaylandCompositor::createPointerDevice(QWaylandSeat *seat) { - return new QWaylandPointer(inputDevice); + return new QWaylandPointer(seat); } /*! * \internal */ -QWaylandKeyboard *QWaylandCompositor::createKeyboardDevice(QWaylandInputDevice *inputDevice) +QWaylandKeyboard *QWaylandCompositor::createKeyboardDevice(QWaylandSeat *seat) { - return new QWaylandKeyboard(inputDevice); + return new QWaylandKeyboard(seat); } /*! * \internal */ -QWaylandTouch *QWaylandCompositor::createTouchDevice(QWaylandInputDevice *inputDevice) +QWaylandTouch *QWaylandCompositor::createTouchDevice(QWaylandSeat *seat) { - return new QWaylandTouch(inputDevice); + return new QWaylandTouch(seat); } /*! @@ -751,38 +754,38 @@ void QWaylandCompositor::overrideSelection(const QMimeData *data) } /*! - * \qmlproperty object QtWaylandCompositor::WaylandCompositor::defaultInputDevice + * \qmlproperty object QtWaylandCompositor::WaylandCompositor::defaultSeat * - * This property contains the default input device for this + * This property contains the default seat for this * WaylandCompositor. */ /*! - * \property QWaylandCompositor::defaultInputDevice + * \property QWaylandCompositor::defaultSeat * - * This property contains the default input device for this + * This property contains the default seat for this * QWaylandCompositor. */ -QWaylandInputDevice *QWaylandCompositor::defaultInputDevice() const +QWaylandSeat *QWaylandCompositor::defaultSeat() const { Q_D(const QWaylandCompositor); - if (d->inputDevices.size()) - return d->inputDevices.first(); + if (d->seats.size()) + return d->seats.first(); return Q_NULLPTR; } /*! * \internal * - * Currently, Qt only supports a single input device, so this exists for + * Currently, Qt only supports a single seat, so this exists for * future proofing the APIs. */ -QWaylandInputDevice *QWaylandCompositor::inputDeviceFor(QInputEvent *inputEvent) +QWaylandSeat *QWaylandCompositor::seatFor(QInputEvent *inputEvent) { Q_D(QWaylandCompositor); - QWaylandInputDevice *dev = NULL; - for (int i = 0; i < d->inputDevices.size(); i++) { - QWaylandInputDevice *candidate = d->inputDevices.at(i); + QWaylandSeat *dev = NULL; + for (int i = 0; i < d->seats.size(); i++) { + QWaylandSeat *candidate = d->seats.at(i); if (candidate->isOwner(inputEvent)) { dev = candidate; break; @@ -810,12 +813,17 @@ QWaylandInputDevice *QWaylandCompositor::inputDeviceFor(QInputEvent *inputEvent) */ bool QWaylandCompositor::useHardwareIntegrationExtension() const { +#ifdef QT_WAYLAND_COMPOSITOR_GL Q_D(const QWaylandCompositor); return d->use_hw_integration_extension; +#else + return false; +#endif } void QWaylandCompositor::setUseHardwareIntegrationExtension(bool use) { +#ifdef QT_WAYLAND_COMPOSITOR_GL Q_D(QWaylandCompositor); if (use == d->use_hw_integration_extension) return; @@ -825,6 +833,10 @@ void QWaylandCompositor::setUseHardwareIntegrationExtension(bool use) d->use_hw_integration_extension = use; useHardwareIntegrationExtensionChanged(); +#else + if (use) + qWarning() << "Hardware integration not supported without OpenGL support"; +#endif } /*! @@ -832,16 +844,16 @@ void QWaylandCompositor::setUseHardwareIntegrationExtension(bool use) * The default implementation requires a OpenGL context to be bound to the current thread * to work. If this is not possible, reimplement this function in your compositor subclass * to implement custom logic. - * The default implementation only grabs SHM and OpenGL buffers, reimplement this in your + * The default implementation only grabs shared memory and OpenGL buffers, reimplement this in your * compositor subclass to handle more buffer types. * \note You should not call this manually, but rather use QWaylandSurfaceGrabber (\a grabber). */ void QWaylandCompositor::grabSurface(QWaylandSurfaceGrabber *grabber, const QWaylandBufferRef &buffer) { - if (buffer.isShm()) { + if (buffer.isSharedMemory()) { emit grabber->success(buffer.image()); } else { -#ifdef QT_COMPOSITOR_WAYLAND_GL +#ifdef QT_WAYLAND_COMPOSITOR_GL if (QOpenGLContext::currentContext()) { QOpenGLFramebufferObject fbo(buffer.size()); fbo.bind(); diff --git a/src/compositor/compositor_api/qwaylandcompositor.h b/src/compositor/compositor_api/qwaylandcompositor.h index f97484d86..15022b378 100644 --- a/src/compositor/compositor_api/qwaylandcompositor.h +++ b/src/compositor/compositor_api/qwaylandcompositor.h @@ -58,7 +58,7 @@ class QOpenGLContext; class QWaylandCompositorPrivate; class QWaylandClient; class QWaylandSurface; -class QWaylandInputDevice; +class QWaylandSeat; class QWaylandGlobalInterface; class QWaylandView; class QWaylandPointer; @@ -77,7 +77,7 @@ class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandCompositor : public QWaylandObject Q_PROPERTY(bool retainedSelection READ retainedSelectionEnabled WRITE setRetainedSelectionEnabled) Q_PROPERTY(QWaylandOutput *defaultOutput READ defaultOutput WRITE setDefaultOutput NOTIFY defaultOutputChanged) Q_PROPERTY(bool useHardwareIntegrationExtension READ useHardwareIntegrationExtension WRITE setUseHardwareIntegrationExtension NOTIFY useHardwareIntegrationExtensionChanged) - Q_PROPERTY(QWaylandInputDevice *defaultInputDevice READ defaultInputDevice NOTIFY defaultInputDeviceChanged) + Q_PROPERTY(QWaylandSeat *defaultSeat READ defaultSeat NOTIFY defaultSeatChanged) public: QWaylandCompositor(QObject *parent = nullptr); @@ -111,11 +111,11 @@ public: bool retainedSelectionEnabled() const; void overrideSelection(const QMimeData *data); - QWaylandInputDevice *defaultInputDevice() const; + QWaylandSeat *defaultSeat() const; QWaylandView *createSurfaceView(QWaylandSurface *surface); - QWaylandInputDevice *inputDeviceFor(QInputEvent *inputEvent); + QWaylandSeat *seatFor(QInputEvent *inputEvent); bool useHardwareIntegrationExtension() const; void setUseHardwareIntegrationExtension(bool use); @@ -126,21 +126,25 @@ public Q_SLOTS: void processWaylandEvents(); Q_SIGNALS: - void createSurface(QWaylandClient *client, uint id, int version); + void surfaceRequested(QWaylandClient *client, uint id, int version); void surfaceCreated(QWaylandSurface *surface); void surfaceAboutToBeDestroyed(QWaylandSurface *surface); void subsurfaceChanged(QWaylandSurface *child, QWaylandSurface *parent); void defaultOutputChanged(); - void defaultInputDeviceChanged(QWaylandInputDevice *newDevice, QWaylandInputDevice *oldDevice); + void defaultSeatChanged(QWaylandSeat *newDevice, QWaylandSeat *oldDevice); void useHardwareIntegrationExtensionChanged(); + + void outputAdded(QWaylandOutput *output); + void outputRemoved(QWaylandOutput *output); + protected: virtual void retainedSelectionReceived(QMimeData *mimeData); - virtual QWaylandInputDevice *createInputDevice(); - virtual QWaylandPointer *createPointerDevice(QWaylandInputDevice *inputDevice); - virtual QWaylandKeyboard *createKeyboardDevice(QWaylandInputDevice *inputDevice); - virtual QWaylandTouch *createTouchDevice(QWaylandInputDevice *inputDevice); + virtual QWaylandSeat *createSeat(); + virtual QWaylandPointer *createPointerDevice(QWaylandSeat *seat); + virtual QWaylandKeyboard *createKeyboardDevice(QWaylandSeat *seat); + virtual QWaylandTouch *createTouchDevice(QWaylandSeat *seat); QWaylandCompositor(QWaylandCompositorPrivate &dptr, QObject *parent = nullptr); }; diff --git a/src/compositor/compositor_api/qwaylandcompositor_p.h b/src/compositor/compositor_api/qwaylandcompositor_p.h index 8966acb38..708d0113d 100644 --- a/src/compositor/compositor_api/qwaylandcompositor_p.h +++ b/src/compositor/compositor_api/qwaylandcompositor_p.h @@ -90,12 +90,12 @@ public: QtWayland::DataDeviceManager *dataDeviceManager() const { return data_device_manager; } void feedRetainedSelectionData(QMimeData *data); - QWaylandPointer *callCreatePointerDevice(QWaylandInputDevice *inputDevice) - { return q_func()->createPointerDevice(inputDevice); } - QWaylandKeyboard *callCreateKeyboardDevice(QWaylandInputDevice *inputDevice) - { return q_func()->createKeyboardDevice(inputDevice); } - QWaylandTouch *callCreateTouchDevice(QWaylandInputDevice *inputDevice) - { return q_func()->createTouchDevice(inputDevice); } + QWaylandPointer *callCreatePointerDevice(QWaylandSeat *seat) + { return q_func()->createPointerDevice(seat); } + QWaylandKeyboard *callCreateKeyboardDevice(QWaylandSeat *seat) + { return q_func()->createKeyboardDevice(seat); } + QWaylandTouch *callCreateTouchDevice(QWaylandSeat *seat) + { return q_func()->createTouchDevice(seat); } inline void addClient(QWaylandClient *client); inline void removeClient(QWaylandClient *client); @@ -114,7 +114,7 @@ protected: protected: void initializeHardwareIntegration(); void initializeExtensions(); - void initializeDefaultInputDevice(); + void initializeDefaultSeat(); void loadClientBufferIntegration(); void loadServerBufferIntegration(); @@ -122,7 +122,7 @@ protected: QByteArray socket_name; struct wl_display *display; - QList<QWaylandInputDevice *> inputDevices; + QList<QWaylandSeat *> seats; QList<QWaylandOutput *> outputs; QList<QWaylandSurface *> all_surfaces; @@ -135,7 +135,7 @@ protected: QList<QWaylandClient *> clients; -#ifdef QT_COMPOSITOR_WAYLAND_GL +#ifdef QT_WAYLAND_COMPOSITOR_GL bool use_hw_integration_extension; QScopedPointer<QtWayland::HardwareIntegration> hw_integration; QScopedPointer<QtWayland::ClientBufferIntegration> client_buffer_integration; @@ -154,7 +154,7 @@ protected: QtWayland::ClientBufferIntegration * QWaylandCompositorPrivate::clientBufferIntegration() const { -#ifdef QT_COMPOSITOR_WAYLAND_GL +#ifdef QT_WAYLAND_COMPOSITOR_GL return client_buffer_integration.data(); #else return 0; @@ -163,7 +163,7 @@ QtWayland::ClientBufferIntegration * QWaylandCompositorPrivate::clientBufferInte QtWayland::ServerBufferIntegration * QWaylandCompositorPrivate::serverBufferIntegration() const { -#ifdef QT_COMPOSITOR_WAYLAND_GL +#ifdef QT_WAYLAND_COMPOSITOR_GL return server_buffer_integration.data(); #else return 0; @@ -185,16 +185,20 @@ void QWaylandCompositorPrivate::removeClient(QWaylandClient *client) void QWaylandCompositorPrivate::addOutput(QWaylandOutput *output) { Q_ASSERT(output); + Q_Q(QWaylandCompositor); if (outputs.contains(output)) return; outputs.append(output); + emit q->outputAdded(output); } void QWaylandCompositorPrivate::removeOutput(QWaylandOutput *output) { Q_ASSERT(output); Q_ASSERT(outputs.count(output) == 1); - outputs.removeOne(output); + Q_Q(QWaylandCompositor); + if (outputs.removeOne(output)) + emit q->outputRemoved(output); } QT_END_NAMESPACE diff --git a/src/compositor/compositor_api/qwaylanddrag.cpp b/src/compositor/compositor_api/qwaylanddrag.cpp index cc45c1279..3c3d9ce52 100644 --- a/src/compositor/compositor_api/qwaylanddrag.cpp +++ b/src/compositor/compositor_api/qwaylanddrag.cpp @@ -40,33 +40,33 @@ #include "qwldatadevice_p.h" #include "qwaylandview.h" -#include <QtWaylandCompositor/private/qwaylandinput_p.h> +#include <QtWaylandCompositor/private/qwaylandseat_p.h> QT_BEGIN_NAMESPACE class QWaylandDragPrivate : public QObjectPrivate { public: - QWaylandDragPrivate(QWaylandInputDevice *id) - : inputDevice(id) + QWaylandDragPrivate(QWaylandSeat *seat) + : seat(seat) { } QtWayland::DataDevice *dataDevice() { - return QWaylandInputDevicePrivate::get(inputDevice)->dataDevice(); + return QWaylandSeatPrivate::get(seat)->dataDevice(); } const QtWayland::DataDevice *dataDevice() const { - return QWaylandInputDevicePrivate::get(inputDevice)->dataDevice(); + return QWaylandSeatPrivate::get(seat)->dataDevice(); } - QWaylandInputDevice *inputDevice; + QWaylandSeat *seat; }; -QWaylandDrag::QWaylandDrag(QWaylandInputDevice *inputDevice) - : QObject(* new QWaylandDragPrivate(inputDevice)) +QWaylandDrag::QWaylandDrag(QWaylandSeat *seat) + : QObject(* new QWaylandDragPrivate(seat)) { } @@ -81,6 +81,19 @@ QWaylandSurface *QWaylandDrag::icon() const return dataDevice->dragIcon(); } +QWaylandSurface *QWaylandDrag::origin() const +{ + Q_D(const QWaylandDrag); + const QtWayland::DataDevice *dataDevice = d->dataDevice(); + return dataDevice ? dataDevice->dragOrigin() : nullptr; +} + +QWaylandSeat *QWaylandDrag::seat() const +{ + Q_D(const QWaylandDrag); + return d->seat; +} + bool QWaylandDrag::visible() const { diff --git a/src/compositor/compositor_api/qwaylanddrag.h b/src/compositor/compositor_api/qwaylanddrag.h index 00a2bee8e..08ad11018 100644 --- a/src/compositor/compositor_api/qwaylanddrag.h +++ b/src/compositor/compositor_api/qwaylanddrag.h @@ -46,12 +46,7 @@ QT_BEGIN_NAMESPACE class QWaylandDragPrivate; class QWaylandSurface; -class QWaylandView; -class QWaylandInputDevice; - -namespace QtWayland { - class DataDevice; -} +class QWaylandSeat; class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandDrag : public QObject { @@ -62,10 +57,11 @@ class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandDrag : public QObject Q_PROPERTY(bool visible READ visible NOTIFY iconChanged) public: - explicit QWaylandDrag(QWaylandInputDevice *inputDevice); + explicit QWaylandDrag(QWaylandSeat *seat); QWaylandSurface *icon() const; - // QPointF position() const; + QWaylandSurface *origin() const; + QWaylandSeat *seat() const; bool visible() const; public Q_SLOTS: @@ -76,9 +72,6 @@ public Q_SLOTS: Q_SIGNALS: void iconChanged(); void dragStarted(); // QWaylandSurface *icon???? - -private: - //friend class QtWayland::DataDevice; }; QT_END_NAMESPACE diff --git a/src/compositor/compositor_api/qwaylandinputmethodcontrol.cpp b/src/compositor/compositor_api/qwaylandinputmethodcontrol.cpp index 122c589da..68279bb97 100644 --- a/src/compositor/compositor_api/qwaylandinputmethodcontrol.cpp +++ b/src/compositor/compositor_api/qwaylandinputmethodcontrol.cpp @@ -38,7 +38,7 @@ #include "qwaylandinputmethodcontrol_p.h" #include "qwaylandcompositor.h" -#include "qwaylandinput.h" +#include "qwaylandseat.h" #include "qwaylandsurface.h" #include "qwaylandview.h" #include "qwaylandtextinput.h" @@ -48,8 +48,8 @@ QWaylandInputMethodControl::QWaylandInputMethodControl(QWaylandSurface *surface) : QObject(*new QWaylandInputMethodControlPrivate(surface), surface) { - connect(d_func()->compositor, &QWaylandCompositor::defaultInputDeviceChanged, - this, &QWaylandInputMethodControl::defaultInputDeviceChanged); + connect(d_func()->compositor, &QWaylandCompositor::defaultSeatChanged, + this, &QWaylandInputMethodControl::defaultSeatChanged); QWaylandTextInput *textInput = d_func()->textInput(); if (textInput) { connect(textInput, &QWaylandTextInput::surfaceEnabled, this, &QWaylandInputMethodControl::surfaceEnabled); @@ -135,13 +135,13 @@ void QWaylandInputMethodControl::setSurface(QWaylandSurface *surface) setEnabled(textInput && textInput->isSurfaceEnabled(d->surface)); } -void QWaylandInputMethodControl::defaultInputDeviceChanged() +void QWaylandInputMethodControl::defaultSeatChanged() { Q_D(QWaylandInputMethodControl); disconnect(d->textInput(), 0, this, 0); - d->inputDevice = d->compositor->defaultInputDevice(); + d->seat = d->compositor->defaultSeat(); QWaylandTextInput *textInput = d->textInput(); connect(textInput, &QWaylandTextInput::surfaceEnabled, this, &QWaylandInputMethodControl::surfaceEnabled); @@ -153,7 +153,7 @@ void QWaylandInputMethodControl::defaultInputDeviceChanged() QWaylandInputMethodControlPrivate::QWaylandInputMethodControlPrivate(QWaylandSurface *surface) : QObjectPrivate() , compositor(surface->compositor()) - , inputDevice(compositor->defaultInputDevice()) + , seat(compositor->defaultSeat()) , surface(surface) , enabled(false) { @@ -161,5 +161,5 @@ QWaylandInputMethodControlPrivate::QWaylandInputMethodControlPrivate(QWaylandSur QWaylandTextInput *QWaylandInputMethodControlPrivate::textInput() const { - return QWaylandTextInput::findIn(inputDevice); + return QWaylandTextInput::findIn(seat); } diff --git a/src/compositor/compositor_api/qwaylandinputmethodcontrol.h b/src/compositor/compositor_api/qwaylandinputmethodcontrol.h index f71650294..ab894c9c5 100644 --- a/src/compositor/compositor_api/qwaylandinputmethodcontrol.h +++ b/src/compositor/compositor_api/qwaylandinputmethodcontrol.h @@ -74,7 +74,7 @@ Q_SIGNALS: #endif private: - void defaultInputDeviceChanged(); + void defaultSeatChanged(); void surfaceEnabled(QWaylandSurface *surface); void surfaceDisabled(QWaylandSurface *surface); }; diff --git a/src/compositor/compositor_api/qwaylandinputmethodcontrol_p.h b/src/compositor/compositor_api/qwaylandinputmethodcontrol_p.h index a687e5299..a4f9ce877 100644 --- a/src/compositor/compositor_api/qwaylandinputmethodcontrol_p.h +++ b/src/compositor/compositor_api/qwaylandinputmethodcontrol_p.h @@ -56,7 +56,7 @@ QT_BEGIN_NAMESPACE class QWaylandCompositor; -class QWaylandInputDevice; +class QWaylandSeat; class QWaylandSurface; class QWaylandTextInput; @@ -70,7 +70,7 @@ public: QWaylandTextInput *textInput() const; QWaylandCompositor *compositor; - QWaylandInputDevice *inputDevice; + QWaylandSeat *seat; QWaylandSurface *surface; bool enabled; }; diff --git a/src/compositor/compositor_api/qwaylandkeyboard.cpp b/src/compositor/compositor_api/qwaylandkeyboard.cpp index 22870654e..42349fb24 100644 --- a/src/compositor/compositor_api/qwaylandkeyboard.cpp +++ b/src/compositor/compositor_api/qwaylandkeyboard.cpp @@ -38,7 +38,7 @@ #include "qwaylandkeyboard.h" #include "qwaylandkeyboard_p.h" #include <QtWaylandCompositor/QWaylandCompositor> -#include <QtWaylandCompositor/QWaylandInputDevice> +#include <QtWaylandCompositor/QWaylandSeat> #include <QtWaylandCompositor/QWaylandClient> #include <QtCore/QFile> @@ -53,7 +53,7 @@ QT_BEGIN_NAMESPACE -QWaylandKeyboardPrivate::QWaylandKeyboardPrivate(QWaylandInputDevice *seat) +QWaylandKeyboardPrivate::QWaylandKeyboardPrivate(QWaylandSeat *seat) : QtWaylandServer::wl_keyboard() , seat(seat) , focus() @@ -384,24 +384,24 @@ void QWaylandKeyboardPrivate::sendRepeatInfo() * \preliminary * \brief The QWaylandKeyboard class represents a keyboard device. * - * This class provides access to the keyboard device in a QWaylandInputDevice. It corresponds to + * This class provides access to the keyboard device in a QWaylandSeat. It corresponds to * the Wayland interface wl_keyboard. */ /*! - * Constructs a QWaylandKeyboard for the given \a inputDevice and with the given \a parent. + * Constructs a QWaylandKeyboard for the given \a seat and with the given \a parent. */ -QWaylandKeyboard::QWaylandKeyboard(QWaylandInputDevice *inputDevice, QObject *parent) - : QWaylandObject(* new QWaylandKeyboardPrivate(inputDevice), parent) +QWaylandKeyboard::QWaylandKeyboard(QWaylandSeat *seat, QObject *parent) + : QWaylandObject(* new QWaylandKeyboardPrivate(seat), parent) { Q_D(QWaylandKeyboard); connect(&d->focusDestroyListener, &QWaylandDestroyListener::fired, this, &QWaylandKeyboard::focusDestroyed); } /*! - * Returns the input device for this QWaylandKeyboard. + * Returns the seat for this QWaylandKeyboard. */ -QWaylandInputDevice *QWaylandKeyboard::inputDevice() const +QWaylandSeat *QWaylandKeyboard::seat() const { Q_D(const QWaylandKeyboard); return d->seat; diff --git a/src/compositor/compositor_api/qwaylandkeyboard.h b/src/compositor/compositor_api/qwaylandkeyboard.h index b5bf6fe5c..1348f5cd9 100644 --- a/src/compositor/compositor_api/qwaylandkeyboard.h +++ b/src/compositor/compositor_api/qwaylandkeyboard.h @@ -47,7 +47,7 @@ QT_BEGIN_NAMESPACE class QWaylandKeyboard; class QWaylandKeyboardPrivate; -class QWaylandInputDevice; +class QWaylandSeat; class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandKeymap { @@ -76,9 +76,9 @@ class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandKeyboard : public QWaylandObject Q_PROPERTY(quint32 repeatRate READ repeatRate WRITE setRepeatRate NOTIFY repeatRateChanged) Q_PROPERTY(quint32 repeatDelay READ repeatDelay WRITE setRepeatDelay NOTIFY repeatDelayChanged) public: - QWaylandKeyboard(QWaylandInputDevice *inputDevice, QObject *parent = nullptr); + QWaylandKeyboard(QWaylandSeat *seat, QObject *parent = nullptr); - QWaylandInputDevice *inputDevice() const; + QWaylandSeat *seat() const; QWaylandCompositor *compositor() const; quint32 repeatRate() const; diff --git a/src/compositor/compositor_api/qwaylandkeyboard_p.h b/src/compositor/compositor_api/qwaylandkeyboard_p.h index ede97d8ba..ac306282e 100644 --- a/src/compositor/compositor_api/qwaylandkeyboard_p.h +++ b/src/compositor/compositor_api/qwaylandkeyboard_p.h @@ -50,7 +50,7 @@ // #include <QtWaylandCompositor/qwaylandexport.h> -#include <QtWaylandCompositor/qwaylandinput.h> +#include <QtWaylandCompositor/qwaylandseat.h> #include <QtWaylandCompositor/qwaylandkeyboard.h> #include <QtWaylandCompositor/qwaylanddestroylistener.h> @@ -74,7 +74,7 @@ public: static QWaylandKeyboardPrivate *get(QWaylandKeyboard *keyboard); - QWaylandKeyboardPrivate(QWaylandInputDevice *seat); + QWaylandKeyboardPrivate(QWaylandSeat *seat); ~QWaylandKeyboardPrivate(); QWaylandCompositor *compositor() const { return seat->compositor(); } @@ -111,7 +111,7 @@ private: void sendRepeatInfo(); - QWaylandInputDevice *seat; + QWaylandSeat *seat; QWaylandSurface *focus; Resource *focusResource; diff --git a/src/compositor/compositor_api/qwaylandoutput.cpp b/src/compositor/compositor_api/qwaylandoutput.cpp index a2ebf8b25..c34080b36 100644 --- a/src/compositor/compositor_api/qwaylandoutput.cpp +++ b/src/compositor/compositor_api/qwaylandoutput.cpp @@ -846,7 +846,7 @@ void QWaylandOutput::sendFrameCallbacks() Q_D(QWaylandOutput); for (int i = 0; i < d->surfaceViews.size(); i++) { const QWaylandSurfaceViewMapper &surfacemapper = d->surfaceViews.at(i); - if (surfacemapper.surface && surfacemapper.surface->isMapped()) { + if (surfacemapper.surface && surfacemapper.surface->hasContent()) { if (!surfacemapper.has_entered) { surfaceEnter(surfacemapper.surface); d->surfaceViews[i].has_entered = true; diff --git a/src/compositor/compositor_api/qwaylandpointer.cpp b/src/compositor/compositor_api/qwaylandpointer.cpp index 5e9778637..742987c8b 100644 --- a/src/compositor/compositor_api/qwaylandpointer.cpp +++ b/src/compositor/compositor_api/qwaylandpointer.cpp @@ -43,7 +43,7 @@ QT_BEGIN_NAMESPACE QWaylandSurfaceRole QWaylandPointerPrivate::s_role("wl_pointer"); -QWaylandPointerPrivate::QWaylandPointerPrivate(QWaylandPointer *pointer, QWaylandInputDevice *seat) +QWaylandPointerPrivate::QWaylandPointerPrivate(QWaylandPointer *pointer, QWaylandSeat *seat) : QObjectPrivate() , wl_pointer() , seat(seat) @@ -97,24 +97,24 @@ void QWaylandPointerPrivate::pointer_set_cursor(wl_pointer::Resource *resource, * \preliminary * \brief The QWaylandPointer class represents a pointer device. * - * This class provides access to the pointer device in a QWaylandInputDevice. It corresponds to + * This class provides access to the pointer device in a QWaylandSeat. It corresponds to * the Wayland interface wl_pointer. */ /*! - * Constructs a QWaylandPointer for the given \a inputDevice and with the given \a parent. + * Constructs a QWaylandPointer for the given \a seat and with the given \a parent. */ -QWaylandPointer::QWaylandPointer(QWaylandInputDevice *inputDevice, QObject *parent) - : QWaylandObject(* new QWaylandPointerPrivate(this, inputDevice), parent) +QWaylandPointer::QWaylandPointer(QWaylandSeat *seat, QObject *parent) + : QWaylandObject(* new QWaylandPointerPrivate(this, seat), parent) { connect(&d_func()->focusDestroyListener, &QWaylandDestroyListener::fired, this, &QWaylandPointer::focusDestroyed); - connect(inputDevice, &QWaylandInputDevice::mouseFocusChanged, this, &QWaylandPointer::pointerFocusChanged); + connect(seat, &QWaylandSeat::mouseFocusChanged, this, &QWaylandPointer::pointerFocusChanged); } /*! * Returns the input device for this QWaylandPointer. */ -QWaylandInputDevice *QWaylandPointer::inputDevice() const +QWaylandSeat *QWaylandPointer::seat() const { Q_D(const QWaylandPointer); return d->seat; diff --git a/src/compositor/compositor_api/qwaylandpointer.h b/src/compositor/compositor_api/qwaylandpointer.h index 9d7d06807..0db1635bb 100644 --- a/src/compositor/compositor_api/qwaylandpointer.h +++ b/src/compositor/compositor_api/qwaylandpointer.h @@ -45,7 +45,7 @@ QT_BEGIN_NAMESPACE class QWaylandPointer; class QWaylandPointerPrivate; -class QWaylandInputDevice; +class QWaylandSeat; class QWaylandView; class QWaylandOutput; class QWaylandClient; @@ -56,9 +56,9 @@ class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandPointer : public QWaylandObject Q_DECLARE_PRIVATE(QWaylandPointer) Q_PROPERTY(bool isButtonPressed READ isButtonPressed NOTIFY buttonPressedChanged) public: - QWaylandPointer(QWaylandInputDevice *inputDevice, QObject *parent = nullptr); + QWaylandPointer(QWaylandSeat *seat, QObject *parent = nullptr); - QWaylandInputDevice *inputDevice() const; + QWaylandSeat *seat() const; QWaylandCompositor *compositor() const; QWaylandOutput *output() const; diff --git a/src/compositor/compositor_api/qwaylandpointer_p.h b/src/compositor/compositor_api/qwaylandpointer_p.h index 5ac030029..54ac72d11 100644 --- a/src/compositor/compositor_api/qwaylandpointer_p.h +++ b/src/compositor/compositor_api/qwaylandpointer_p.h @@ -61,7 +61,7 @@ #include <QtWaylandCompositor/private/qwayland-server-wayland.h> #include <QtWaylandCompositor/QWaylandView> #include <QtWaylandCompositor/QWaylandSurface> -#include <QtWaylandCompositor/QWaylandInputDevice> +#include <QtWaylandCompositor/QWaylandSeat> #include <stdint.h> @@ -74,7 +74,7 @@ class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandPointerPrivate : public QObjectPrivate { Q_DECLARE_PUBLIC(QWaylandPointer) public: - QWaylandPointerPrivate(QWaylandPointer *pointer, QWaylandInputDevice *seat); + QWaylandPointerPrivate(QWaylandPointer *pointer, QWaylandSeat *seat); QWaylandCompositor *compositor() const { return seat->compositor(); } @@ -86,7 +86,7 @@ protected: private: void focusDestroyed(void *data); - QWaylandInputDevice *seat; + QWaylandSeat *seat; QWaylandOutput *output; QPointF localPosition; diff --git a/src/compositor/compositor_api/qwaylandquickcompositor.cpp b/src/compositor/compositor_api/qwaylandquickcompositor.cpp index 64e6fec70..07ea381b4 100644 --- a/src/compositor/compositor_api/qwaylandquickcompositor.cpp +++ b/src/compositor/compositor_api/qwaylandquickcompositor.cpp @@ -37,7 +37,7 @@ #include <QtQml/QQmlEngine> #include <QQuickWindow> -#include <QtGui/private/qopengltextureblitter_p.h> +#include <QOpenGLTextureBlitter> #include <QOpenGLFramebufferObject> #include <QMatrix4x4> #include <QRunnable> @@ -114,7 +114,7 @@ void QWaylandQuickCompositor::componentComplete() */ void QWaylandQuickCompositor::grabSurface(QWaylandSurfaceGrabber *grabber, const QWaylandBufferRef &buffer) { - if (buffer.isShm()) { + if (buffer.isSharedMemory()) { QWaylandCompositor::grabSurface(grabber, buffer); return; } diff --git a/src/compositor/compositor_api/qwaylandquickitem.cpp b/src/compositor/compositor_api/qwaylandquickitem.cpp index a1855529c..08eefffa0 100644 --- a/src/compositor/compositor_api/qwaylandquickitem.cpp +++ b/src/compositor/compositor_api/qwaylandquickitem.cpp @@ -39,14 +39,17 @@ #include "qwaylandquicksurface.h" #include "qwaylandinputmethodcontrol.h" #include "qwaylandtextinput.h" +#include "qwaylandquickoutput.h" #include <QtWaylandCompositor/qwaylandcompositor.h> -#include <QtWaylandCompositor/qwaylandinput.h> +#include <QtWaylandCompositor/qwaylandseat.h> #include <QtWaylandCompositor/qwaylandbufferref.h> +#include <QtWaylandCompositor/QWaylandDrag> #include <QtWaylandCompositor/private/qwlclientbufferintegration_p.h> #include <QtGui/QKeyEvent> #include <QtGui/QGuiApplication> #include <QtGui/QScreen> +#include <QtGui/QOpenGLFunctions> #include <QtQuick/QSGSimpleTextureNode> #include <QtQuick/QQuickWindow> @@ -293,7 +296,7 @@ public: delete m_sgTex; m_sgTex = 0; if (m_ref.hasBuffer()) { - if (buffer.isShm()) { + if (buffer.isSharedMemory()) { m_sgTex = surfaceItem->window()->createTextureFromImage(buffer.image()); if (m_sgTex) { m_sgTex->bind(); @@ -492,13 +495,13 @@ void QWaylandQuickItem::mousePressEvent(QMouseEvent *event) return; } - QWaylandInputDevice *inputDevice = compositor()->inputDeviceFor(event); + QWaylandSeat *seat = compositor()->seatFor(event); if (d->focusOnClick) - takeFocus(inputDevice); + takeFocus(seat); - inputDevice->sendMouseMoveEvent(d->view.data(), event->localPos() / d->scaleFactor(), event->windowPos()); - inputDevice->sendMousePressEvent(event->button()); + seat->sendMouseMoveEvent(d->view.data(), mapToSurface(event->localPos()), event->windowPos()); + seat->sendMousePressEvent(event->button()); } /*! @@ -508,8 +511,20 @@ void QWaylandQuickItem::mouseMoveEvent(QMouseEvent *event) { Q_D(QWaylandQuickItem); if (d->shouldSendInputEvents()) { - QWaylandInputDevice *inputDevice = compositor()->inputDeviceFor(event); - inputDevice->sendMouseMoveEvent(d->view.data(), event->localPos() / d->scaleFactor(), event->windowPos()); + QWaylandSeat *seat = compositor()->seatFor(event); + if (d->isDragging) { + QWaylandQuickOutput *currentOutput = qobject_cast<QWaylandQuickOutput *>(view()->output()); + //TODO: also check if dragging onto other outputs + QWaylandQuickItem *targetItem = qobject_cast<QWaylandQuickItem *>(currentOutput->pickClickableItem(mapToScene(event->localPos()))); + QWaylandSurface *targetSurface = targetItem ? targetItem->surface() : nullptr; + if (targetSurface) { + QPointF position = mapToItem(targetItem, event->localPos()); + QPointF surfacePosition = targetItem->mapToSurface(position); + seat->drag()->dragMove(targetSurface, surfacePosition); + } + } else { + seat->sendMouseMoveEvent(d->view.data(), mapToSurface(event->localPos()), event->windowPos()); + } } else { emit mouseMove(event->windowPos()); event->ignore(); @@ -523,8 +538,13 @@ void QWaylandQuickItem::mouseReleaseEvent(QMouseEvent *event) { Q_D(QWaylandQuickItem); if (d->shouldSendInputEvents()) { - QWaylandInputDevice *inputDevice = compositor()->inputDeviceFor(event); - inputDevice->sendMouseReleaseEvent(event->button()); + QWaylandSeat *seat = compositor()->seatFor(event); + if (d->isDragging) { + d->isDragging = false; + seat->drag()->drop(); + } else { + seat->sendMouseReleaseEvent(event->button()); + } } else { emit mouseRelease(); event->ignore(); @@ -542,8 +562,8 @@ void QWaylandQuickItem::hoverEnterEvent(QHoverEvent *event) return; } if (d->shouldSendInputEvents()) { - QWaylandInputDevice *inputDevice = compositor()->inputDeviceFor(event); - inputDevice->sendMouseMoveEvent(d->view.data(), event->pos(), mapToScene(event->pos())); + QWaylandSeat *seat = compositor()->seatFor(event); + seat->sendMouseMoveEvent(d->view.data(), event->pos(), mapToScene(event->pos())); } else { event->ignore(); } @@ -562,8 +582,8 @@ void QWaylandQuickItem::hoverMoveEvent(QHoverEvent *event) } } if (d->shouldSendInputEvents()) { - QWaylandInputDevice *inputDevice = compositor()->inputDeviceFor(event); - inputDevice->sendMouseMoveEvent(d->view.data(), event->pos() / d->scaleFactor(), mapToScene(event->pos())); + QWaylandSeat *seat = compositor()->seatFor(event); + seat->sendMouseMoveEvent(d->view.data(), mapToSurface(event->pos()), mapToScene(event->pos())); } else { event->ignore(); } @@ -576,8 +596,8 @@ void QWaylandQuickItem::hoverLeaveEvent(QHoverEvent *event) { Q_D(QWaylandQuickItem); if (d->shouldSendInputEvents()) { - QWaylandInputDevice *inputDevice = compositor()->inputDeviceFor(event); - inputDevice->setMouseFocus(Q_NULLPTR); + QWaylandSeat *seat = compositor()->seatFor(event); + seat->setMouseFocus(Q_NULLPTR); } else { event->ignore(); } @@ -595,8 +615,8 @@ void QWaylandQuickItem::wheelEvent(QWheelEvent *event) return; } - QWaylandInputDevice *inputDevice = compositor()->inputDeviceFor(event); - inputDevice->sendMouseWheelEvent(event->orientation(), event->delta()); + QWaylandSeat *seat = compositor()->seatFor(event); + seat->sendMouseWheelEvent(event->orientation(), event->delta()); } else { event->ignore(); } @@ -609,8 +629,8 @@ void QWaylandQuickItem::keyPressEvent(QKeyEvent *event) { Q_D(QWaylandQuickItem); if (d->shouldSendInputEvents()) { - QWaylandInputDevice *inputDevice = compositor()->inputDeviceFor(event); - inputDevice->sendFullKeyEvent(event); + QWaylandSeat *seat = compositor()->seatFor(event); + seat->sendFullKeyEvent(event); } else { event->ignore(); } @@ -623,8 +643,8 @@ void QWaylandQuickItem::keyReleaseEvent(QKeyEvent *event) { Q_D(QWaylandQuickItem); if (d->shouldSendInputEvents() && hasFocus()) { - QWaylandInputDevice *inputDevice = compositor()->inputDeviceFor(event); - inputDevice->sendFullKeyEvent(event); + QWaylandSeat *seat = compositor()->seatFor(event); + seat->sendFullKeyEvent(event); } else { event->ignore(); } @@ -637,7 +657,7 @@ void QWaylandQuickItem::touchEvent(QTouchEvent *event) { Q_D(QWaylandQuickItem); if (d->shouldSendInputEvents() && d->touchEventsEnabled) { - QWaylandInputDevice *inputDevice = compositor()->inputDeviceFor(event); + QWaylandSeat *seat = compositor()->seatFor(event); if (event->type() == QEvent::TouchBegin) { QQuickItem *grabber = window()->mouseGrabberItem(); @@ -656,10 +676,10 @@ void QWaylandQuickItem::touchEvent(QTouchEvent *event) } event->accept(); - if (inputDevice->mouseFocus() != d->view.data()) { - inputDevice->sendMouseMoveEvent(d->view.data(), pointPos, mapToScene(pointPos)); + if (seat->mouseFocus() != d->view.data()) { + seat->sendMouseMoveEvent(d->view.data(), pointPos, mapToScene(pointPos)); } - inputDevice->sendFullTouchEvent(event); + seat->sendFullTouchEvent(event); } else { event->ignore(); } @@ -757,31 +777,90 @@ void QWaylandQuickItem::setSubsurfaceHandler(QObject *handler) } /*! + * \property QWaylandQuickItem::output + * + * This property holds the output on which this item is displayed. + */ +QWaylandOutput *QWaylandQuickItem::output() const +{ + Q_D(const QWaylandQuickItem); + return d->view->output(); +} + +void QWaylandQuickItem::setOutput(QWaylandOutput *output) +{ + Q_D(QWaylandQuickItem); + d->view->setOutput(output); +} + +/*! + * \property QWaylandQuickItem::bufferLocked + * + * This property holds whether the item's buffer is currently locked. As long as + * the buffer is locked, it will not be released and returned to the client. + * + * The default is false. + */ +bool QWaylandQuickItem::isBufferLocked() const +{ + Q_D(const QWaylandQuickItem); + return d->view->isBufferLocked(); +} + +void QWaylandQuickItem::setBufferLocked(bool locked) +{ + Q_D(QWaylandQuickItem); + d->view->setBufferLocked(locked); +} + +/*! + * \property bool QWaylandQuickItem::allowDiscardFrontBuffer + * + * By default, the item locks the current buffer until a new buffer is available + * and updatePaintNode() is called. Set this property to true to allow Qt to release the buffer + * immediately when the throttling view is no longer using it. This is useful for items that have + * slow update intervals. + */ +bool QWaylandQuickItem::allowDiscardFrontBuffer() const +{ + Q_D(const QWaylandQuickItem); + return d->view->allowDiscardFrontBuffer(); +} + +void QWaylandQuickItem::setAllowDiscardFrontBuffer(bool discard) +{ + Q_D(QWaylandQuickItem); + d->view->setAllowDiscardFrontBuffer(discard); +} + +/*! * \internal */ void QWaylandQuickItem::handleSurfaceChanged() { Q_D(QWaylandQuickItem); if (d->oldSurface) { - disconnect(d->oldSurface, &QWaylandSurface::mappedChanged, this, &QWaylandQuickItem::surfaceMappedChanged); + disconnect(d->oldSurface, &QWaylandSurface::hasContentChanged, this, &QWaylandQuickItem::surfaceMappedChanged); disconnect(d->oldSurface, &QWaylandSurface::parentChanged, this, &QWaylandQuickItem::parentChanged); disconnect(d->oldSurface, &QWaylandSurface::sizeChanged, this, &QWaylandQuickItem::updateSize); disconnect(d->oldSurface, &QWaylandSurface::bufferScaleChanged, this, &QWaylandQuickItem::updateSize); disconnect(d->oldSurface, &QWaylandSurface::configure, this, &QWaylandQuickItem::updateBuffer); disconnect(d->oldSurface, &QWaylandSurface::redraw, this, &QQuickItem::update); disconnect(d->oldSurface, &QWaylandSurface::childAdded, this, &QWaylandQuickItem::handleSubsurfaceAdded); + disconnect(d->oldSurface, &QWaylandSurface::dragStarted, this, &QWaylandQuickItem::handleDragStarted); #ifndef QT_NO_IM disconnect(d->oldSurface->inputMethodControl(), &QWaylandInputMethodControl::updateInputMethod, this, &QWaylandQuickItem::updateInputMethod); #endif } if (QWaylandSurface *newSurface = d->view->surface()) { - connect(newSurface, &QWaylandSurface::mappedChanged, this, &QWaylandQuickItem::surfaceMappedChanged); + connect(newSurface, &QWaylandSurface::hasContentChanged, this, &QWaylandQuickItem::surfaceMappedChanged); connect(newSurface, &QWaylandSurface::parentChanged, this, &QWaylandQuickItem::parentChanged); connect(newSurface, &QWaylandSurface::sizeChanged, this, &QWaylandQuickItem::updateSize); connect(newSurface, &QWaylandSurface::bufferScaleChanged, this, &QWaylandQuickItem::updateSize); connect(newSurface, &QWaylandSurface::configure, this, &QWaylandQuickItem::updateBuffer); connect(newSurface, &QWaylandSurface::redraw, this, &QQuickItem::update); connect(newSurface, &QWaylandSurface::childAdded, this, &QWaylandQuickItem::handleSubsurfaceAdded); + connect(newSurface, &QWaylandSurface::dragStarted, this, &QWaylandQuickItem::handleDragStarted); #ifndef QT_NO_IM connect(newSurface->inputMethodControl(), &QWaylandInputMethodControl::updateInputMethod, this, &QWaylandQuickItem::updateInputMethod); #endif @@ -808,16 +887,16 @@ void QWaylandQuickItem::handleSurfaceChanged() * Calling this function causes the item to take the focus of the * input \a device. */ -void QWaylandQuickItem::takeFocus(QWaylandInputDevice *device) +void QWaylandQuickItem::takeFocus(QWaylandSeat *device) { forceActiveFocus(); if (!surface()) return; - QWaylandInputDevice *target = device; + QWaylandSeat *target = device; if (!target) { - target = compositor()->defaultInputDevice(); + target = compositor()->defaultSeat(); } target->setKeyboardFocus(surface()); QWaylandTextInput *textInput = QWaylandTextInput::findIn(target); @@ -898,13 +977,23 @@ void QWaylandQuickItem::setFocusOnClick(bool focus) */ bool QWaylandQuickItem::inputRegionContains(const QPointF &localPosition) { - Q_D(QWaylandQuickItem); if (QWaylandSurface *s = surface()) - return s->inputRegionContains(localPosition.toPoint() / d->scaleFactor()); + return s->inputRegionContains(mapToSurface(localPosition).toPoint()); return false; } /*! + * Maps the given \a point in this item's coordinate system to the equivalent + * point within the Wayland surface's coordinate system, and returns the mapped + * coordinate. + */ +QPointF QWaylandQuickItem::mapToSurface(const QPointF &point) const +{ + Q_D(const QWaylandQuickItem); + return point / d->scaleFactor(); +} + +/*! * \qmlproperty bool QtWaylandCompositor::WaylandQuickItem::sizeFollowsSurface * * This property specifies whether the size of the item should always match @@ -1043,9 +1132,9 @@ void QWaylandQuickItem::updateInputMethod(Qt::InputMethodQueries queries) QSGNode *QWaylandQuickItem::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *) { Q_D(QWaylandQuickItem); - const bool mapped = surface() && surface()->isMapped() && d->view->currentBuffer().hasBuffer(); + const bool hasContent = surface() && surface()->hasContent() && d->view->currentBuffer().hasBuffer(); - if (!mapped || !d->paintEnabled) { + if (!hasContent || !d->paintEnabled) { delete oldNode; return 0; } @@ -1055,7 +1144,7 @@ QSGNode *QWaylandQuickItem::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeDat const QRectF rect = invertY ? QRectF(0, height(), width(), -height()) : QRectF(0, 0, width(), height()); - if (ref.isShm() || bufferTypes[ref.bufferFormatEgl()].canProvideTexture) { + if (ref.isSharedMemory() || bufferTypes[ref.bufferFormatEgl()].canProvideTexture) { QSGSimpleTextureNode *node = static_cast<QSGSimpleTextureNode *>(oldNode); if (!node) { @@ -1138,6 +1227,8 @@ void QWaylandQuickItem::setInputEventsEnabled(bool enabled) { Q_D(QWaylandQuickItem); if (d->inputEventsEnabled != enabled) { + if (enabled) + setEnabled(true); d->setInputEventsEnabled(enabled); emit inputEventsEnabledChanged(); } @@ -1172,5 +1263,13 @@ void QWaylandQuickItem::handleSubsurfacePosition(const QPoint &pos) QQuickItem::setPosition(pos * d->scaleFactor()); } +void QWaylandQuickItem::handleDragStarted(QWaylandDrag *drag) +{ + Q_D(QWaylandQuickItem); + Q_ASSERT(drag->origin() == surface()); + drag->seat()->setMouseFocus(nullptr); + d->isDragging = true; +} + QT_END_NAMESPACE diff --git a/src/compositor/compositor_api/qwaylandquickitem.h b/src/compositor/compositor_api/qwaylandquickitem.h index 07b6a40a4..5c89d58b4 100644 --- a/src/compositor/compositor_api/qwaylandquickitem.h +++ b/src/compositor/compositor_api/qwaylandquickitem.h @@ -51,14 +51,13 @@ Q_DECLARE_METATYPE(QWaylandQuickSurface*) QT_BEGIN_NAMESPACE -class QWaylandInputDevice; +class QWaylandSeat; class QWaylandQuickItemPrivate; class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandQuickItem : public QQuickItem { Q_OBJECT Q_DECLARE_PRIVATE(QWaylandQuickItem) - Q_PROPERTY(QWaylandView *view READ view CONSTANT) Q_PROPERTY(QWaylandCompositor *compositor READ compositor) Q_PROPERTY(QWaylandSurface *surface READ surface WRITE setSurface NOTIFY surfaceChanged) Q_PROPERTY(bool paintEnabled READ paintEnabled WRITE setPaintEnabled) @@ -68,6 +67,9 @@ class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandQuickItem : public QQuickItem Q_PROPERTY(bool focusOnClick READ focusOnClick WRITE setFocusOnClick NOTIFY focusOnClickChanged) Q_PROPERTY(bool sizeFollowsSurface READ sizeFollowsSurface WRITE setSizeFollowsSurface NOTIFY sizeFollowsSurfaceChanged) Q_PROPERTY(QObject *subsurfaceHandler READ subsurfaceHandler WRITE setSubsurfaceHandler NOTIFY subsurfaceHandlerChanged) + Q_PROPERTY(QWaylandOutput *output READ output WRITE setOutput NOTIFY outputChanged) + Q_PROPERTY(bool bufferLocked READ isBufferLocked WRITE setBufferLocked NOTIFY bufferLockedChanged) + Q_PROPERTY(bool allowDiscardFrontBuffer READ allowDiscardFrontBuffer WRITE setAllowDiscardFrontBuffer NOTIFY allowDiscardFrontBufferChanged) public: QWaylandQuickItem(QQuickItem *parent = nullptr); ~QWaylandQuickItem(); @@ -95,6 +97,7 @@ public: void setFocusOnClick(bool focus); bool inputRegionContains(const QPointF &localPosition); + Q_INVOKABLE QPointF mapToSurface(const QPointF &point) const; bool sizeFollowsSurface() const; void setSizeFollowsSurface(bool sizeFollowsSurface); @@ -107,6 +110,15 @@ public: QObject *subsurfaceHandler() const; void setSubsurfaceHandler(QObject*); + QWaylandOutput *output() const; + void setOutput(QWaylandOutput *output); + + bool isBufferLocked() const; + void setBufferLocked(bool locked); + + bool allowDiscardFrontBuffer() const; + void setAllowDiscardFrontBuffer(bool discard); + protected: void mousePressEvent(QMouseEvent *event) Q_DECL_OVERRIDE; void mouseMoveEvent(QMouseEvent *event) Q_DECL_OVERRIDE; @@ -128,7 +140,7 @@ protected: virtual void surfaceChangedEvent(QWaylandSurface *newSurface, QWaylandSurface *oldSurface); public Q_SLOTS: - virtual void takeFocus(QWaylandInputDevice *device = nullptr); + virtual void takeFocus(QWaylandSeat *device = nullptr); void setPaintEnabled(bool paintEnabled); void raise(); void lower(); @@ -143,6 +155,7 @@ private Q_SLOTS: void beforeSync(); void handleSubsurfaceAdded(QWaylandSurface *childSurface); void handleSubsurfacePosition(const QPoint &pos); + void handleDragStarted(QWaylandDrag *drag); #ifndef QT_NO_IM void updateInputMethod(Qt::InputMethodQueries queries); #endif @@ -158,6 +171,9 @@ Q_SIGNALS: void mouseRelease(); void sizeFollowsSurfaceChanged(); void subsurfaceHandlerChanged(); + void outputChanged(); + void bufferLockedChanged(); + void allowDiscardFrontBufferChanged(); protected: QSGNode *updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *) Q_DECL_OVERRIDE; diff --git a/src/compositor/compositor_api/qwaylandquickitem_p.h b/src/compositor/compositor_api/qwaylandquickitem_p.h index b529ba959..8c242ac88 100644 --- a/src/compositor/compositor_api/qwaylandquickitem_p.h +++ b/src/compositor/compositor_api/qwaylandquickitem_p.h @@ -112,6 +112,7 @@ public: , paintEnabled(true) , touchEventsEnabled(false) , inputEventsEnabled(true) + , isDragging(false) , newTexture(false) , focusOnClick(true) , sizeFollowsSurface(true) @@ -138,9 +139,11 @@ public: QObject::connect(view.data(), &QWaylandView::surfaceChanged, q, &QWaylandQuickItem::surfaceChanged); QObject::connect(view.data(), &QWaylandView::surfaceChanged, q, &QWaylandQuickItem::handleSurfaceChanged); QObject::connect(view.data(), &QWaylandView::surfaceDestroyed, q, &QWaylandQuickItem::surfaceDestroyed); + QObject::connect(view.data(), &QWaylandView::outputChanged, q, &QWaylandQuickItem::outputChanged); + QObject::connect(view.data(), &QWaylandView::bufferLockedChanged, q, &QWaylandQuickItem::bufferLockedChanged); + QObject::connect(view.data(), &QWaylandView::allowDiscardFrontBufferChanged, q, &QWaylandQuickItem::allowDiscardFrontBuffer); } - void setInputEventsEnabled(bool enable) { Q_Q(QWaylandQuickItem); @@ -164,6 +167,7 @@ public: bool paintEnabled; bool touchEventsEnabled; bool inputEventsEnabled; + bool isDragging; bool newTexture; bool focusOnClick; bool sizeFollowsSurface; diff --git a/src/compositor/compositor_api/qwaylandquickoutput.cpp b/src/compositor/compositor_api/qwaylandquickoutput.cpp index 8abf6cbb1..0e25362fc 100644 --- a/src/compositor/compositor_api/qwaylandquickoutput.cpp +++ b/src/compositor/compositor_api/qwaylandquickoutput.cpp @@ -37,6 +37,7 @@ #include "qwaylandquickoutput.h" #include "qwaylandquickcompositor.h" +#include "qwaylandquickitem_p.h" QT_BEGIN_NAMESPACE @@ -102,6 +103,44 @@ void QWaylandQuickOutput::setAutomaticFrameCallback(bool automatic) automaticFrameCallbackChanged(); } +static QQuickItem* clickableItemAtPosition(QQuickItem *rootItem, const QPointF &position) +{ + if (!rootItem->isEnabled() || !rootItem->isVisible()) + return nullptr; + + QList<QQuickItem *> paintOrderItems = QQuickItemPrivate::get(rootItem)->paintOrderChildItems(); + auto negativeZStart = paintOrderItems.crend(); + for (auto it = paintOrderItems.crbegin(); it != paintOrderItems.crend(); ++it) { + if ((*it)->z() < 0) { + negativeZStart = it; + break; + } + QQuickItem *item = clickableItemAtPosition(*it, rootItem->mapToItem(*it, position)); + if (item) + return item; + } + + if (rootItem->contains(position) && rootItem->acceptedMouseButtons() != Qt::NoButton) + return rootItem; + + for (auto it = negativeZStart; it != paintOrderItems.crend(); ++it) { + QQuickItem *item = clickableItemAtPosition(*it, rootItem->mapToItem(*it, position)); + if (item) + return item; + } + + return nullptr; +} + +QQuickItem *QWaylandQuickOutput::pickClickableItem(const QPointF &position) +{ + QQuickWindow *quickWindow = qobject_cast<QQuickWindow *>(window()); + if (!quickWindow) + return nullptr; + + return clickableItemAtPosition(quickWindow->contentItem(), position); +} + /*! * \internal */ diff --git a/src/compositor/compositor_api/qwaylandquickoutput.h b/src/compositor/compositor_api/qwaylandquickoutput.h index 83091e4c7..2cef03282 100644 --- a/src/compositor/compositor_api/qwaylandquickoutput.h +++ b/src/compositor/compositor_api/qwaylandquickoutput.h @@ -59,6 +59,8 @@ public: bool automaticFrameCallback() const; void setAutomaticFrameCallback(bool automatic); + QQuickItem *pickClickableItem(const QPointF &position); + public Q_SLOTS: void updateStarted(); diff --git a/src/compositor/compositor_api/qwaylandinput.cpp b/src/compositor/compositor_api/qwaylandseat.cpp index 6f0f8c758..f84325185 100644 --- a/src/compositor/compositor_api/qwaylandinput.cpp +++ b/src/compositor/compositor_api/qwaylandseat.cpp @@ -34,8 +34,8 @@ ** ****************************************************************************/ -#include "qwaylandinput.h" -#include "qwaylandinput_p.h" +#include "qwaylandseat.h" +#include "qwaylandseat_p.h" #include "qwaylandcompositor.h" #include "qwaylandinputmethodcontrol.h" @@ -44,7 +44,7 @@ #include <QtWaylandCompositor/QWaylandTouch> #include <QtWaylandCompositor/QWaylandPointer> #include <QtWaylandCompositor/QWaylandWlShellSurface> -#include <QtWaylandCompositor/private/qwaylandinput_p.h> +#include <QtWaylandCompositor/private/qwaylandseat_p.h> #include <QtWaylandCompositor/private/qwaylandcompositor_p.h> #include <QtWaylandCompositor/private/qwldatadevice_p.h> @@ -53,7 +53,7 @@ QT_BEGIN_NAMESPACE -QWaylandInputDevicePrivate::QWaylandInputDevicePrivate(QWaylandInputDevice *inputdevice, QWaylandCompositor *compositor) +QWaylandSeatPrivate::QWaylandSeatPrivate(QWaylandSeat *seat, QWaylandCompositor *compositor) : QObjectPrivate() , QtWaylandServer::wl_seat(compositor->display(), 4) , compositor(compositor) @@ -61,29 +61,29 @@ QWaylandInputDevicePrivate::QWaylandInputDevicePrivate(QWaylandInputDevice *inpu , keyboardFocus(nullptr) , capabilities() , data_device() - , drag_handle(new QWaylandDrag(inputdevice)) + , drag_handle(new QWaylandDrag(seat)) { } -QWaylandInputDevicePrivate::~QWaylandInputDevicePrivate() +QWaylandSeatPrivate::~QWaylandSeatPrivate() { } -void QWaylandInputDevicePrivate::setCapabilities(QWaylandInputDevice::CapabilityFlags caps) +void QWaylandSeatPrivate::setCapabilities(QWaylandSeat::CapabilityFlags caps) { - Q_Q(QWaylandInputDevice); + Q_Q(QWaylandSeat); if (capabilities != caps) { - QWaylandInputDevice::CapabilityFlags changed = caps ^ capabilities; + QWaylandSeat::CapabilityFlags changed = caps ^ capabilities; - if (changed & QWaylandInputDevice::Pointer) { + if (changed & QWaylandSeat::Pointer) { pointer.reset(pointer.isNull() ? QWaylandCompositorPrivate::get(compositor)->callCreatePointerDevice(q) : 0); } - if (changed & QWaylandInputDevice::Keyboard) { + if (changed & QWaylandSeat::Keyboard) { keyboard.reset(keyboard.isNull() ? QWaylandCompositorPrivate::get(compositor)->callCreateKeyboardDevice(q) : 0); } - if (changed & QWaylandInputDevice::Touch) { + if (changed & QWaylandSeat::Touch) { touch.reset(touch.isNull() ? QWaylandCompositorPrivate::get(compositor)->callCreateTouchDevice(q) : 0); } @@ -93,45 +93,45 @@ void QWaylandInputDevicePrivate::setCapabilities(QWaylandInputDevice::Capability wl_seat::send_capabilities(resources.at(i)->handle, (uint32_t)capabilities); } - if ((changed & caps & QWaylandInputDevice::Keyboard) && keyboardFocus != nullptr) + if ((changed & caps & QWaylandSeat::Keyboard) && keyboardFocus != nullptr) keyboard->setFocus(keyboardFocus); } } -void QWaylandInputDevicePrivate::clientRequestedDataDevice(QtWayland::DataDeviceManager *, struct wl_client *client, uint32_t id) +void QWaylandSeatPrivate::clientRequestedDataDevice(QtWayland::DataDeviceManager *, struct wl_client *client, uint32_t id) { - Q_Q(QWaylandInputDevice); + Q_Q(QWaylandSeat); if (!data_device) data_device.reset(new QtWayland::DataDevice(q)); data_device->add(client, id, 1); } -void QWaylandInputDevicePrivate::seat_destroy_resource(wl_seat::Resource *) +void QWaylandSeatPrivate::seat_destroy_resource(wl_seat::Resource *) { // cleanupDataDeviceForClient(resource->client(), true); } -void QWaylandInputDevicePrivate::seat_bind_resource(wl_seat::Resource *resource) +void QWaylandSeatPrivate::seat_bind_resource(wl_seat::Resource *resource) { // The order of capabilities matches the order defined in the wayland protocol wl_seat::send_capabilities(resource->handle, (uint32_t)capabilities); } -void QWaylandInputDevicePrivate::seat_get_pointer(wl_seat::Resource *resource, uint32_t id) +void QWaylandSeatPrivate::seat_get_pointer(wl_seat::Resource *resource, uint32_t id) { if (!pointer.isNull()) { pointer->addClient(QWaylandClient::fromWlClient(compositor, resource->client()), id, resource->version()); } } -void QWaylandInputDevicePrivate::seat_get_keyboard(wl_seat::Resource *resource, uint32_t id) +void QWaylandSeatPrivate::seat_get_keyboard(wl_seat::Resource *resource, uint32_t id) { if (!keyboard.isNull()) { keyboard->addClient(QWaylandClient::fromWlClient(compositor, resource->client()), id, resource->version()); } } -void QWaylandInputDevicePrivate::seat_get_touch(wl_seat::Resource *resource, uint32_t id) +void QWaylandSeatPrivate::seat_get_touch(wl_seat::Resource *resource, uint32_t id) { if (!touch.isNull()) { touch->addClient(QWaylandClient::fromWlClient(compositor, resource->client()), id, resource->version()); @@ -149,56 +149,56 @@ QWaylandKeymap::QWaylandKeymap(const QString &layout, const QString &variant, co /*! - * \class QWaylandInputDevice + * \class QWaylandSeat * \inmodule QtWaylandCompositor * \preliminary - * \brief The QWaylandInputDevice class provides access to keyboard, mouse, and touch input. + * \brief The QWaylandSeat class provides access to keyboard, mouse, and touch input. * - * The QWaylandInputDevice provides access to different types of user input and maintains + * The QWaylandSeat provides access to different types of user input and maintains * a keyboard focus and a mouse pointer. It corresponds to the wl_seat interface in the Wayland protocol. */ /*! - * \enum QWaylandInputDevice::CapabilityFlag + * \enum QWaylandSeat::CapabilityFlag * - * This enum type describes the capabilities of a QWaylandInputDevice. + * This enum type describes the capabilities of a QWaylandSeat. * - * \value Pointer The QWaylandInputDevice supports pointer input. - * \value Keyboard The QWaylandInputDevice supports keyboard input. - * \value Touch The QWaylandInputDevice supports touch input. + * \value Pointer The QWaylandSeat supports pointer input. + * \value Keyboard The QWaylandSeat supports keyboard input. + * \value Touch The QWaylandSeat supports touch input. */ /*! - * Constructs a QWaylandInputDevice for the given \a compositor and with the given \a capabilityFlags. + * Constructs a QWaylandSeat for the given \a compositor and with the given \a capabilityFlags. */ -QWaylandInputDevice::QWaylandInputDevice(QWaylandCompositor *compositor, CapabilityFlags capabilityFlags) - : QWaylandObject(*new QWaylandInputDevicePrivate(this,compositor)) +QWaylandSeat::QWaylandSeat(QWaylandCompositor *compositor, CapabilityFlags capabilityFlags) + : QWaylandObject(*new QWaylandSeatPrivate(this,compositor)) { d_func()->setCapabilities(capabilityFlags); } /*! - * Destroys the QWaylandInputDevice + * Destroys the QWaylandSeat */ -QWaylandInputDevice::~QWaylandInputDevice() +QWaylandSeat::~QWaylandSeat() { } /*! - * Sends a mouse press event for \a button to the QWaylandInputDevice's pointer device. + * Sends a mouse press event for \a button to the QWaylandSeat's pointer device. */ -void QWaylandInputDevice::sendMousePressEvent(Qt::MouseButton button) +void QWaylandSeat::sendMousePressEvent(Qt::MouseButton button) { - Q_D(QWaylandInputDevice); + Q_D(QWaylandSeat); d->pointer->sendMousePressEvent(button); } /*! - * Sends a mouse release event for \a button to the QWaylandInputDevice's pointer device. + * Sends a mouse release event for \a button to the QWaylandSeat's pointer device. */ -void QWaylandInputDevice::sendMouseReleaseEvent(Qt::MouseButton button) +void QWaylandSeat::sendMouseReleaseEvent(Qt::MouseButton button) { - Q_D(QWaylandInputDevice); + Q_D(QWaylandSeat); d->pointer->sendMouseReleaseEvent(button); } @@ -206,36 +206,36 @@ void QWaylandInputDevice::sendMouseReleaseEvent(Qt::MouseButton button) * Sets the mouse focus to \a view and sends a mouse move event to the pointer device with the * local position \a localPos and output space position \a outputSpacePos. **/ -void QWaylandInputDevice::sendMouseMoveEvent(QWaylandView *view, const QPointF &localPos, const QPointF &outputSpacePos) +void QWaylandSeat::sendMouseMoveEvent(QWaylandView *view, const QPointF &localPos, const QPointF &outputSpacePos) { - Q_D(QWaylandInputDevice); + Q_D(QWaylandSeat); d->pointer->sendMouseMoveEvent(view, localPos, outputSpacePos); } /*! - * Sends a mouse wheel event to the QWaylandInputDevice's pointer device with the given \a orientation and \a delta. + * Sends a mouse wheel event to the QWaylandSeat's pointer device with the given \a orientation and \a delta. */ -void QWaylandInputDevice::sendMouseWheelEvent(Qt::Orientation orientation, int delta) +void QWaylandSeat::sendMouseWheelEvent(Qt::Orientation orientation, int delta) { - Q_D(QWaylandInputDevice); + Q_D(QWaylandSeat); d->pointer->sendMouseWheelEvent(orientation, delta); } /*! * Sends a key press event with the key \a code to the keyboard device. */ -void QWaylandInputDevice::sendKeyPressEvent(uint code) +void QWaylandSeat::sendKeyPressEvent(uint code) { - Q_D(QWaylandInputDevice); + Q_D(QWaylandSeat); d->keyboard->sendKeyPressEvent(code); } /*! * Sends a key release event with the key \a code to the keyboard device. */ -void QWaylandInputDevice::sendKeyReleaseEvent(uint code) +void QWaylandSeat::sendKeyReleaseEvent(uint code) { - Q_D(QWaylandInputDevice); + Q_D(QWaylandSeat); d->keyboard->sendKeyReleaseEvent(code); } @@ -243,9 +243,9 @@ void QWaylandInputDevice::sendKeyReleaseEvent(uint code) * Sends a touch point event with the given \a id and \a state to the touch device. The position * of the touch point is given by \a point. */ -void QWaylandInputDevice::sendTouchPointEvent(int id, const QPointF &point, Qt::TouchPointState state) +void QWaylandSeat::sendTouchPointEvent(int id, const QPointF &point, Qt::TouchPointState state) { - Q_D(QWaylandInputDevice); + Q_D(QWaylandSeat); if (d->touch.isNull()) { return; } @@ -255,9 +255,9 @@ void QWaylandInputDevice::sendTouchPointEvent(int id, const QPointF &point, Qt:: /*! * Sends a frame event to the touch device. */ -void QWaylandInputDevice::sendTouchFrameEvent() +void QWaylandSeat::sendTouchFrameEvent() { - Q_D(QWaylandInputDevice); + Q_D(QWaylandSeat); if (!d->touch.isNull()) { d->touch->sendFrameEvent(); } @@ -266,9 +266,9 @@ void QWaylandInputDevice::sendTouchFrameEvent() /*! * Sends a cancel event to the touch device. */ -void QWaylandInputDevice::sendTouchCancelEvent() +void QWaylandSeat::sendTouchCancelEvent() { - Q_D(QWaylandInputDevice); + Q_D(QWaylandSeat); if (!d->touch.isNull()) { d->touch->sendCancelEvent(); } @@ -277,9 +277,9 @@ void QWaylandInputDevice::sendTouchCancelEvent() /*! * Sends the \a event to the touch device. */ -void QWaylandInputDevice::sendFullTouchEvent(QTouchEvent *event) +void QWaylandSeat::sendFullTouchEvent(QTouchEvent *event) { - Q_D(QWaylandInputDevice); + Q_D(QWaylandSeat); if (!mouseFocus()) { qWarning("Cannot send touch event, no pointer focus, fix the compositor"); return; @@ -294,9 +294,9 @@ void QWaylandInputDevice::sendFullTouchEvent(QTouchEvent *event) /*! * Sends the \a event to the keyboard device. */ -void QWaylandInputDevice::sendFullKeyEvent(QKeyEvent *event) +void QWaylandSeat::sendFullKeyEvent(QKeyEvent *event) { - Q_D(QWaylandInputDevice); + Q_D(QWaylandSeat); if (!keyboardFocus()) { qWarning("Cannot send key event, no keyboard focus, fix the compositor"); @@ -327,18 +327,18 @@ void QWaylandInputDevice::sendFullKeyEvent(QKeyEvent *event) /*! * Returns the keyboard for this input device. */ -QWaylandKeyboard *QWaylandInputDevice::keyboard() const +QWaylandKeyboard *QWaylandSeat::keyboard() const { - Q_D(const QWaylandInputDevice); + Q_D(const QWaylandSeat); return d->keyboard.data(); } /*! * Returns the current focused surface for keyboard input. */ -QWaylandSurface *QWaylandInputDevice::keyboardFocus() const +QWaylandSurface *QWaylandSeat::keyboardFocus() const { - Q_D(const QWaylandInputDevice); + Q_D(const QWaylandSeat); if (d->keyboard.isNull() || !d->keyboard->focus()) return Q_NULLPTR; @@ -348,9 +348,9 @@ QWaylandSurface *QWaylandInputDevice::keyboardFocus() const /*! * Sets the current keyboard focus to \a surface. */ -bool QWaylandInputDevice::setKeyboardFocus(QWaylandSurface *surface) +bool QWaylandSeat::setKeyboardFocus(QWaylandSurface *surface) { - Q_D(QWaylandInputDevice); + Q_D(QWaylandSeat); if (surface && surface->isDestroyed()) return false; @@ -372,47 +372,47 @@ bool QWaylandInputDevice::setKeyboardFocus(QWaylandSurface *surface) } /*! - * Sets the key map of this QWaylandInputDevice to \a keymap. + * Sets the key map of this QWaylandSeat to \a keymap. */ -void QWaylandInputDevice::setKeymap(const QWaylandKeymap &keymap) +void QWaylandSeat::setKeymap(const QWaylandKeymap &keymap) { if (keyboard()) keyboard()->setKeymap(keymap); } /*! - * Returns the pointer device for this QWaylandInputDevice. + * Returns the pointer device for this QWaylandSeat. */ -QWaylandPointer *QWaylandInputDevice::pointer() const +QWaylandPointer *QWaylandSeat::pointer() const { - Q_D(const QWaylandInputDevice); + Q_D(const QWaylandSeat); return d->pointer.data(); } /*! - * Returns the touch device for this QWaylandInputDevice. + * Returns the touch device for this QWaylandSeat. */ -QWaylandTouch *QWaylandInputDevice::touch() const +QWaylandTouch *QWaylandSeat::touch() const { - Q_D(const QWaylandInputDevice); + Q_D(const QWaylandSeat); return d->touch.data(); } /*! * Returns the view that currently has mouse focus. */ -QWaylandView *QWaylandInputDevice::mouseFocus() const +QWaylandView *QWaylandSeat::mouseFocus() const { - Q_D(const QWaylandInputDevice); + Q_D(const QWaylandSeat); return d->mouseFocus; } /*! * Sets the current mouse focus to \a view. */ -void QWaylandInputDevice::setMouseFocus(QWaylandView *view) +void QWaylandSeat::setMouseFocus(QWaylandView *view) { - Q_D(QWaylandInputDevice); + Q_D(QWaylandSeat); if (view == d->mouseFocus) return; @@ -422,52 +422,52 @@ void QWaylandInputDevice::setMouseFocus(QWaylandView *view) } /*! - * Returns the compositor for this QWaylandInputDevice. + * Returns the compositor for this QWaylandSeat. */ -QWaylandCompositor *QWaylandInputDevice::compositor() const +QWaylandCompositor *QWaylandSeat::compositor() const { - Q_D(const QWaylandInputDevice); + Q_D(const QWaylandSeat); return d->compositor; } /*! - * Returns the drag object for this QWaylandInputDevice. + * Returns the drag object for this QWaylandSeat. */ -QWaylandDrag *QWaylandInputDevice::drag() const +QWaylandDrag *QWaylandSeat::drag() const { - Q_D(const QWaylandInputDevice); + Q_D(const QWaylandSeat); return d->drag_handle.data(); } /*! - * Returns the capability flags for this QWaylandInputDevice. + * Returns the capability flags for this QWaylandSeat. */ -QWaylandInputDevice::CapabilityFlags QWaylandInputDevice::capabilities() const +QWaylandSeat::CapabilityFlags QWaylandSeat::capabilities() const { - Q_D(const QWaylandInputDevice); + Q_D(const QWaylandSeat); return d->capabilities; } /*! * \internal */ -bool QWaylandInputDevice::isOwner(QInputEvent *inputEvent) const +bool QWaylandSeat::isOwner(QInputEvent *inputEvent) const { Q_UNUSED(inputEvent); return true; } /*! - * Returns the QWaylandInputDevice corresponding to the \a resource. The \a resource is expected + * Returns the QWaylandSeat corresponding to the \a resource. The \a resource is expected * to have the type wl_seat. */ -QWaylandInputDevice *QWaylandInputDevice::fromSeatResource(struct ::wl_resource *resource) +QWaylandSeat *QWaylandSeat::fromSeatResource(struct ::wl_resource *resource) { - return static_cast<QWaylandInputDevicePrivate *>(QWaylandInputDevicePrivate::Resource::fromResource(resource)->seat_object)->q_func(); + return static_cast<QWaylandSeatPrivate *>(QWaylandSeatPrivate::Resource::fromResource(resource)->seat_object)->q_func(); } /*! - * \fn void QWaylandInputDevice::mouseFocusChanged(QWaylandView *newFocus, QWaylandView *oldFocus) + * \fn void QWaylandSeat::mouseFocusChanged(QWaylandView *newFocus, QWaylandView *oldFocus) * * This signal is emitted when the mouse focus has changed from \a oldFocus to \a newFocus. */ diff --git a/src/compositor/compositor_api/qwaylandinput.h b/src/compositor/compositor_api/qwaylandseat.h index d1cb922b7..bfd6e4041 100644 --- a/src/compositor/compositor_api/qwaylandinput.h +++ b/src/compositor/compositor_api/qwaylandseat.h @@ -34,8 +34,8 @@ ** ****************************************************************************/ -#ifndef QWAYLANDINPUT_H -#define QWAYLANDINPUT_H +#ifndef QWAYLANDSEAT_H +#define QWAYLANDSEAT_H #include <QtCore/qnamespace.h> #include <QtCore/QPoint> @@ -53,20 +53,18 @@ class QKeyEvent; class QTouchEvent; class QWaylandView; class QInputEvent; -class QWaylandInputDevicePrivate; +class QWaylandSeatPrivate; class QWaylandDrag; class QWaylandKeyboard; class QWaylandPointer; class QWaylandTouch; -namespace QtWayland { -class InputDevice; -} - -class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandInputDevice : public QWaylandObject +class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandSeat : public QWaylandObject { Q_OBJECT - Q_DECLARE_PRIVATE(QWaylandInputDevice) + Q_DECLARE_PRIVATE(QWaylandSeat) + + Q_PROPERTY(QWaylandDrag *drag READ drag CONSTANT) public: enum CapabilityFlag { // The order should match the enum WL_SEAT_CAPABILITY_* @@ -79,8 +77,8 @@ public: Q_DECLARE_FLAGS(CapabilityFlags, CapabilityFlag) Q_ENUM(CapabilityFlags) - QWaylandInputDevice(QWaylandCompositor *compositor, CapabilityFlags capabilityFlags = DefaultCapabilities); - virtual ~QWaylandInputDevice(); + QWaylandSeat(QWaylandCompositor *compositor, CapabilityFlags capabilityFlags = DefaultCapabilities); + virtual ~QWaylandSeat(); void sendMousePressEvent(Qt::MouseButton button); void sendMouseReleaseEvent(Qt::MouseButton button); @@ -116,11 +114,11 @@ public: QWaylandDrag *drag() const; - QWaylandInputDevice::CapabilityFlags capabilities() const; + QWaylandSeat::CapabilityFlags capabilities() const; virtual bool isOwner(QInputEvent *inputEvent) const; - static QWaylandInputDevice *fromSeatResource(struct ::wl_resource *resource); + static QWaylandSeat *fromSeatResource(struct ::wl_resource *resource); Q_SIGNALS: void mouseFocusChanged(QWaylandView *newFocus, QWaylandView *oldFocus); @@ -128,8 +126,8 @@ Q_SIGNALS: void cursorSurfaceRequest(QWaylandSurface *surface, int hotspotX, int hotspotY); }; -Q_DECLARE_OPERATORS_FOR_FLAGS(QWaylandInputDevice::CapabilityFlags) +Q_DECLARE_OPERATORS_FOR_FLAGS(QWaylandSeat::CapabilityFlags) QT_END_NAMESPACE -#endif // QWAYLANDINPUT_H +#endif // QWAYLANDSEAT_H diff --git a/src/compositor/compositor_api/qwaylandinput_p.h b/src/compositor/compositor_api/qwaylandseat_p.h index 5e57c43cc..6588600cf 100644 --- a/src/compositor/compositor_api/qwaylandinput_p.h +++ b/src/compositor/compositor_api/qwaylandseat_p.h @@ -34,8 +34,8 @@ ** ****************************************************************************/ -#ifndef QWAYLANDINPUT_P_H -#define QWAYLANDINPUT_P_H +#ifndef QWAYLANDSEAT_P_H +#define QWAYLANDSEAT_P_H // // W A R N I N G @@ -51,7 +51,7 @@ #include <stdint.h> #include <QtWaylandCompositor/qwaylandexport.h> -#include <QtWaylandCompositor/qwaylandinput.h> +#include <QtWaylandCompositor/qwaylandseat.h> #include <QtCore/QList> #include <QtCore/QPoint> @@ -68,7 +68,7 @@ QT_BEGIN_NAMESPACE class QKeyEvent; class QTouchEvent; -class QWaylandInputDevice; +class QWaylandSeat; class QWaylandDrag; class QWaylandView; @@ -85,18 +85,18 @@ class InputMethod; } -class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandInputDevicePrivate : public QObjectPrivate, public QtWaylandServer::wl_seat +class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandSeatPrivate : public QObjectPrivate, public QtWaylandServer::wl_seat { public: - Q_DECLARE_PUBLIC(QWaylandInputDevice) + Q_DECLARE_PUBLIC(QWaylandSeat) - QWaylandInputDevicePrivate(QWaylandInputDevice *device, QWaylandCompositor *compositor); - ~QWaylandInputDevicePrivate(); + QWaylandSeatPrivate(QWaylandSeat *seat, QWaylandCompositor *compositor); + ~QWaylandSeatPrivate(); void clientRequestedDataDevice(QtWayland::DataDeviceManager *dndSelection, struct wl_client *client, uint32_t id); - void setCapabilities(QWaylandInputDevice::CapabilityFlags caps); + void setCapabilities(QWaylandSeat::CapabilityFlags caps); - static QWaylandInputDevicePrivate *get(QWaylandInputDevice *device) { return device->d_func(); } + static QWaylandSeatPrivate *get(QWaylandSeat *device) { return device->d_func(); } QtWayland::DataDevice *dataDevice() const { return data_device.data(); } @@ -116,7 +116,7 @@ private: QWaylandCompositor *compositor; QWaylandView *mouseFocus; QWaylandSurface *keyboardFocus; - QWaylandInputDevice::CapabilityFlags capabilities; + QWaylandSeat::CapabilityFlags capabilities; QScopedPointer<QWaylandPointer> pointer; QScopedPointer<QWaylandKeyboard> keyboard; @@ -128,4 +128,4 @@ private: QT_END_NAMESPACE -#endif // QWAYLANDINPUT_P_H +#endif // QWAYLANDSEAT_P_H diff --git a/src/compositor/compositor_api/qwaylandsurface.cpp b/src/compositor/compositor_api/qwaylandsurface.cpp index edb34e0bd..ea94433bb 100644 --- a/src/compositor/compositor_api/qwaylandsurface.cpp +++ b/src/compositor/compositor_api/qwaylandsurface.cpp @@ -52,7 +52,7 @@ #include <QtWaylandCompositor/private/qwaylandcompositor_p.h> #include <QtWaylandCompositor/private/qwaylandview_p.h> -#include <QtWaylandCompositor/private/qwaylandinput_p.h> +#include <QtWaylandCompositor/private/qwaylandseat_p.h> #include <QtCore/private/qobject_p.h> @@ -129,7 +129,7 @@ QWaylandSurfacePrivate::QWaylandSurfacePrivate() , bufferScale(1) , isCursorSurface(false) , destroyed(false) - , mapped(false) + , hasContent(false) , isInitialized(false) , contentOrientation(Qt::PrimaryOrientation) , inputMethodControl(Q_NULLPTR) @@ -193,9 +193,9 @@ void QWaylandSurfacePrivate::notifyViewsAboutDestruction() foreach (QWaylandView *view, views) { QWaylandViewPrivate::get(view)->markSurfaceAsDestroyed(q); } - if (mapped) { - mapped = false; - emit q->mappedChanged(); + if (hasContent) { + hasContent = false; + emit q->hasContentChanged(); } } @@ -342,10 +342,10 @@ void QWaylandSurfacePrivate::setBackBuffer(QtWayland::SurfaceBuffer *b, const QR emit q->damaged(damage); - bool oldMapped = mapped; - mapped = QtWayland::SurfaceBuffer::hasContent(buffer); - if (oldMapped != mapped) - emit q->mappedChanged(); + bool oldHasContent = hasContent; + hasContent = QtWayland::SurfaceBuffer::hasContent(buffer); + if (oldHasContent != hasContent) + emit q->hasContentChanged(); if (!pending.offset.isNull()) emit q->offsetForNextFrame(pending.offset); @@ -484,20 +484,20 @@ QWaylandClient *QWaylandSurface::client() const } /*! - * \qmlproperty bool QtWaylandCompositor::WaylandSurface::isMapped + * \qmlproperty bool QtWaylandCompositor::WaylandSurface::hasContent * * This property holds whether the WaylandSurface has content. */ /*! - * \property QWaylandSurface::isMapped + * \property QWaylandSurface::hasContent * * This property holds whether the QWaylandSurface has content. */ -bool QWaylandSurface::isMapped() const +bool QWaylandSurface::hasContent() const { Q_D(const QWaylandSurface); - return d->mapped; + return d->hasContent; } /*! @@ -708,9 +708,9 @@ QWaylandInputMethodControl *QWaylandSurface::inputMethodControl() const void QWaylandSurface::updateSelection() { Q_D(QWaylandSurface); - QWaylandInputDevice *inputDevice = d->compositor->defaultInputDevice(); - if (inputDevice) { - const QtWayland::DataDevice *dataDevice = QWaylandInputDevicePrivate::get(inputDevice)->dataDevice(); + QWaylandSeat *seat = d->compositor->defaultSeat(); + if (seat) { + const QtWayland::DataDevice *dataDevice = QWaylandSeatPrivate::get(seat)->dataDevice(); if (dataDevice) { QWaylandCompositorPrivate::get(d->compositor)->dataDeviceManager()->offerRetainedSelection( dataDevice->resourceMap().value(d->resource()->client())->handle); @@ -894,4 +894,16 @@ void QWaylandSurfacePrivate::Subsurface::subsurface_set_desync(wl_subsurface::Re qDebug() << Q_FUNC_INFO; } +/*! + * \qmlsignal void QtWaylandCompositor::WaylandSurface::dragStarted(object drag) + * + * This signal is emitted when a drag has started from this surface. + */ + +/*! + * \fn void QWaylandSurface::dragStarted(QWaylandDrag *drag) + * + * This signal is emitted when a drag has started from this surface. + */ + QT_END_NAMESPACE diff --git a/src/compositor/compositor_api/qwaylandsurface.h b/src/compositor/compositor_api/qwaylandsurface.h index 816b5c987..ed358fefa 100644 --- a/src/compositor/compositor_api/qwaylandsurface.h +++ b/src/compositor/compositor_api/qwaylandsurface.h @@ -60,6 +60,7 @@ class QWaylandBufferRef; class QWaylandView; class QWaylandSurfaceOp; class QWaylandInputMethodControl; +class QWaylandDrag; class QWaylandSurfaceRole { @@ -81,7 +82,7 @@ class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandSurface : public QWaylandObject Q_PROPERTY(int bufferScale READ bufferScale NOTIFY bufferScaleChanged) Q_PROPERTY(Qt::ScreenOrientation contentOrientation READ contentOrientation NOTIFY contentOrientationChanged) Q_PROPERTY(QWaylandSurface::Origin origin READ origin NOTIFY originChanged) - Q_PROPERTY(bool isMapped READ isMapped NOTIFY mappedChanged) + Q_PROPERTY(bool hasContent READ hasContent NOTIFY hasContentChanged) Q_PROPERTY(bool cursorSurface READ isCursorSurface WRITE markAsCursorSurface) public: @@ -104,7 +105,7 @@ public: bool setRole(QWaylandSurfaceRole *role, wl_resource *errorResource, uint32_t errorCode); QWaylandSurfaceRole *role() const; - bool isMapped() const; + bool hasContent() const; QSize size() const; int bufferScale() const; @@ -143,7 +144,7 @@ protected: QWaylandSurface(QWaylandSurfacePrivate &dptr); Q_SIGNALS: - void mappedChanged(); + void hasContentChanged(); void damaged(const QRegion &rect); void parentChanged(QWaylandSurface *newParent, QWaylandSurface *oldParent); void childAdded(QWaylandSurface *child); @@ -156,6 +157,7 @@ Q_SIGNALS: void subsurfacePositionChanged(const QPoint &position); void subsurfacePlaceAbove(QWaylandSurface *sibling); void subsurfacePlaceBelow(QWaylandSurface *sibling); + void dragStarted(QWaylandDrag *drag); void configure(bool hasBuffer); void redraw(); diff --git a/src/compositor/compositor_api/qwaylandsurface_p.h b/src/compositor/compositor_api/qwaylandsurface_p.h index e37179cc6..0596b61ba 100644 --- a/src/compositor/compositor_api/qwaylandsurface_p.h +++ b/src/compositor/compositor_api/qwaylandsurface_p.h @@ -171,7 +171,7 @@ public: //member variables int bufferScale; bool isCursorSurface; bool destroyed; - bool mapped; + bool hasContent; bool isInitialized; Qt::ScreenOrientation contentOrientation; QWindow::Visibility visibility; diff --git a/src/compositor/compositor_api/qwaylandsurfacegrabber.cpp b/src/compositor/compositor_api/qwaylandsurfacegrabber.cpp index d415642c4..f751a3d96 100644 --- a/src/compositor/compositor_api/qwaylandsurfacegrabber.cpp +++ b/src/compositor/compositor_api/qwaylandsurfacegrabber.cpp @@ -51,7 +51,8 @@ QT_BEGIN_NAMESPACE Sometimes it is needed to get the contents of a surface, for example to provide a screenshot to the user. The QWaylandSurfaceGrabber class provides a simple method to do so, without - having to care what type of buffer backs the surface, be it SHM, OpenGL or something else. + having to care what type of buffer backs the surface, be it shared memory, OpenGL or something + else. */ /*! diff --git a/src/compositor/compositor_api/qwaylandtouch.cpp b/src/compositor/compositor_api/qwaylandtouch.cpp index a9b44527e..c07809e71 100644 --- a/src/compositor/compositor_api/qwaylandtouch.cpp +++ b/src/compositor/compositor_api/qwaylandtouch.cpp @@ -38,7 +38,7 @@ #include "qwaylandtouch_p.h" #include <QtWaylandCompositor/QWaylandCompositor> -#include <QtWaylandCompositor/QWaylandInputDevice> +#include <QtWaylandCompositor/QWaylandSeat> #include <QtWaylandCompositor/QWaylandView> #include <QtWaylandCompositor/QWaylandClient> @@ -46,7 +46,7 @@ QT_BEGIN_NAMESPACE -QWaylandTouchPrivate::QWaylandTouchPrivate(QWaylandTouch *touch, QWaylandInputDevice *seat) +QWaylandTouchPrivate::QWaylandTouchPrivate(QWaylandTouch *touch, QWaylandSeat *seat) : wl_touch() , seat(seat) , focusResource() @@ -80,12 +80,12 @@ void QWaylandTouchPrivate::touch_release(Resource *resource) void QWaylandTouchPrivate::sendDown(uint32_t time, int touch_id, const QPointF &position) { Q_Q(QWaylandTouch); - if (!focusResource || !q->mouseFocus()) + if (!focusResource || !seat->mouseFocus()) return; uint32_t serial = q->compositor()->nextSerial(); - wl_touch_send_down(focusResource->handle, serial, time, q->mouseFocus()->surfaceResource(), touch_id, + wl_touch_send_down(focusResource->handle, serial, time, seat->mouseFocus()->surfaceResource(), touch_id, wl_fixed_from_double(position.x()), wl_fixed_from_double(position.y())); } @@ -113,15 +113,15 @@ void QWaylandTouchPrivate::sendMotion(uint32_t time, int touch_id, const QPointF * \preliminary * \brief The QWaylandTouch class provides access to a touch device. * - * This class provides access to the touch device in a QWaylandInputDevice. It corresponds to + * This class provides access to the touch device in a QWaylandSeat. It corresponds to * the Wayland interface wl_touch. */ /*! - * Constructs a QWaylandTouch for the \a inputDevice and with the given \a parent. + * Constructs a QWaylandTouch for the \a seat and with the given \a parent. */ -QWaylandTouch::QWaylandTouch(QWaylandInputDevice *inputDevice, QObject *parent) - : QWaylandObject(*new QWaylandTouchPrivate(this, inputDevice), parent) +QWaylandTouch::QWaylandTouch(QWaylandSeat *seat, QObject *parent) + : QWaylandObject(*new QWaylandTouchPrivate(this, seat), parent) { connect(&d_func()->focusDestroyListener, &QWaylandDestroyListener::fired, this, &QWaylandTouch::focusDestroyed); } @@ -129,7 +129,7 @@ QWaylandTouch::QWaylandTouch(QWaylandInputDevice *inputDevice, QObject *parent) /*! * Returns the input device for this QWaylandTouch. */ -QWaylandInputDevice *QWaylandTouch::inputDevice() const +QWaylandSeat *QWaylandTouch::seat() const { Q_D(const QWaylandTouch); return d->seat; @@ -147,9 +147,6 @@ QWaylandCompositor *QWaylandTouch::compositor() const /*! * Sends a touch point event for the touch device with the given \a id, * \a position, and \a state. - * - * - * \sa mouseFocus() */ void QWaylandTouch::sendTouchPointEvent(int id, const QPointF &position, Qt::TouchPointState state) { @@ -246,15 +243,6 @@ struct wl_resource *QWaylandTouch::focusResource() const } /*! - * Returns the view currently holding mouse focus in the input device. - */ -QWaylandView *QWaylandTouch::mouseFocus() const -{ - Q_D(const QWaylandTouch); - return d->seat->mouseFocus(); -} - -/*! * \internal */ void QWaylandTouch::focusDestroyed(void *data) diff --git a/src/compositor/compositor_api/qwaylandtouch.h b/src/compositor/compositor_api/qwaylandtouch.h index b6c40ea96..c058d42ae 100644 --- a/src/compositor/compositor_api/qwaylandtouch.h +++ b/src/compositor/compositor_api/qwaylandtouch.h @@ -48,7 +48,7 @@ QT_BEGIN_NAMESPACE class QWaylandTouch; class QWaylandTouchPrivate; -class QWaylandInputDevice; +class QWaylandSeat; class QWaylandView; class QWaylandClient; @@ -57,9 +57,9 @@ class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandTouch : public QWaylandObject Q_OBJECT Q_DECLARE_PRIVATE(QWaylandTouch) public: - QWaylandTouch(QWaylandInputDevice *inputDevice, QObject *parent = nullptr); + QWaylandTouch(QWaylandSeat *seat, QObject *parent = nullptr); - QWaylandInputDevice *inputDevice() const; + QWaylandSeat *seat() const; QWaylandCompositor *compositor() const; virtual void sendTouchPointEvent(int id, const QPointF &position, Qt::TouchPointState state); @@ -72,7 +72,6 @@ public: wl_resource *focusResource() const; - QWaylandView *mouseFocus() const; private: void focusDestroyed(void *data); void mouseFocusChanged(QWaylandView *newFocus, QWaylandView *oldFocus); diff --git a/src/compositor/compositor_api/qwaylandtouch_p.h b/src/compositor/compositor_api/qwaylandtouch_p.h index ea334eea1..2f60076a7 100644 --- a/src/compositor/compositor_api/qwaylandtouch_p.h +++ b/src/compositor/compositor_api/qwaylandtouch_p.h @@ -52,7 +52,7 @@ #include <QtWaylandCompositor/qwaylandexport.h> #include <QtWaylandCompositor/QWaylandDestroyListener> #include <QtWaylandCompositor/QWaylandTouch> -#include <QtWaylandCompositor/QWaylandInputDevice> +#include <QtWaylandCompositor/QWaylandSeat> #include <QtWaylandCompositor/QWaylandView> #include <QtWaylandCompositor/QWaylandCompositor> @@ -67,7 +67,7 @@ class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandTouchPrivate : public QObjectPrivate, { Q_DECLARE_PUBLIC(QWaylandTouch) public: - explicit QWaylandTouchPrivate(QWaylandTouch *touch, QWaylandInputDevice *seat); + explicit QWaylandTouchPrivate(QWaylandTouch *touch, QWaylandSeat *seat); QWaylandCompositor *compositor() const { return seat->compositor(); } @@ -92,7 +92,7 @@ private: void touch_destroy_resource(Resource *resource) Q_DECL_OVERRIDE; void touch_release(Resource *resource) Q_DECL_OVERRIDE; - QWaylandInputDevice *seat; + QWaylandSeat *seat; Resource *focusResource; QWaylandDestroyListener focusDestroyListener; diff --git a/src/compositor/compositor_api/qwaylandview.cpp b/src/compositor/compositor_api/qwaylandview.cpp index 12b67bf5d..1f32bb61d 100644 --- a/src/compositor/compositor_api/qwaylandview.cpp +++ b/src/compositor/compositor_api/qwaylandview.cpp @@ -37,7 +37,7 @@ #include "qwaylandview.h" #include "qwaylandview_p.h" #include "qwaylandsurface.h" -#include <QtWaylandCompositor/QWaylandInputDevice> +#include <QtWaylandCompositor/QWaylandSeat> #include <QtWaylandCompositor/QWaylandCompositor> #include <QtWaylandCompositor/private/qwaylandsurface_p.h> @@ -96,7 +96,7 @@ QWaylandView::~QWaylandView() if (d->surface) { if (d->output) QWaylandOutputPrivate::get(d->output)->removeView(this, d->surface); - QWaylandInputDevice *i = d->surface->compositor()->defaultInputDevice(); + QWaylandSeat *i = d->surface->compositor()->defaultSeat(); if (i->mouseFocus() == this) i->setMouseFocus(Q_NULLPTR); @@ -145,7 +145,7 @@ void QWaylandView::setSurface(QWaylandSurface *newSurface) d->surface = newSurface; - if (!d->bufferLock) { + if (!d->bufferLocked) { d->currentBuffer = QWaylandBufferRef(); d->currentDamage = QRegion(); } @@ -216,7 +216,7 @@ void QWaylandView::attach(const QWaylandBufferRef &ref, const QRegion &damage) * * If this view is set as the surface's throttling view, discardCurrentBuffer() * is called on all views of the same surface for which the - * \l{QWaylandView::discardFrontBuffers}{discardFrontBuffers} + * \l{QWaylandView::allowDiscardFrontBuffer}{allowDiscardFrontBuffer} * property is set to true and the current buffer is the same as the * throttling view's current buffer. * @@ -231,12 +231,12 @@ bool QWaylandView::advance() if (d->currentBuffer == d->nextBuffer && !d->forceAdvanceSucceed) return false; - if (d->bufferLock) + if (d->bufferLocked) return false; if (d->surface && d->surface->throttlingView() == this) { Q_FOREACH (QWaylandView *view, d->surface->views()) { - if (view != this && view->discardFrontBuffers() && view->d_func()->currentBuffer == d->currentBuffer) + if (view != this && view->allowDiscardFrontBuffer() && view->d_func()->currentBuffer == d->currentBuffer) view->discardCurrentBuffer(); } } @@ -280,7 +280,7 @@ QRegion QWaylandView::currentDamage() } /*! - * \qmlproperty bool QtWaylandCompositor::WaylandView::bufferLock + * \qmlproperty bool QtWaylandCompositor::WaylandView::bufferLocked * * This property holds whether the view's buffer is currently locked. When * the buffer is locked, advance() will not advance to the next buffer and @@ -290,7 +290,7 @@ QRegion QWaylandView::currentDamage() */ /*! - * \property QWaylandView::bufferLock + * \property QWaylandView::bufferLocked * * This property holds whether the view's buffer is currently locked. When * the buffer is locked, advance() will not advance to the next buffer @@ -301,42 +301,43 @@ QRegion QWaylandView::currentDamage() bool QWaylandView::isBufferLocked() const { Q_D(const QWaylandView); - return d->bufferLock; + return d->bufferLocked; } -void QWaylandView::setBufferLock(bool locked) +void QWaylandView::setBufferLocked(bool locked) { Q_D(QWaylandView); - if (d->bufferLock == locked) + if (d->bufferLocked == locked) return; - d->bufferLock = locked; - emit bufferLockChanged(); + d->bufferLocked = locked; + emit bufferLockedChanged(); } /*! - * \qmlproperty bool QtWaylandCompositor::WaylandView::discardFrontBuffers + * \qmlproperty bool QtWaylandCompositor::WaylandView::allowDiscardFrontBuffer * * By default, the view locks the current buffer until advance() is called. Set this property * to true to allow Qt to release the buffer when the throttling view is no longer using it. */ + /*! - * \property QWaylandView::discardFrontBuffers + * \property QWaylandView::allowDiscardFrontBuffer * * By default, the view locks the current buffer until advance() is called. Set this property * to \c true to allow Qt to release the buffer when the throttling view is no longer using it. */ -bool QWaylandView::discardFrontBuffers() const +bool QWaylandView::allowDiscardFrontBuffer() const { Q_D(const QWaylandView); - return d->discardFrontBuffers; + return d->allowDiscardFrontBuffer; } -void QWaylandView::setDiscardFrontBuffers(bool discard) +void QWaylandView::setAllowDiscardFrontBuffer(bool discard) { Q_D(QWaylandView); - if (d->discardFrontBuffers == discard) + if (d->allowDiscardFrontBuffer == discard) return; - d->discardFrontBuffers = discard; - emit discardFrontBuffersChanged(); + d->allowDiscardFrontBuffer = discard; + emit allowDiscardFrontBufferChanged(); } /*! diff --git a/src/compositor/compositor_api/qwaylandview.h b/src/compositor/compositor_api/qwaylandview.h index f89d8ca78..6247e06e2 100644 --- a/src/compositor/compositor_api/qwaylandview.h +++ b/src/compositor/compositor_api/qwaylandview.h @@ -56,8 +56,8 @@ class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandView : public QObject Q_PROPERTY(QObject *renderObject READ renderObject CONSTANT) Q_PROPERTY(QWaylandSurface *surface READ surface WRITE setSurface NOTIFY surfaceChanged) Q_PROPERTY(QWaylandOutput *output READ output WRITE setOutput NOTIFY outputChanged) - Q_PROPERTY(bool bufferLock READ isBufferLocked WRITE setBufferLock NOTIFY bufferLockChanged) - Q_PROPERTY(bool discardFrontBuffers READ discardFrontBuffers WRITE setDiscardFrontBuffers NOTIFY discardFrontBuffersChanged) + Q_PROPERTY(bool bufferLocked READ isBufferLocked WRITE setBufferLocked NOTIFY bufferLockedChanged) + Q_PROPERTY(bool allowDiscardFrontBuffer READ allowDiscardFrontBuffer WRITE setAllowDiscardFrontBuffer NOTIFY allowDiscardFrontBufferChanged) public: QWaylandView(QObject *renderObject = nullptr, QObject *parent = nullptr); virtual ~QWaylandView(); @@ -77,10 +77,10 @@ public: virtual QRegion currentDamage(); bool isBufferLocked() const; - void setBufferLock(bool locked); + void setBufferLocked(bool locked); - bool discardFrontBuffers() const; - void setDiscardFrontBuffers(bool discard); + bool allowDiscardFrontBuffer() const; + void setAllowDiscardFrontBuffer(bool discard); struct wl_resource *surfaceResource() const; @@ -88,8 +88,8 @@ Q_SIGNALS: void surfaceChanged(); void surfaceDestroyed(); void outputChanged(); - void bufferLockChanged(); - void discardFrontBuffersChanged(); + void bufferLockedChanged(); + void allowDiscardFrontBufferChanged(); }; QT_END_NAMESPACE diff --git a/src/compositor/compositor_api/qwaylandview_p.h b/src/compositor/compositor_api/qwaylandview_p.h index 8c4cea085..d9fd352ed 100644 --- a/src/compositor/compositor_api/qwaylandview_p.h +++ b/src/compositor/compositor_api/qwaylandview_p.h @@ -69,10 +69,10 @@ public: : renderObject(Q_NULLPTR) , surface(Q_NULLPTR) , output(Q_NULLPTR) - , bufferLock(false) + , bufferLocked(false) , broadcastRequestedPositionChanged(false) , forceAdvanceSucceed(false) - , discardFrontBuffers(false) + , allowDiscardFrontBuffer(false) { } void markSurfaceAsDestroyed(QWaylandSurface *surface); @@ -86,10 +86,10 @@ public: QRegion currentDamage; QWaylandBufferRef nextBuffer; QRegion nextDamage; - bool bufferLock; + bool bufferLocked; bool broadcastRequestedPositionChanged; bool forceAdvanceSucceed; - bool discardFrontBuffers; + bool allowDiscardFrontBuffer; }; QT_END_NAMESPACE diff --git a/src/compositor/extensions/extensions.pri b/src/compositor/extensions/extensions.pri index 4894eb3c4..bb0abe885 100644 --- a/src/compositor/extensions/extensions.pri +++ b/src/compositor/extensions/extensions.pri @@ -5,7 +5,7 @@ WAYLANDSERVERSOURCES += \ ../extensions/surface-extension.xml \ ../extensions/touch-extension.xml \ ../extensions/qtkey-extension.xml \ - ../extensions/windowmanager.xml \ + ../extensions/qt-windowmanager.xml \ ../3rdparty/protocol/text-input-unstable-v2.xml \ ../3rdparty/protocol/xdg-shell.xml \ @@ -19,8 +19,8 @@ HEADERS += \ extensions/qwaylandtextinput_p.h \ extensions/qwaylandtextinputmanager.h \ extensions/qwaylandtextinputmanager_p.h \ - extensions/qwaylandwindowmanagerextension.h \ - extensions/qwaylandwindowmanagerextension_p.h \ + extensions/qwaylandqtwindowmanager.h \ + extensions/qwaylandqtwindowmanager_p.h \ extensions/qwaylandxdgshell.h \ extensions/qwaylandxdgshell_p.h \ extensions/qwaylandshellsurface.h \ @@ -32,10 +32,10 @@ SOURCES += \ extensions/qwaylandwlshell.cpp \ extensions/qwaylandtextinput.cpp \ extensions/qwaylandtextinputmanager.cpp \ - extensions/qwaylandwindowmanagerextension.cpp \ + extensions/qwaylandqtwindowmanager.cpp \ extensions/qwaylandxdgshell.cpp \ -qtHaveModule(quick) { +qtHaveModule(quick):contains(QT_CONFIG, opengl) { HEADERS += \ extensions/qwaylandquickshellsurfaceitem.h \ extensions/qwaylandquickshellsurfaceitem_p.h \ diff --git a/src/compositor/extensions/qwaylandwindowmanagerextension.cpp b/src/compositor/extensions/qwaylandqtwindowmanager.cpp index 1e7ed2892..f82a8e46f 100644 --- a/src/compositor/extensions/qwaylandwindowmanagerextension.cpp +++ b/src/compositor/extensions/qwaylandqtwindowmanager.cpp @@ -1,6 +1,7 @@ /**************************************************************************** ** ** Copyright (C) 2015 The Qt Company Ltd. +** Copyright (C) 2016 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com> ** Contact: http://www.qt.io/licensing/ ** ** This file is part of the QtWaylandCompositor module of the Qt Toolkit. @@ -34,115 +35,116 @@ ** ****************************************************************************/ -#include "qwaylandwindowmanagerextension.h" -#include "qwaylandwindowmanagerextension_p.h" +#include <QtCore/QObject> +#include <QtCore/QUrl> #include <QtWaylandCompositor/QWaylandCompositor> #include <QtWaylandCompositor/QWaylandClient> -#include <QtCore/QUrl> +#include "qwaylandqtwindowmanager.h" +#include "qwaylandqtwindowmanager_p.h" QT_BEGIN_NAMESPACE -QWaylandWindowManagerExtension::QWaylandWindowManagerExtension() - : QWaylandCompositorExtensionTemplate<QWaylandWindowManagerExtension>(*new QWaylandWindowManagerExtensionPrivate) +QWaylandQtWindowManagerPrivate::QWaylandQtWindowManagerPrivate() + : QWaylandCompositorExtensionPrivate() + , qt_windowmanager() + , showIsFullScreen(false) { } -QWaylandWindowManagerExtension::QWaylandWindowManagerExtension(QWaylandCompositor *compositor) - : QWaylandCompositorExtensionTemplate<QWaylandWindowManagerExtension>(compositor, *new QWaylandWindowManagerExtensionPrivate) +void QWaylandQtWindowManagerPrivate::windowmanager_bind_resource(Resource *resource) { + send_hints(resource->handle, static_cast<int32_t>(showIsFullScreen)); } -QWaylandWindowManagerExtensionPrivate::QWaylandWindowManagerExtensionPrivate() - : QWaylandCompositorExtensionPrivate() - , QtWaylandServer::qt_windowmanager() - , showIsFullScreen(false) +void QWaylandQtWindowManagerPrivate::windowmanager_destroy_resource(Resource *resource) +{ + urls.remove(resource); +} + +void QWaylandQtWindowManagerPrivate::windowmanager_open_url(Resource *resource, uint32_t remaining, const QString &newUrl) +{ + Q_Q(QWaylandQtWindowManager); + + QWaylandCompositor *compositor = static_cast<QWaylandCompositor *>(q->extensionContainer()); + if (!compositor) { + qWarning() << "Failed to find QWaylandCompositor from QWaylandQtWindowManager::windowmanager_open_url()"; + return; + } + + QString url = urls.value(resource, QString()); + + url.append(newUrl); + + if (remaining) + urls.insert(resource, url); + else { + urls.remove(resource); + q->openUrl(QWaylandClient::fromWlClient(compositor, resource->client()), QUrl(url)); + } +} + +QWaylandQtWindowManager::QWaylandQtWindowManager() + : QWaylandCompositorExtensionTemplate<QWaylandQtWindowManager>(*new QWaylandQtWindowManagerPrivate()) { } -bool QWaylandWindowManagerExtension::showIsFullScreen() const +QWaylandQtWindowManager::QWaylandQtWindowManager(QWaylandCompositor *compositor) + : QWaylandCompositorExtensionTemplate<QWaylandQtWindowManager>(compositor, *new QWaylandQtWindowManagerPrivate()) { - Q_D(const QWaylandWindowManagerExtension); +} + +bool QWaylandQtWindowManager::showIsFullScreen() const +{ + Q_D(const QWaylandQtWindowManager); return d->showIsFullScreen; } -void QWaylandWindowManagerExtension::setShowIsFullScreen(bool value) +void QWaylandQtWindowManager::setShowIsFullScreen(bool value) { - Q_D(QWaylandWindowManagerExtension); + Q_D(QWaylandQtWindowManager); if (d->showIsFullScreen == value) return; d->showIsFullScreen = value; - Q_FOREACH (QWaylandWindowManagerExtensionPrivate::Resource *resource, d->resourceMap().values()) { + Q_FOREACH (QWaylandQtWindowManagerPrivate::Resource *resource, d->resourceMap().values()) { d->send_hints(resource->handle, static_cast<int32_t>(d->showIsFullScreen)); } Q_EMIT showIsFullScreenChanged(); } -void QWaylandWindowManagerExtension::sendQuitMessage(wl_client *client) +void QWaylandQtWindowManager::sendQuitMessage(QWaylandClient *client) { - Q_D(QWaylandWindowManagerExtension); - QWaylandWindowManagerExtensionPrivate::Resource *resource = d->resourceMap().value(client); + Q_D(QWaylandQtWindowManager); + QWaylandQtWindowManagerPrivate::Resource *resource = d->resourceMap().value(client->client()); if (resource) d->send_quit(resource->handle); } -void QWaylandWindowManagerExtension::initialize() +void QWaylandQtWindowManager::initialize() { - Q_D(QWaylandWindowManagerExtension); + Q_D(QWaylandQtWindowManager); QWaylandCompositorExtensionTemplate::initialize(); QWaylandCompositor *compositor = static_cast<QWaylandCompositor *>(extensionContainer()); if (!compositor) { - qWarning() << "Failed to find QWaylandCompositor when initializing QWaylandWindowManagerExtension"; + qWarning() << "Failed to find QWaylandCompositor when initializing QWaylandQtWindowManager"; return; } d->init(compositor->display(), 1); } -void QWaylandWindowManagerExtensionPrivate::windowmanager_bind_resource(Resource *resource) -{ - send_hints(resource->handle, static_cast<int32_t>(showIsFullScreen)); -} - -void QWaylandWindowManagerExtensionPrivate::windowmanager_destroy_resource(Resource *resource) -{ - urls.remove(resource); -} - -void QWaylandWindowManagerExtensionPrivate::windowmanager_open_url(Resource *resource, uint32_t remaining, const QString &newUrl) -{ - Q_Q(QWaylandWindowManagerExtension); - - QWaylandCompositor *compositor = static_cast<QWaylandCompositor *>(q->extensionContainer()); - if (!compositor) { - qWarning() << "Failed to find QWaylandCompositor from QWaylandWindowManagerExtension::windowmanager_open_url()"; - return; - } - - QString url = urls.value(resource, QString()); - - url.append(newUrl); - - if (remaining) - urls.insert(resource, url); - else { - urls.remove(resource); - q->openUrl(QWaylandClient::fromWlClient(compositor, resource->client()), QUrl(url)); - } -} - -const struct wl_interface *QWaylandWindowManagerExtension::interface() +const struct wl_interface *QWaylandQtWindowManager::interface() { - return QWaylandWindowManagerExtensionPrivate::interface(); + return QWaylandQtWindowManagerPrivate::interface(); } -QByteArray QWaylandWindowManagerExtension::interfaceName() +QByteArray QWaylandQtWindowManager::interfaceName() { - return QWaylandWindowManagerExtensionPrivate::interfaceName(); + return QWaylandQtWindowManagerPrivate::interfaceName(); } QT_END_NAMESPACE diff --git a/src/compositor/extensions/qwaylandwindowmanagerextension.h b/src/compositor/extensions/qwaylandqtwindowmanager.h index 184bcc3c5..4d3951025 100644 --- a/src/compositor/extensions/qwaylandwindowmanagerextension.h +++ b/src/compositor/extensions/qwaylandqtwindowmanager.h @@ -1,6 +1,7 @@ /**************************************************************************** ** ** Copyright (C) 2015 The Qt Company Ltd. +** Copyright (C) 2016 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com> ** Contact: http://www.qt.io/licensing/ ** ** This file is part of the QtWaylandCompositor module of the Qt Toolkit. @@ -34,8 +35,8 @@ ** ****************************************************************************/ -#ifndef WAYLANDWINDOWMANAGERINTEGRATION_H -#define WAYLANDWINDOWMANAGERINTEGRATION_H +#ifndef QWAYLANDQTWINDOWMANAGER_H +#define QWAYLANDQTWINDOWMANAGER_H #include <QtWaylandCompositor/QWaylandCompositorExtension> #include <QtWaylandCompositor/QWaylandClient> @@ -44,23 +45,21 @@ QT_BEGIN_NAMESPACE -class QWaylandCompositor; +class QWaylandQtWindowManagerPrivate; -class QWaylandWindowManagerExtensionPrivate; - -class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandWindowManagerExtension : public QWaylandCompositorExtensionTemplate<QWaylandWindowManagerExtension> +class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandQtWindowManager : public QWaylandCompositorExtensionTemplate<QWaylandQtWindowManager> { Q_OBJECT + Q_DECLARE_PRIVATE(QWaylandQtWindowManager) Q_PROPERTY(bool showIsFullScreen READ showIsFullScreen WRITE setShowIsFullScreen NOTIFY showIsFullScreenChanged) - Q_DECLARE_PRIVATE(QWaylandWindowManagerExtension) public: - QWaylandWindowManagerExtension(); - explicit QWaylandWindowManagerExtension(QWaylandCompositor *compositor); + QWaylandQtWindowManager(); + explicit QWaylandQtWindowManager(QWaylandCompositor *compositor); bool showIsFullScreen() const; void setShowIsFullScreen(bool value); - void sendQuitMessage(wl_client *client); + void sendQuitMessage(QWaylandClient *client); void initialize() Q_DECL_OVERRIDE; @@ -74,4 +73,4 @@ Q_SIGNALS: QT_END_NAMESPACE -#endif // WAYLANDWINDOWMANAGERINTEGRATION_H +#endif // QWAYLANDQTWINDOWMANAGER_H diff --git a/src/compositor/extensions/qwaylandwindowmanagerextension_p.h b/src/compositor/extensions/qwaylandqtwindowmanager_p.h index 9573855d5..a6df2138f 100644 --- a/src/compositor/extensions/qwaylandwindowmanagerextension_p.h +++ b/src/compositor/extensions/qwaylandqtwindowmanager_p.h @@ -1,6 +1,7 @@ /**************************************************************************** ** ** Copyright (C) 2015 The Qt Company Ltd. +** Copyright (C) 2016 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com> ** Contact: http://www.qt.io/licensing/ ** ** This file is part of the QtWaylandCompositor module of the Qt Toolkit. @@ -34,8 +35,14 @@ ** ****************************************************************************/ -#ifndef QWAYLANDWINDOWMANAGEREXTENSION_P_H -#define QWAYLANDWINDOWMANAGEREXTENSION_P_H +#ifndef QWAYLANDQTWINDOWMANAGER_P_H +#define QWAYLANDQTWINDOWMANAGER_P_H + +#include <QtCore/QMap> + +#include <QtWaylandCompositor/QWaylandQtWindowManager> +#include <QtWaylandCompositor/private/qwaylandcompositorextension_p.h> +#include <QtWaylandCompositor/private/qwayland-server-qt-windowmanager.h> // // W A R N I N G @@ -48,21 +55,15 @@ // We mean it. // -#include <QtWaylandCompositor/private/qwaylandcompositorextension_p.h> - -#include <QtWaylandCompositor/private/qwayland-server-windowmanager.h> - -#include <QMap> - QT_BEGIN_NAMESPACE -class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandWindowManagerExtensionPrivate +class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandQtWindowManagerPrivate : public QWaylandCompositorExtensionPrivate , public QtWaylandServer::qt_windowmanager { - Q_DECLARE_PUBLIC(QWaylandWindowManagerExtension) + Q_DECLARE_PUBLIC(QWaylandQtWindowManager) public: - QWaylandWindowManagerExtensionPrivate(); + QWaylandQtWindowManagerPrivate(); protected: void windowmanager_bind_resource(Resource *resource) Q_DECL_OVERRIDE; @@ -76,4 +77,4 @@ private: QT_END_NAMESPACE -#endif /*QWAYLANDWINDOWMANAGEREXTENSION_P_H*/ +#endif // QWAYLANDQTWINDOWMANAGER_P_H diff --git a/src/compositor/extensions/qwaylandquickshellsurfaceitem.h b/src/compositor/extensions/qwaylandquickshellsurfaceitem.h index e233c99e5..f72b970c2 100644 --- a/src/compositor/extensions/qwaylandquickshellsurfaceitem.h +++ b/src/compositor/extensions/qwaylandquickshellsurfaceitem.h @@ -51,8 +51,6 @@ class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandQuickShellSurfaceItem : public QWaylan Q_DECLARE_PRIVATE(QWaylandQuickShellSurfaceItem) Q_PROPERTY(QWaylandShellSurface *shellSurface READ shellSurface WRITE setShellSurface NOTIFY shellSurfaceChanged) Q_PROPERTY(QQuickItem *moveItem READ moveItem WRITE setMoveItem NOTIFY moveItemChanged) - - QWaylandQuickShellSurfaceItem(QWaylandQuickShellSurfaceItemPrivate &dd, QQuickItem *parent); public: QWaylandQuickShellSurfaceItem(QQuickItem *parent = nullptr); @@ -67,6 +65,8 @@ Q_SIGNALS: void moveItemChanged(); protected: + QWaylandQuickShellSurfaceItem(QWaylandQuickShellSurfaceItemPrivate &dd, QQuickItem *parent); + void mouseMoveEvent(QMouseEvent *event) Q_DECL_OVERRIDE; void mouseReleaseEvent(QMouseEvent *event) Q_DECL_OVERRIDE; }; diff --git a/src/compositor/extensions/qwaylandquickshellsurfaceitem_p.h b/src/compositor/extensions/qwaylandquickshellsurfaceitem_p.h index c39a1cd08..3cd9bf228 100644 --- a/src/compositor/extensions/qwaylandquickshellsurfaceitem_p.h +++ b/src/compositor/extensions/qwaylandquickshellsurfaceitem_p.h @@ -40,6 +40,8 @@ #include <QtWaylandCompositor/private/qwaylandquickitem_p.h> #include <QtCore/QBasicTimer> +#include <functional> + QT_BEGIN_NAMESPACE // @@ -83,7 +85,7 @@ class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandQuickShellEventFilter : public QObject { Q_OBJECT public: - typedef void (*CallbackFunction)(void); + typedef std::function<void()> CallbackFunction; static void startFilter(QWaylandClient *client, CallbackFunction closePopupCallback); static void cancelFilter(); diff --git a/src/compositor/extensions/qwaylandshellsurface.h b/src/compositor/extensions/qwaylandshellsurface.h index 1e9fcb5ab..e8c75327c 100644 --- a/src/compositor/extensions/qwaylandshellsurface.h +++ b/src/compositor/extensions/qwaylandshellsurface.h @@ -49,13 +49,20 @@ class QWaylandShellSurfaceTemplatePrivate; class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandShellSurface : public QWaylandCompositorExtension { Q_OBJECT + Q_PROPERTY(Qt::WindowType windowType READ windowType NOTIFY windowTypeChanged) public: +#ifdef QT_WAYLAND_COMPOSITOR_QUICK virtual QWaylandQuickShellIntegration *createIntegration(QWaylandQuickShellSurfaceItem *item) = 0; +#endif QWaylandShellSurface(QWaylandObject *waylandObject) : QWaylandCompositorExtension(waylandObject) {} + virtual Qt::WindowType windowType() const { return Qt::WindowType::Window; } protected: QWaylandShellSurface(QWaylandCompositorExtensionPrivate &dd) : QWaylandCompositorExtension(dd){} QWaylandShellSurface(QWaylandObject *container, QWaylandCompositorExtensionPrivate &dd) : QWaylandCompositorExtension(container, dd) {} + +Q_SIGNALS: + void windowTypeChanged(); }; template <typename T> diff --git a/src/compositor/extensions/qwaylandtextinput.cpp b/src/compositor/extensions/qwaylandtextinput.cpp index 973308f2f..14dafaab0 100644 --- a/src/compositor/extensions/qwaylandtextinput.cpp +++ b/src/compositor/extensions/qwaylandtextinput.cpp @@ -38,7 +38,7 @@ #include "qwaylandtextinput_p.h" #include <QtWaylandCompositor/QWaylandCompositor> -#include <QtWaylandCompositor/private/qwaylandinput_p.h> +#include <QtWaylandCompositor/private/qwaylandseat_p.h> #include "qwaylandsurface.h" #include "qwaylandview.h" diff --git a/src/compositor/extensions/qwaylandtextinputmanager.cpp b/src/compositor/extensions/qwaylandtextinputmanager.cpp index 9dd7ace8f..7be00b6dd 100644 --- a/src/compositor/extensions/qwaylandtextinputmanager.cpp +++ b/src/compositor/extensions/qwaylandtextinputmanager.cpp @@ -38,7 +38,7 @@ #include "qwaylandtextinputmanager_p.h" #include <QtWaylandCompositor/QWaylandCompositor> -#include <QtWaylandCompositor/QWaylandInputDevice> +#include <QtWaylandCompositor/QWaylandSeat> #include "qwaylandtextinput.h" @@ -50,14 +50,14 @@ QWaylandTextInputManagerPrivate::QWaylandTextInputManagerPrivate() { } -void QWaylandTextInputManagerPrivate::zwp_text_input_manager_v2_get_text_input(Resource *resource, uint32_t id, struct ::wl_resource *seat) +void QWaylandTextInputManagerPrivate::zwp_text_input_manager_v2_get_text_input(Resource *resource, uint32_t id, struct ::wl_resource *seatResource) { Q_Q(QWaylandTextInputManager); QWaylandCompositor *compositor = static_cast<QWaylandCompositor *>(q->extensionContainer()); - QWaylandInputDevice *inputDevice = QWaylandInputDevice::fromSeatResource(seat); - QWaylandTextInput *textInput = QWaylandTextInput::findIn(inputDevice); + QWaylandSeat *seat = QWaylandSeat::fromSeatResource(seatResource); + QWaylandTextInput *textInput = QWaylandTextInput::findIn(seat); if (!textInput) { - textInput = new QWaylandTextInput(inputDevice, compositor); + textInput = new QWaylandTextInput(seat, compositor); } textInput->add(resource->client(), id, wl_resource_get_version(resource->handle)); } diff --git a/src/compositor/extensions/qwaylandtextinputmanager_p.h b/src/compositor/extensions/qwaylandtextinputmanager_p.h index 4af717096..955a5cc8a 100644 --- a/src/compositor/extensions/qwaylandtextinputmanager_p.h +++ b/src/compositor/extensions/qwaylandtextinputmanager_p.h @@ -61,7 +61,7 @@ public: QWaylandTextInputManagerPrivate(); protected: - void zwp_text_input_manager_v2_get_text_input(Resource *resource, uint32_t id, struct ::wl_resource *seat) Q_DECL_OVERRIDE; + void zwp_text_input_manager_v2_get_text_input(Resource *resource, uint32_t id, struct ::wl_resource *seatResource) Q_DECL_OVERRIDE; }; QT_END_NAMESPACE diff --git a/src/compositor/extensions/qwaylandwlshell.cpp b/src/compositor/extensions/qwaylandwlshell.cpp index c79ddac7c..a1313a6c2 100644 --- a/src/compositor/extensions/qwaylandwlshell.cpp +++ b/src/compositor/extensions/qwaylandwlshell.cpp @@ -38,7 +38,9 @@ #include "qwaylandwlshell.h" #include "qwaylandwlshell_p.h" +#ifdef QT_WAYLAND_COMPOSITOR_QUICK #include "qwaylandwlshellintegration_p.h" +#endif #include <QtWaylandCompositor/QWaylandCompositor> #include <QtWaylandCompositor/QWaylandView> @@ -77,16 +79,23 @@ void QWaylandWlShellPrivate::shell_get_shell_surface(Resource *resource, uint32_ if (!surface->setRole(QWaylandWlShellSurface::role(), displayRes, WL_DISPLAY_ERROR_INVALID_OBJECT)) return; - emit q->createShellSurface(surface, shellSurfaceResource); + emit q->wlShellSurfaceRequested(surface, shellSurfaceResource); QWaylandWlShellSurface *shellSurface = QWaylandWlShellSurface::fromResource(shellSurfaceResource.resource()); if (!shellSurface) { - // A QWaylandShellSurface was not created in response to the createShellSurface signal - // we create one as fallback here instead. + // A QWaylandWlShellSurface was not created in response to the wlShellSurfaceRequested + // signal, so we create one as fallback here instead. shellSurface = new QWaylandWlShellSurface(q, surface, shellSurfaceResource); } - emit q->shellSurfaceCreated(shellSurface); + m_shellSurfaces.append(shellSurface); + emit q->wlShellSurfaceCreated(shellSurface); +} + +void QWaylandWlShellPrivate::unregisterShellSurface(QWaylandWlShellSurface *shellSurface) +{ + if (!m_shellSurfaces.removeOne(shellSurface)) + qWarning("Unexpected state. Can't find registered shell surface."); } QWaylandWlShellSurfacePrivate::QWaylandWlShellSurfacePrivate() @@ -95,6 +104,7 @@ QWaylandWlShellSurfacePrivate::QWaylandWlShellSurfacePrivate() , m_shell(Q_NULLPTR) , m_surface(Q_NULLPTR) , m_focusPolicy(QWaylandWlShellSurface::DefaultFocus) + , m_windowType(Qt::WindowType::Window) { } @@ -108,6 +118,16 @@ void QWaylandWlShellSurfacePrivate::ping(uint32_t serial) send_ping(serial); } +void QWaylandWlShellSurfacePrivate::setWindowType(Qt::WindowType windowType) +{ + if (m_windowType == windowType) + return; + m_windowType = windowType; + + Q_Q(QWaylandWlShellSurface); + emit q->windowTypeChanged(); +} + void QWaylandWlShellSurfacePrivate::shell_surface_destroy_resource(Resource *) { Q_Q(QWaylandWlShellSurface); @@ -123,7 +143,7 @@ void QWaylandWlShellSurfacePrivate::shell_surface_move(Resource *resource, Q_UNUSED(serial); Q_Q(QWaylandWlShellSurface); - QWaylandInputDevice *input_device = QWaylandInputDevice::fromSeatResource(input_device_super); + QWaylandSeat *input_device = QWaylandSeat::fromSeatResource(input_device_super); emit q->startMove(input_device); } @@ -136,7 +156,7 @@ void QWaylandWlShellSurfacePrivate::shell_surface_resize(Resource *resource, Q_UNUSED(serial); Q_Q(QWaylandWlShellSurface); - QWaylandInputDevice *input_device = QWaylandInputDevice::fromSeatResource(input_device_super); + QWaylandSeat *input_device = QWaylandSeat::fromSeatResource(input_device_super); emit q->startResize(input_device, QWaylandWlShellSurface::ResizeEdge(edges)); } @@ -145,6 +165,7 @@ void QWaylandWlShellSurfacePrivate::shell_surface_set_toplevel(Resource *resourc Q_UNUSED(resource); Q_Q(QWaylandWlShellSurface); setFocusPolicy(QWaylandWlShellSurface::DefaultFocus); + setWindowType(Qt::WindowType::Window); emit q->setDefaultToplevel(); } @@ -162,6 +183,7 @@ void QWaylandWlShellSurfacePrivate::shell_surface_set_transient(Resource *resour flags & WL_SHELL_SURFACE_TRANSIENT_INACTIVE ? QWaylandWlShellSurface::NoKeyboardFocus : QWaylandWlShellSurface::DefaultFocus; setFocusPolicy(focusPolicy); + setWindowType(Qt::WindowType::SubWindow); emit q->setTransient(parent_surface, QPoint(x,y), focusPolicy); } @@ -178,6 +200,7 @@ void QWaylandWlShellSurfacePrivate::shell_surface_set_fullscreen(Resource *resou QWaylandOutput *output = output_resource ? QWaylandOutput::fromResource(output_resource) : Q_NULLPTR; + setWindowType(Qt::WindowType::Window); emit q->setFullScreen(QWaylandWlShellSurface::FullScreenMethod(method), framerate, output); } @@ -188,8 +211,9 @@ void QWaylandWlShellSurfacePrivate::shell_surface_set_popup(Resource *resource, Q_UNUSED(flags); Q_Q(QWaylandWlShellSurface); setFocusPolicy(QWaylandWlShellSurface::DefaultFocus); - QWaylandInputDevice *input = QWaylandInputDevice::fromSeatResource(input_device); + QWaylandSeat *input = QWaylandSeat::fromSeatResource(input_device); QWaylandSurface *parentSurface = QWaylandSurface::fromResource(parent); + setWindowType(Qt::WindowType::Popup); emit q->setPopup(input, parentSurface, QPoint(x,y)); } @@ -203,6 +227,7 @@ void QWaylandWlShellSurfacePrivate::shell_surface_set_maximized(Resource *resour QWaylandOutput *output = output_resource ? QWaylandOutput::fromResource(output_resource) : Q_NULLPTR; + setWindowType(Qt::WindowType::Window); emit q->setMaximized(output); } @@ -308,6 +333,23 @@ void QWaylandWlShell::initialize() d->init(compositor->display(), 1); } +QList<QWaylandWlShellSurface *> QWaylandWlShell::shellSurfaces() const +{ + Q_D(const QWaylandWlShell); + return d->m_shellSurfaces; +} + +QList<QWaylandWlShellSurface *> QWaylandWlShell::shellSurfacesForClient(QWaylandClient *client) const +{ + Q_D(const QWaylandWlShell); + QList<QWaylandWlShellSurface *> surfsForClient; + Q_FOREACH (QWaylandWlShellSurface *shellSurface, d->m_shellSurfaces) { + if (shellSurface->surface()->client() == client) + surfsForClient.append(shellSurface); + } + return surfsForClient; +} + /*! * Returns the Wayland interface for the QWaylandWlShell. */ @@ -317,7 +359,7 @@ const struct wl_interface *QWaylandWlShell::interface() } /*! - * \qmlsignal void QtWaylandCompositor::WlShell::createShellSurface(object surface, object client, int id) + * \qmlsignal void QtWaylandCompositor::WlShell::wlShellSurfaceRequested(object surface, object client, int id) * * This signal is emitted when the \a client has requested a \c wl_shell_surface to be associated * with \a surface, which is identified by \a id. The handler for this signal is @@ -326,7 +368,7 @@ const struct wl_interface *QWaylandWlShell::interface() */ /*! - * \fn void QWaylandWlShell::createShellSurface(QWaylandSurface *surface, const QWaylandResource &resource) + * \fn void QWaylandWlShell::wlShellSurfaceRequested(QWaylandSurface *surface, const QWaylandResource &resource) * * Constructs a QWaylandSurface, assigns it to \a surface and initializes it with the given \a resource. */ @@ -382,6 +424,12 @@ QWaylandWlShellSurface::QWaylandWlShellSurface(QWaylandWlShell *shell, QWaylandS initialize(shell, surface, res); } +QWaylandWlShellSurface::~QWaylandWlShellSurface() +{ + Q_D(QWaylandWlShellSurface); + QWaylandWlShellPrivate::get(d->m_shell)->unregisterShellSurface(this); +} + /*! * \qmlmethod void QtWaylandCompositor::WlShellSurface::initialize(object shell, object surface, object client, int id) * @@ -399,6 +447,7 @@ void QWaylandWlShellSurface::initialize(QWaylandWlShell *shell, QWaylandSurface d->init(resource.resource()); setExtensionContainer(surface); emit surfaceChanged(); + emit shellChanged(); QWaylandCompositorExtension::initialize(); } @@ -493,10 +542,12 @@ void QWaylandWlShellSurface::sendPopupDone() d->send_popup_done(); } +#ifdef QT_WAYLAND_COMPOSITOR_QUICK QWaylandQuickShellIntegration *QWaylandWlShellSurface::createIntegration(QWaylandQuickShellSurfaceItem *item) { return new QtWayland::WlShellIntegration(item); } +#endif /*! * \qmlproperty object QtWaylandCompositor::WlShellSurface::surface @@ -516,6 +567,23 @@ QWaylandSurface *QWaylandWlShellSurface::surface() const } /*! + * \qmlproperty object QtWaylandCompositor::WlShellSurface::shell + * + * This property holds the shell associated with this WlShellSurface. + */ + +/*! + * \property QWaylandWlShellSurface::shell + * + * This property holds the shell associated with this QWaylandWlShellSurface. + */ +QWaylandWlShell *QWaylandWlShellSurface::shell() const +{ + Q_D(const QWaylandWlShellSurface); + return d->m_shell; +} + +/*! * \enum QWaylandWlShellSurface::FocusPolicy * * This enum type is used to specify the focus policy of a shell surface. @@ -542,6 +610,23 @@ QWaylandWlShellSurface::FocusPolicy QWaylandWlShellSurface::focusPolicy() const } /*! + * \qmlproperty enum QtWaylandCompositor::WlShellSurface::windowType + * + * This property holds the window type of the WlShellSurface. + */ + +/*! + * \property QWaylandWlShellSurface::windowType + * + * This property holds the window type of the QWaylandWlShellSurface. + */ +Qt::WindowType QWaylandWlShellSurface::windowType() const +{ + Q_D(const QWaylandWlShellSurface); + return d->m_windowType; +} + +/*! * \qmlproperty string QtWaylandCompositor::WlShellSurface::title * * This property holds the title of the WlShellSurface. diff --git a/src/compositor/extensions/qwaylandwlshell.h b/src/compositor/extensions/qwaylandwlshell.h index 5bddd4f7b..c2d40a87c 100644 --- a/src/compositor/extensions/qwaylandwlshell.h +++ b/src/compositor/extensions/qwaylandwlshell.h @@ -49,7 +49,7 @@ class QWaylandWlShellPrivate; class QWaylandWlShellSurfacePrivate; class QWaylandSurface; class QWaylandClient; -class QWaylandInputDevice; +class QWaylandSeat; class QWaylandOutput; class QWaylandSurfaceRole; class QWaylandWlShellSurface; @@ -63,13 +63,15 @@ public: QWaylandWlShell(QWaylandCompositor *compositor); void initialize() Q_DECL_OVERRIDE; + QList<QWaylandWlShellSurface *> shellSurfaces() const; + QList<QWaylandWlShellSurface *> shellSurfacesForClient(QWaylandClient* client) const; static const struct wl_interface *interface(); static QByteArray interfaceName(); Q_SIGNALS: - void createShellSurface(QWaylandSurface *surface, const QWaylandResource &resource); - void shellSurfaceCreated(QWaylandWlShellSurface *shellSurface); + void wlShellSurfaceRequested(QWaylandSurface *surface, const QWaylandResource &resource); + void wlShellSurfaceCreated(QWaylandWlShellSurface *shellSurface); }; class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandWlShellSurface : public QWaylandShellSurfaceTemplate<QWaylandWlShellSurface> @@ -77,6 +79,7 @@ class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandWlShellSurface : public QWaylandShellS Q_OBJECT Q_DECLARE_PRIVATE(QWaylandWlShellSurface) Q_PROPERTY(QWaylandSurface *surface READ surface NOTIFY surfaceChanged) + Q_PROPERTY(QWaylandWlShell *shell READ shell NOTIFY shellChanged) Q_PROPERTY(QString title READ title NOTIFY titleChanged) Q_PROPERTY(QString className READ className NOTIFY classNameChanged) Q_PROPERTY(FocusPolicy focusPolicy READ focusPolicy NOTIFY focusPolicyChanged) @@ -111,6 +114,7 @@ public: QWaylandWlShellSurface(); QWaylandWlShellSurface(QWaylandWlShell *shell, QWaylandSurface *surface, const QWaylandResource &resource); + virtual ~QWaylandWlShellSurface(); Q_INVOKABLE void initialize(QWaylandWlShell *shell, QWaylandSurface *surface, const QWaylandResource &resource); @@ -118,8 +122,10 @@ public: QString className() const; QWaylandSurface *surface() const; + QWaylandWlShell *shell() const; FocusPolicy focusPolicy() const; + Qt::WindowType windowType() const override; static const struct wl_interface *interface(); static QByteArray interfaceName(); @@ -131,24 +137,27 @@ public: Q_INVOKABLE void sendConfigure(const QSize &size, ResizeEdge edges); Q_INVOKABLE void sendPopupDone(); +#ifdef QT_WAYLAND_COMPOSITOR_QUICK QWaylandQuickShellIntegration *createIntegration(QWaylandQuickShellSurfaceItem *item) Q_DECL_OVERRIDE; +#endif public Q_SLOTS: void ping(); Q_SIGNALS: void surfaceChanged(); + void shellChanged(); void titleChanged(); void classNameChanged(); void focusPolicyChanged(); void pong(); - void startMove(QWaylandInputDevice *inputDevice); - void startResize(QWaylandInputDevice *inputDevice, ResizeEdge edges); + void startMove(QWaylandSeat *seat); + void startResize(QWaylandSeat *seat, ResizeEdge edges); void setDefaultToplevel(); void setTransient(QWaylandSurface *parentSurface, const QPoint &relativeToParent, FocusPolicy focusPolicy); void setFullScreen(FullScreenMethod method, uint framerate, QWaylandOutput *output); - void setPopup(QWaylandInputDevice *inputDevice, QWaylandSurface *parentSurface, const QPoint &relativeToParent); + void setPopup(QWaylandSeat *seat, QWaylandSurface *parentSurface, const QPoint &relativeToParent); void setMaximized(QWaylandOutput *output); private: diff --git a/src/compositor/extensions/qwaylandwlshell_p.h b/src/compositor/extensions/qwaylandwlshell_p.h index 39ed645c1..e840a01fe 100644 --- a/src/compositor/extensions/qwaylandwlshell_p.h +++ b/src/compositor/extensions/qwaylandwlshell_p.h @@ -41,7 +41,7 @@ #include <QtWaylandCompositor/qwaylandsurface.h> #include <QtWaylandCompositor/private/qwaylandcompositorextension_p.h> #include <QtWaylandCompositor/QWaylandWlShellSurface> -#include <QtWaylandCompositor/QWaylandInputDevice> +#include <QtWaylandCompositor/QWaylandSeat> #include <wayland-server.h> #include <QHash> @@ -70,10 +70,15 @@ class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandWlShellPrivate Q_DECLARE_PUBLIC(QWaylandWlShell) public: QWaylandWlShellPrivate(); + + void unregisterShellSurface(QWaylandWlShellSurface *shellSurface); + static QWaylandWlShellPrivate *get(QWaylandWlShell *shell) { return shell->d_func(); } protected: void shell_get_shell_surface(Resource *resource, uint32_t id, struct ::wl_resource *surface) Q_DECL_OVERRIDE; + + QList<QWaylandWlShellSurface *> m_shellSurfaces; }; class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandWlShellSurfacePrivate @@ -97,6 +102,9 @@ public: m_focusPolicy = focusPolicy; emit q->focusPolicyChanged(); } + + void setWindowType(Qt::WindowType windowType); + private: QWaylandWlShell *m_shell; QWaylandSurface *m_surface; @@ -106,6 +114,7 @@ private: QString m_title; QString m_className; QWaylandWlShellSurface::FocusPolicy m_focusPolicy; + Qt::WindowType m_windowType; void shell_surface_destroy_resource(Resource *resource) Q_DECL_OVERRIDE; diff --git a/src/compositor/extensions/qwaylandwlshellintegration.cpp b/src/compositor/extensions/qwaylandwlshellintegration.cpp index a1ef5f32a..1acc01dd7 100644 --- a/src/compositor/extensions/qwaylandwlshellintegration.cpp +++ b/src/compositor/extensions/qwaylandwlshellintegration.cpp @@ -39,7 +39,7 @@ #include <QtWaylandCompositor/QWaylandCompositor> #include <QtWaylandCompositor/QWaylandWlShellSurface> #include <QtWaylandCompositor/QWaylandQuickShellSurfaceItem> -#include <QtWaylandCompositor/QWaylandInputDevice> +#include <QtWaylandCompositor/QWaylandSeat> QT_BEGIN_NAMESPACE @@ -60,28 +60,39 @@ WlShellIntegration::WlShellIntegration(QWaylandQuickShellSurfaceItem *item) connect(m_shellSurface, &QWaylandWlShellSurface::destroyed, this, &WlShellIntegration::handleShellSurfaceDestroyed); } -void WlShellIntegration::handleStartMove(QWaylandInputDevice *inputDevice) +void WlShellIntegration::handleStartMove(QWaylandSeat *seat) { grabberState = GrabberState::Move; - moveState.inputDevice = inputDevice; + moveState.seat = seat; moveState.initialized = false; } -void WlShellIntegration::handleStartResize(QWaylandInputDevice *inputDevice, QWaylandWlShellSurface::ResizeEdge edges) +void WlShellIntegration::handleStartResize(QWaylandSeat *seat, QWaylandWlShellSurface::ResizeEdge edges) { grabberState = GrabberState::Resize; - resizeState.inputDevice = inputDevice; + resizeState.seat = seat; resizeState.resizeEdges = edges; float scaleFactor = m_item->view()->output()->scaleFactor(); resizeState.initialSize = m_shellSurface->surface()->size() / scaleFactor; resizeState.initialized = false; } -void WlShellIntegration::handleSetPopup(QWaylandInputDevice *inputDevice, QWaylandSurface *parent, const QPoint &relativeToParent) +void WlShellIntegration::handleSetPopup(QWaylandSeat *seat, QWaylandSurface *parent, const QPoint &relativeToParent) { - Q_UNUSED(inputDevice); + Q_UNUSED(seat); + + // Find the parent item on the same output + QWaylandQuickShellSurfaceItem *parentItem = nullptr; + Q_FOREACH (QWaylandView *view, parent->views()) { + if (view->output() == m_item->view()->output()) { + QWaylandQuickShellSurfaceItem *item = qobject_cast<QWaylandQuickShellSurfaceItem*>(view->renderObject()); + if (item) { + parentItem = item; + break; + } + } + } - QWaylandQuickShellSurfaceItem* parentItem = qobject_cast<QWaylandQuickShellSurfaceItem*>(parent->views().first()->renderObject()); if (parentItem) { // Clear all the transforms for this ShellSurfaceItem. They are not // applicable when the item becomes a child to a surface that has its @@ -100,8 +111,8 @@ void WlShellIntegration::handleSetPopup(QWaylandInputDevice *inputDevice, QWayla if (!popupShellSurfaces.contains(m_shellSurface)) { popupShellSurfaces.append(m_shellSurface); - QObject::connect(m_shellSurface->surface(), &QWaylandSurface::mappedChanged, - this, &WlShellIntegration::handleSurfaceUnmapped); + QObject::connect(m_shellSurface->surface(), &QWaylandSurface::hasContentChanged, + this, &WlShellIntegration::handleSurfaceHasContentChanged); } } @@ -109,8 +120,8 @@ void WlShellIntegration::handlePopupClosed() { handlePopupRemoved(); if (m_shellSurface) - QObject::disconnect(m_shellSurface->surface(), &QWaylandSurface::mappedChanged, - this, &WlShellIntegration::handleSurfaceUnmapped); + QObject::disconnect(m_shellSurface->surface(), &QWaylandSurface::hasContentChanged, + this, &WlShellIntegration::handleSurfaceHasContentChanged); } void WlShellIntegration::handlePopupRemoved() @@ -130,7 +141,7 @@ void WlShellIntegration::handleShellSurfaceDestroyed() m_shellSurface = nullptr; } -void WlShellIntegration::handleSurfaceUnmapped() +void WlShellIntegration::handleSurfaceHasContentChanged() { if (!m_shellSurface || !m_shellSurface->surface()->size().isEmpty()) return; @@ -147,7 +158,7 @@ void WlShellIntegration::adjustOffsetForNextFrame(const QPointF &offset) bool WlShellIntegration::mouseMoveEvent(QMouseEvent *event) { if (grabberState == GrabberState::Resize) { - Q_ASSERT(resizeState.inputDevice == m_item->compositor()->inputDeviceFor(event)); + Q_ASSERT(resizeState.seat == m_item->compositor()->seatFor(event)); if (!resizeState.initialized) { resizeState.initialMousePos = event->windowPos(); resizeState.initialized = true; @@ -158,7 +169,7 @@ bool WlShellIntegration::mouseMoveEvent(QMouseEvent *event) QSize newSize = m_shellSurface->sizeForResize(resizeState.initialSize, delta, resizeState.resizeEdges); m_shellSurface->sendConfigure(newSize, resizeState.resizeEdges); } else if (grabberState == GrabberState::Move) { - Q_ASSERT(moveState.inputDevice == m_item->compositor()->inputDeviceFor(event)); + Q_ASSERT(moveState.seat == m_item->compositor()->seatFor(event)); QQuickItem *moveItem = m_item->moveItem(); if (!moveState.initialized) { moveState.initialOffset = moveItem->mapFromItem(nullptr, event->windowPos()); diff --git a/src/compositor/extensions/qwaylandwlshellintegration_p.h b/src/compositor/extensions/qwaylandwlshellintegration_p.h index 3f063af39..f68040cdf 100644 --- a/src/compositor/extensions/qwaylandwlshellintegration_p.h +++ b/src/compositor/extensions/qwaylandwlshellintegration_p.h @@ -65,11 +65,11 @@ public: bool mouseReleaseEvent(QMouseEvent *event) Q_DECL_OVERRIDE; private Q_SLOTS: - void handleStartMove(QWaylandInputDevice *inputDevice); - void handleStartResize(QWaylandInputDevice *inputDevice, QWaylandWlShellSurface::ResizeEdge edges); - void handleSetPopup(QWaylandInputDevice *inputDevice, QWaylandSurface *parent, const QPoint &relativeToParent); + void handleStartMove(QWaylandSeat *seat); + void handleStartResize(QWaylandSeat *seat, QWaylandWlShellSurface::ResizeEdge edges); + void handleSetPopup(QWaylandSeat *seat, QWaylandSurface *parent, const QPoint &relativeToParent); void handleShellSurfaceDestroyed(); - void handleSurfaceUnmapped(); + void handleSurfaceHasContentChanged(); void adjustOffsetForNextFrame(const QPointF &offset); private: @@ -88,12 +88,12 @@ private: QWaylandWlShellSurface *m_shellSurface; GrabberState grabberState; struct { - QWaylandInputDevice *inputDevice; + QWaylandSeat *seat; QPointF initialOffset; bool initialized; } moveState; struct { - QWaylandInputDevice *inputDevice; + QWaylandSeat *seat; QWaylandWlShellSurface::ResizeEdge resizeEdges; QSizeF initialSize; QPointF initialMousePos; diff --git a/src/compositor/extensions/qwaylandxdgshell.cpp b/src/compositor/extensions/qwaylandxdgshell.cpp index b5346036a..ab2c60ecc 100644 --- a/src/compositor/extensions/qwaylandxdgshell.cpp +++ b/src/compositor/extensions/qwaylandxdgshell.cpp @@ -36,13 +36,16 @@ #include "qwaylandxdgshell.h" #include "qwaylandxdgshell_p.h" + +#ifdef QT_WAYLAND_COMPOSITOR_QUICK #include "qwaylandxdgshellintegration_p.h" +#endif #include <QtWaylandCompositor/QWaylandCompositor> #include <QtWaylandCompositor/QWaylandSurface> #include <QtWaylandCompositor/QWaylandSurfaceRole> #include <QtWaylandCompositor/QWaylandResource> -#include <QtWaylandCompositor/QWaylandInputDevice> +#include <QtWaylandCompositor/QWaylandSeat> #include <QtCore/QObject> @@ -147,11 +150,11 @@ void QWaylandXdgShellPrivate::xdg_shell_get_xdg_surface(Resource *resource, uint QWaylandResource xdgSurfaceResource(wl_resource_create(resource->client(), &xdg_surface_interface, wl_resource_get_version(resource->handle), id)); - emit q->createXdgSurface(surface, xdgSurfaceResource); + emit q->xdgSurfaceRequested(surface, xdgSurfaceResource); QWaylandXdgSurface *xdgSurface = QWaylandXdgSurface::fromResource(xdgSurfaceResource.resource()); if (!xdgSurface) { - // A QWaylandXdgSurface was not created in response to the createXdgSurface signal, so we + // A QWaylandXdgSurface was not created in response to the xdgSurfaceRequested signal, so we // create one as fallback here instead. xdgSurface = new QWaylandXdgSurface(q, surface, xdgSurfaceResource); } @@ -171,7 +174,7 @@ void QWaylandXdgShellPrivate::xdg_shell_use_unstable_version(Resource *resource, void QWaylandXdgShellPrivate::xdg_shell_get_xdg_popup(Resource *resource, uint32_t id, wl_resource *surface_res, wl_resource *parent, - wl_resource *seat, uint32_t serial, + wl_resource *seatResource, uint32_t serial, int32_t x, int32_t y) { Q_UNUSED(serial); @@ -191,15 +194,15 @@ void QWaylandXdgShellPrivate::xdg_shell_get_xdg_popup(Resource *resource, uint32 QWaylandResource xdgPopupResource (wl_resource_create(resource->client(), &xdg_popup_interface, wl_resource_get_version(resource->handle), id)); - QWaylandInputDevice *inputDevice = QWaylandInputDevice::fromSeatResource(seat); + QWaylandSeat *seat = QWaylandSeat::fromSeatResource(seatResource); QPoint position(x, y); - emit q->createXdgPopup(surface, parentSurface, inputDevice, position, xdgPopupResource); + emit q->xdgPopupRequested(surface, parentSurface, seat, position, xdgPopupResource); QWaylandXdgPopup *xdgPopup = QWaylandXdgPopup::fromResource(xdgPopupResource.resource()); if (!xdgPopup) { - // A QWaylandXdgPopup was not created in response to the createXdgPopup signal, so we + // A QWaylandXdgPopup was not created in response to the xdgPopupRequested signal, so we // create one as fallback here instead. - xdgPopup = new QWaylandXdgPopup(q, surface, parentSurface, xdgPopupResource); + xdgPopup = new QWaylandXdgPopup(q, surface, parentSurface, position, xdgPopupResource); } registerXdgPopup(xdgPopup); @@ -221,6 +224,7 @@ QWaylandXdgSurfacePrivate::QWaylandXdgSurfacePrivate() , xdg_surface() , m_surface(nullptr) , m_parentSurface(nullptr) + , m_windowType(UnknownWindowType) , m_unsetWindowGeometry(true) , m_lastAckedConfigure({{}, QSize(0, 0), 0}) { @@ -246,6 +250,27 @@ void QWaylandXdgSurfacePrivate::handleFocusReceived() q->sendConfigure(current.size, current.states); } +QRect QWaylandXdgSurfacePrivate::calculateFallbackWindowGeometry() const +{ + // TODO: The unset window geometry should include subsurfaces as well, so this solution + // won't work too well on those kinds of clients. + return QRect(QPoint(0, 0), m_surface->size() / m_surface->bufferScale()); +} + +void QWaylandXdgSurfacePrivate::updateFallbackWindowGeometry() +{ + Q_Q(QWaylandXdgSurface); + if (!m_unsetWindowGeometry) + return; + + const QRect unsetGeometry = calculateFallbackWindowGeometry(); + if (unsetGeometry == m_windowGeometry) + return; + + m_windowGeometry = unsetGeometry; + emit q->windowGeometryChanged(); +} + void QWaylandXdgSurfacePrivate::xdg_surface_destroy_resource(Resource *resource) { Q_UNUSED(resource); @@ -265,7 +290,7 @@ void QWaylandXdgSurfacePrivate::xdg_surface_move(Resource *resource, wl_resource Q_UNUSED(serial); Q_Q(QWaylandXdgSurface); - QWaylandInputDevice *input_device = QWaylandInputDevice::fromSeatResource(seat); + QWaylandSeat *input_device = QWaylandSeat::fromSeatResource(seat); emit q->startMove(input_device); } @@ -276,7 +301,7 @@ void QWaylandXdgSurfacePrivate::xdg_surface_resize(Resource *resource, wl_resour Q_UNUSED(serial); Q_Q(QWaylandXdgSurface); - QWaylandInputDevice *input_device = QWaylandInputDevice::fromSeatResource(seat); + QWaylandSeat *input_device = QWaylandSeat::fromSeatResource(seat); emit q->startResize(input_device, QWaylandXdgSurface::ResizeEdge(edges)); } @@ -325,12 +350,22 @@ void QWaylandXdgSurfacePrivate::xdg_surface_set_parent(Resource *resource, wl_re QWaylandXdgSurfacePrivate::Resource::fromResource(parent)->xdg_surface_object)->q_func(); } - if (m_parentSurface == parentSurface) - return; - Q_Q(QWaylandXdgSurface); - m_parentSurface = parentSurface; - emit q->parentSurfaceChanged(); + + if (m_parentSurface != parentSurface) { + m_parentSurface = parentSurface; + emit q->parentSurfaceChanged(); + } + + if (m_parentSurface && m_windowType != TransientWindowType) { + // There's a parent now, which means the surface is transient + m_windowType = TransientWindowType; + emit q->setTransient(); + } else if (!m_parentSurface && m_windowType != TopLevelWindowType) { + // When the surface has no parent it is toplevel + m_windowType = TopLevelWindowType; + emit q->setTopLevel(); + } } void QWaylandXdgSurfacePrivate::xdg_surface_set_app_id(Resource *resource, const QString &app_id) @@ -343,15 +378,15 @@ void QWaylandXdgSurfacePrivate::xdg_surface_set_app_id(Resource *resource, const emit q->appIdChanged(); } -void QWaylandXdgSurfacePrivate::xdg_surface_show_window_menu(Resource *resource, wl_resource *seat, +void QWaylandXdgSurfacePrivate::xdg_surface_show_window_menu(Resource *resource, wl_resource *seatResource, uint32_t serial, int32_t x, int32_t y) { Q_UNUSED(resource); Q_UNUSED(serial); QPoint position(x, y); - auto inputDevice = QWaylandInputDevice::fromSeatResource(seat); + auto seat = QWaylandSeat::fromSeatResource(seatResource); Q_Q(QWaylandXdgSurface); - emit q->showWindowMenu(inputDevice, position); + emit q->showWindowMenu(seat, position); } void QWaylandXdgSurfacePrivate::xdg_surface_ack_configure(Resource *resource, uint32_t serial) @@ -490,10 +525,10 @@ void QWaylandXdgShell::initialize() } d->init(compositor->display(), 1); - handleDefaultInputDeviceChanged(compositor->defaultInputDevice(), nullptr); + handleSeatChanged(compositor->defaultSeat(), nullptr); - connect(compositor, &QWaylandCompositor::defaultInputDeviceChanged, - this, &QWaylandXdgShell::handleDefaultInputDeviceChanged); + connect(compositor, &QWaylandCompositor::defaultSeatChanged, + this, &QWaylandXdgShell::handleSeatChanged); } /*! @@ -548,15 +583,15 @@ void QWaylandXdgShell::closeAllPopups() } } -void QWaylandXdgShell::handleDefaultInputDeviceChanged(QWaylandInputDevice *newDevice, QWaylandInputDevice *oldDevice) +void QWaylandXdgShell::handleSeatChanged(QWaylandSeat *newSeat, QWaylandSeat *oldSeat) { - if (oldDevice != nullptr) { - disconnect(oldDevice, &QWaylandInputDevice::keyboardFocusChanged, + if (oldSeat != nullptr) { + disconnect(oldSeat, &QWaylandSeat::keyboardFocusChanged, this, &QWaylandXdgShell::handleFocusChanged); } - if (newDevice != nullptr) { - connect(newDevice, &QWaylandInputDevice::keyboardFocusChanged, + if (newSeat != nullptr) { + connect(newSeat, &QWaylandSeat::keyboardFocusChanged, this, &QWaylandXdgShell::handleFocusChanged); } } @@ -590,6 +625,20 @@ void QWaylandXdgShell::handleFocusChanged(QWaylandSurface *newSurface, QWaylandS */ /*! + * \qmlsignal QtWaylandCompositor::XdgSurface::setTopLevel() + * + * This signal is emitted when the parent surface is unset, effectively + * making the window top level. + */ + +/*! + * \qmlsignal QtWaylandCompositor::XdgSurface::setTransient() + * + * This signal is emitted when the parent surface is set, effectively + * making the window transient. + */ + +/*! * Constructs a QWaylandXdgSurface. */ QWaylandXdgSurface::QWaylandXdgSurface() @@ -625,8 +674,10 @@ void QWaylandXdgSurface::initialize(QWaylandXdgShell *xdgShell, QWaylandSurface d->m_surface = surface; d->init(resource.resource()); setExtensionContainer(surface); - d->m_windowGeometry = QRect(QPoint(0,0), surface->size()); + d->m_windowGeometry = d->calculateFallbackWindowGeometry(); connect(surface, &QWaylandSurface::sizeChanged, this, &QWaylandXdgSurface::handleSurfaceSizeChanged); + connect(surface, &QWaylandSurface::bufferScaleChanged, this, &QWaylandXdgSurface::handleBufferScaleChanged); + emit shellChanged(); emit surfaceChanged(); emit windowGeometryChanged(); QWaylandCompositorExtension::initialize(); @@ -652,12 +703,30 @@ QList<int> QWaylandXdgSurface::statesAsInts() const void QWaylandXdgSurface::handleSurfaceSizeChanged() { Q_D(QWaylandXdgSurface); - if (d->m_unsetWindowGeometry && d->m_windowGeometry.size() != surface()->size()) { - // TODO: The unset window geometry should include subsurfaces as well, so this solution - // won't work too well on those kinds of clients. - d->m_windowGeometry.setSize(surface()->size()); - emit windowGeometryChanged(); - } + d->updateFallbackWindowGeometry(); +} + +void QWaylandXdgSurface::handleBufferScaleChanged() +{ + Q_D(QWaylandXdgSurface); + d->updateFallbackWindowGeometry(); +} + +/*! + * \qmlproperty object QtWaylandCompositor::XdgSurface::shell + * + * This property holds the shell associated with this XdgSurface. + */ + +/*! + * \property QWaylandXdgSurface::shell + * + * This property holds the shell associated with this QWaylandXdgSurface. + */ +QWaylandXdgShell *QWaylandXdgSurface::shell() const +{ + Q_D(const QWaylandXdgSurface); + return d->m_xdgShell; } /*! @@ -681,12 +750,22 @@ QWaylandSurface *QWaylandXdgSurface::surface() const * \qmlproperty object QtWaylandCompositor::XdgSurface::parentSurface * * This property holds the XdgSurface parent of this XdgSurface. + * When a parent surface is set, the parentSurfaceChanged() signal + * is guaranteed to be emitted before setTopLevel() and setTransient(). + * + * \sa QtWaylandCompositor::XdgSurface::setTopLevel() + * \sa QtWaylandCompositor::XdgSurface::setTransient() */ /*! * \property QWaylandXdgSurface::parentSurface * * This property holds the XdgSurface parent of this XdgSurface. + * When a parent surface is set, the parentSurfaceChanged() signal + * is guaranteed to be emitted before setTopLevel() and setTransient(). + * + * \sa QWaylandXdgSurface::setTopLevel() + * \sa QWaylandXdgSurface::setTransient() */ QWaylandXdgSurface *QWaylandXdgSurface::parentSurface() const { @@ -867,7 +946,7 @@ void QWaylandXdgSurface::sendClose() d->send_close(); } -uint QWaylandXdgSurface::requestMaximized(const QSize &size) +uint QWaylandXdgSurface::sendMaximized(const QSize &size) { Q_D(QWaylandXdgSurface); QWaylandXdgSurfacePrivate::ConfigureEvent conf = d->lastSentConfigure(); @@ -880,7 +959,7 @@ uint QWaylandXdgSurface::requestMaximized(const QSize &size) return sendConfigure(size, conf.states); } -uint QWaylandXdgSurface::requestUnMaximized(const QSize &size) +uint QWaylandXdgSurface::sendUnmaximized(const QSize &size) { Q_D(QWaylandXdgSurface); QWaylandXdgSurfacePrivate::ConfigureEvent conf = d->lastSentConfigure(); @@ -892,7 +971,7 @@ uint QWaylandXdgSurface::requestUnMaximized(const QSize &size) return sendConfigure(size, conf.states); } -uint QWaylandXdgSurface::requestFullscreen(const QSize &size) +uint QWaylandXdgSurface::sendFullscreen(const QSize &size) { Q_D(QWaylandXdgSurface); QWaylandXdgSurfacePrivate::ConfigureEvent conf = d->lastSentConfigure(); @@ -905,7 +984,7 @@ uint QWaylandXdgSurface::requestFullscreen(const QSize &size) return sendConfigure(size, conf.states); } -uint QWaylandXdgSurface::requestResizing(const QSize &maxSize) +uint QWaylandXdgSurface::sendResizing(const QSize &maxSize) { Q_D(QWaylandXdgSurface); QWaylandXdgSurfacePrivate::ConfigureEvent conf = d->lastSentConfigure(); @@ -918,10 +997,12 @@ uint QWaylandXdgSurface::requestResizing(const QSize &maxSize) return sendConfigure(maxSize, conf.states); } +#ifdef QT_WAYLAND_COMPOSITOR_QUICK QWaylandQuickShellIntegration *QWaylandXdgSurface::createIntegration(QWaylandQuickShellSurfaceItem *item) { return new QtWayland::XdgShellIntegration(item); } +#endif /*! * \class QWaylandXdgPopup @@ -940,7 +1021,7 @@ QWaylandQuickShellIntegration *QWaylandXdgSurface::createIntegration(QWaylandQui * Constructs a QWaylandXdgPopup. */ QWaylandXdgPopup::QWaylandXdgPopup() - : QWaylandCompositorExtensionTemplate<QWaylandXdgPopup>(*new QWaylandXdgPopupPrivate) + : QWaylandShellSurfaceTemplate<QWaylandXdgPopup>(*new QWaylandXdgPopupPrivate) { } @@ -949,10 +1030,10 @@ QWaylandXdgPopup::QWaylandXdgPopup() * given \a parentSurface and \a resource. */ QWaylandXdgPopup::QWaylandXdgPopup(QWaylandXdgShell *xdgShell, QWaylandSurface *surface, - QWaylandSurface *parentSurface, const QWaylandResource &resource) - : QWaylandCompositorExtensionTemplate<QWaylandXdgPopup>(*new QWaylandXdgPopupPrivate) + QWaylandSurface *parentSurface, const QPoint &position, const QWaylandResource &resource) + : QWaylandShellSurfaceTemplate<QWaylandXdgPopup>(*new QWaylandXdgPopupPrivate) { - initialize(xdgShell, surface, parentSurface, resource); + initialize(xdgShell, surface, parentSurface, position, resource); } /*! @@ -966,21 +1047,40 @@ QWaylandXdgPopup::QWaylandXdgPopup(QWaylandXdgShell *xdgShell, QWaylandSurface * * Initializes the QWaylandXdgPopup, associating it with the given \a shell \a surface, * \a parentSurface and \a resource. */ -void QWaylandXdgPopup::initialize(QWaylandXdgShell *shell, QWaylandSurface *surface, - QWaylandSurface *parentSurface, const QWaylandResource &resource) +void QWaylandXdgPopup::initialize(QWaylandXdgShell *shell, QWaylandSurface *surface, QWaylandSurface *parentSurface, + const QPoint& position, const QWaylandResource &resource) { Q_D(QWaylandXdgPopup); d->m_surface = surface; d->m_parentSurface = parentSurface; d->m_xdgShell = shell; + d->m_position = position; d->init(resource.resource()); setExtensionContainer(surface); + emit shellChanged(); emit surfaceChanged(); emit parentSurfaceChanged(); QWaylandCompositorExtension::initialize(); } /*! + * \qmlproperty object QtWaylandCompositor::XdgPopup::shell + * + * This property holds the shell associated with this XdgPopup. + */ + +/*! + * \property QWaylandXdgPopup::shell + * + * This property holds the shell associated with this QWaylandXdgPopup. + */ +QWaylandXdgShell *QWaylandXdgPopup::shell() const +{ + Q_D(const QWaylandXdgPopup); + return d->m_xdgShell; +} + +/*! * \qmlproperty object QtWaylandCompositor::XdgPopup::surface * * This property holds the surface associated with this XdgPopup. @@ -1015,12 +1115,34 @@ QWaylandSurface *QWaylandXdgPopup::parentSurface() const return d->m_parentSurface; } + +/*! + * \qmlproperty object QtWaylandCompositor::XdgPopup::position + * + * This property holds the location of the upper left corner of the surface + * relative to the upper left corner of the parent surface, in surface local + * coordinates. + */ + +/*! + * \property QWaylandXdgPopup::position + * + * This property holds the location of the upper left corner of the surface + * relative to the upper left corner of the parent surface, in surface local + * coordinates. + */ +QPoint QWaylandXdgPopup::position() const +{ + Q_D(const QWaylandXdgPopup); + return d->m_position; +} + /*! * \internal */ void QWaylandXdgPopup::initialize() { - QWaylandCompositorExtensionTemplate::initialize(); + QWaylandCompositorExtension::initialize(); } /*! @@ -1058,4 +1180,11 @@ void QWaylandXdgPopup::sendPopupDone() d->send_popup_done(); } +#ifdef QT_WAYLAND_COMPOSITOR_QUICK +QWaylandQuickShellIntegration *QWaylandXdgPopup::createIntegration(QWaylandQuickShellSurfaceItem *item) +{ + return new QtWayland::XdgPopupIntegration(item); +} +#endif + QT_END_NAMESPACE diff --git a/src/compositor/extensions/qwaylandxdgshell.h b/src/compositor/extensions/qwaylandxdgshell.h index c11ca1f3a..4a1ec5d06 100644 --- a/src/compositor/extensions/qwaylandxdgshell.h +++ b/src/compositor/extensions/qwaylandxdgshell.h @@ -55,7 +55,7 @@ class QWaylandXdgPopupPrivate; class QWaylandSurface; class QWaylandSurfaceRole; -class QWaylandInputDevice; +class QWaylandSeat; class QWaylandOutput; class QWaylandClient; @@ -77,14 +77,14 @@ public Q_SLOTS: void closeAllPopups(); Q_SIGNALS: - void createXdgSurface(QWaylandSurface *surface, const QWaylandResource &resource); + void xdgSurfaceRequested(QWaylandSurface *surface, const QWaylandResource &resource); void xdgSurfaceCreated(QWaylandXdgSurface *xdgSurface); void xdgPopupCreated(QWaylandXdgPopup *xdgPopup); - void createXdgPopup(QWaylandSurface *surface, QWaylandSurface *parent, QWaylandInputDevice *seat, const QPoint &position, const QWaylandResource &resource); + void xdgPopupRequested(QWaylandSurface *surface, QWaylandSurface *parent, QWaylandSeat *seat, const QPoint &position, const QWaylandResource &resource); void pong(uint serial); private Q_SLOTS: - void handleDefaultInputDeviceChanged(QWaylandInputDevice *newDevice, QWaylandInputDevice *oldDevice); + void handleSeatChanged(QWaylandSeat *newSeat, QWaylandSeat *oldSeat); void handleFocusChanged(QWaylandSurface *newSurface, QWaylandSurface *oldSurface); }; @@ -93,6 +93,7 @@ class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandXdgSurface : public QWaylandShellSurfa { Q_OBJECT Q_DECLARE_PRIVATE(QWaylandXdgSurface) + Q_PROPERTY(QWaylandXdgShell *shell READ shell NOTIFY shellChanged) Q_PROPERTY(QWaylandSurface *surface READ surface NOTIFY surfaceChanged) Q_PROPERTY(QWaylandXdgSurface *parentSurface READ parentSurface NOTIFY parentSurfaceChanged) Q_PROPERTY(QString title READ title NOTIFY titleChanged) @@ -141,6 +142,8 @@ public: bool resizing() const; bool activated() const; + QWaylandXdgShell *shell() const; + QWaylandSurface *surface() const; QWaylandXdgSurface *parentSurface() const; @@ -154,14 +157,17 @@ public: Q_INVOKABLE uint sendConfigure(const QSize &size, const QVector<State> &states); Q_INVOKABLE void sendClose(); - Q_INVOKABLE uint requestMaximized(const QSize &size); - Q_INVOKABLE uint requestUnMaximized(const QSize &size = QSize(0, 0)); - Q_INVOKABLE uint requestFullscreen(const QSize &size); - Q_INVOKABLE uint requestResizing(const QSize &maxSize); + Q_INVOKABLE uint sendMaximized(const QSize &size); + Q_INVOKABLE uint sendUnmaximized(const QSize &size = QSize(0, 0)); + Q_INVOKABLE uint sendFullscreen(const QSize &size); + Q_INVOKABLE uint sendResizing(const QSize &maxSize); +#ifdef QT_WAYLAND_COMPOSITOR_QUICK QWaylandQuickShellIntegration *createIntegration(QWaylandQuickShellSurfaceItem *item) Q_DECL_OVERRIDE; +#endif Q_SIGNALS: + void shellChanged(); void surfaceChanged(); void titleChanged(); void windowGeometryChanged(); @@ -174,9 +180,11 @@ Q_SIGNALS: void resizingChanged(); void activatedChanged(); - void showWindowMenu(QWaylandInputDevice *inputDevice, const QPoint &localSurfacePosition); - void startMove(QWaylandInputDevice *inputDevice); - void startResize(QWaylandInputDevice *inputDevice, ResizeEdge edges); + void showWindowMenu(QWaylandSeat *seat, const QPoint &localSurfacePosition); + void startMove(QWaylandSeat *seat); + void startResize(QWaylandSeat *seat, ResizeEdge edges); + void setTopLevel(); + void setTransient(); void setMaximized(); void unsetMaximized(); void setFullscreen(QWaylandOutput *output); @@ -190,24 +198,33 @@ private: private Q_SLOTS: void handleSurfaceSizeChanged(); + void handleBufferScaleChanged(); }; -class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandXdgPopup : public QWaylandCompositorExtensionTemplate<QWaylandXdgPopup> +class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandXdgPopup : public QWaylandShellSurfaceTemplate<QWaylandXdgPopup> { Q_OBJECT Q_DECLARE_PRIVATE(QWaylandXdgPopup) + Q_PROPERTY(QWaylandXdgShell *shell READ shell NOTIFY shellChanged) Q_PROPERTY(QWaylandSurface *surface READ surface NOTIFY surfaceChanged) Q_PROPERTY(QWaylandSurface *parentSurface READ parentSurface NOTIFY parentSurfaceChanged) + Q_PROPERTY(QPoint position READ position) public: QWaylandXdgPopup(); - QWaylandXdgPopup(QWaylandXdgShell *xdgShell, QWaylandSurface *surface, QWaylandSurface *parentSurface, const QWaylandResource &resource); + QWaylandXdgPopup(QWaylandXdgShell *xdgShell, QWaylandSurface *surface, QWaylandSurface *parentSurface, + const QPoint &position, const QWaylandResource &resource); + + Qt::WindowType windowType() const override { return Qt::WindowType::Popup; } Q_INVOKABLE void initialize(QWaylandXdgShell *shell, QWaylandSurface *surface, - QWaylandSurface *parentSurface, const QWaylandResource &resource); + QWaylandSurface *parentSurface, const QPoint &position, const QWaylandResource &resource); + + QWaylandXdgShell *shell() const; QWaylandSurface *surface() const; QWaylandSurface *parentSurface() const; + QPoint position() const; static const struct wl_interface *interface(); static QByteArray interfaceName(); @@ -216,7 +233,12 @@ public: Q_INVOKABLE void sendPopupDone(); +#ifdef QT_WAYLAND_COMPOSITOR_QUICK + QWaylandQuickShellIntegration *createIntegration(QWaylandQuickShellSurfaceItem *item) Q_DECL_OVERRIDE; +#endif + Q_SIGNALS: + void shellChanged(); void surfaceChanged(); void parentSurfaceChanged(); diff --git a/src/compositor/extensions/qwaylandxdgshell_p.h b/src/compositor/extensions/qwaylandxdgshell_p.h index 3165eb7ca..d7244c704 100644 --- a/src/compositor/extensions/qwaylandxdgshell_p.h +++ b/src/compositor/extensions/qwaylandxdgshell_p.h @@ -73,19 +73,19 @@ public: bool isValidPopupParent(QWaylandSurface *parentSurface) const; QWaylandXdgPopup *topmostPopupForClient(struct wl_client* client) const; -private: QSet<uint32_t> m_pings; QMultiMap<struct wl_client *, QWaylandXdgSurface *> m_xdgSurfaces; QMultiMap<struct wl_client *, QWaylandXdgPopup *> m_xdgPopups; QWaylandXdgSurface *xdgSurfaceFromSurface(QWaylandSurface *surface); +protected: void xdg_shell_destroy(Resource *resource) Q_DECL_OVERRIDE; void xdg_shell_get_xdg_surface(Resource *resource, uint32_t id, struct ::wl_resource *surface) Q_DECL_OVERRIDE; void xdg_shell_use_unstable_version(Resource *resource, int32_t version) Q_DECL_OVERRIDE; void xdg_shell_get_xdg_popup(Resource *resource, uint32_t id, struct ::wl_resource *surface, - struct ::wl_resource *parent, struct ::wl_resource *seat, + struct ::wl_resource *parent, struct ::wl_resource *seatResource, uint32_t serial, int32_t x, int32_t y) Q_DECL_OVERRIDE; void xdg_shell_pong(Resource *resource, uint32_t serial) Q_DECL_OVERRIDE; }; @@ -99,6 +99,12 @@ public: QWaylandXdgSurfacePrivate(); static QWaylandXdgSurfacePrivate *get(QWaylandXdgSurface *xdgSurface) { return xdgSurface->d_func(); } + enum WindowType { + UnknownWindowType, + TopLevelWindowType, + TransientWindowType + }; + struct ConfigureEvent { QVector<uint> states; QSize size; @@ -107,12 +113,16 @@ public: void handleFocusLost(); void handleFocusReceived(); + QRect calculateFallbackWindowGeometry() const; + void updateFallbackWindowGeometry(); private: QWaylandXdgShell *m_xdgShell; QWaylandSurface *m_surface; QWaylandXdgSurface *m_parentSurface; + WindowType m_windowType; + QString m_title; QString m_appId; QRect m_windowGeometry; @@ -137,7 +147,7 @@ private: void xdg_surface_set_minimized(Resource *resource) Q_DECL_OVERRIDE; void xdg_surface_set_parent(Resource *resource, struct ::wl_resource *parent) Q_DECL_OVERRIDE; void xdg_surface_set_app_id(Resource *resource, const QString &app_id) Q_DECL_OVERRIDE; - void xdg_surface_show_window_menu(Resource *resource, struct ::wl_resource *seat, + void xdg_surface_show_window_menu(Resource *resource, struct ::wl_resource *seatResource, uint32_t serial, int32_t x, int32_t y) Q_DECL_OVERRIDE; void xdg_surface_ack_configure(Resource *resource, uint32_t serial) Q_DECL_OVERRIDE; void xdg_surface_set_title(Resource *resource, const QString &title) Q_DECL_OVERRIDE; @@ -157,10 +167,10 @@ public: QWaylandXdgPopupPrivate(); static QWaylandXdgPopupPrivate *get(QWaylandXdgPopup *xdgPopup) { return xdgPopup->d_func(); } -private: QWaylandSurface *m_surface; QWaylandSurface *m_parentSurface; QWaylandXdgShell *m_xdgShell; + QPoint m_position; void xdg_popup_destroy_resource(Resource *resource) Q_DECL_OVERRIDE; void xdg_popup_destroy(xdg_popup::Resource *resource) Q_DECL_OVERRIDE; diff --git a/src/compositor/extensions/qwaylandxdgshellintegration.cpp b/src/compositor/extensions/qwaylandxdgshellintegration.cpp index ab10011e6..90c7a7b36 100644 --- a/src/compositor/extensions/qwaylandxdgshellintegration.cpp +++ b/src/compositor/extensions/qwaylandxdgshellintegration.cpp @@ -38,8 +38,10 @@ #include <QtWaylandCompositor/QWaylandQuickShellSurfaceItem> #include <QtWaylandCompositor/QWaylandCompositor> -#include <QtWaylandCompositor/QWaylandInputDevice> +#include <QtWaylandCompositor/QWaylandSeat> +#include <QtWaylandCompositor/private/qwaylandxdgshell_p.h> #include <QMouseEvent> +#include <QGuiApplication> QT_BEGIN_NAMESPACE @@ -64,18 +66,17 @@ XdgShellIntegration::XdgShellIntegration(QWaylandQuickShellSurfaceItem *item) bool XdgShellIntegration::mouseMoveEvent(QMouseEvent *event) { if (grabberState == GrabberState::Resize) { - Q_ASSERT(resizeState.inputDevice == m_item->compositor()->inputDeviceFor(event)); + Q_ASSERT(resizeState.seat == m_item->compositor()->seatFor(event)); if (!resizeState.initialized) { resizeState.initialMousePos = event->windowPos(); resizeState.initialized = true; return true; } - float scaleFactor = m_item->view()->output()->scaleFactor(); - QPointF delta = (event->windowPos() - resizeState.initialMousePos) / scaleFactor; + QPointF delta = m_item->mapToSurface(event->windowPos() - resizeState.initialMousePos); QSize newSize = m_xdgSurface->sizeForResize(resizeState.initialWindowSize, delta, resizeState.resizeEdges); - m_xdgSurface->requestResizing(newSize); + m_xdgSurface->sendResizing(newSize); } else if (grabberState == GrabberState::Move) { - Q_ASSERT(moveState.inputDevice == m_item->compositor()->inputDeviceFor(event)); + Q_ASSERT(moveState.seat == m_item->compositor()->seatFor(event)); QQuickItem *moveItem = m_item->moveItem(); if (!moveState.initialized) { moveState.initialOffset = moveItem->mapFromItem(nullptr, event->windowPos()); @@ -95,7 +96,7 @@ bool XdgShellIntegration::mouseReleaseEvent(QMouseEvent *event) Q_UNUSED(event); if (grabberState == GrabberState::Resize) { - m_xdgSurface->requestUnMaximized(); + m_xdgSurface->sendUnmaximized(); grabberState = GrabberState::Default; return true; } else if (grabberState == GrabberState::Move) { @@ -105,20 +106,20 @@ bool XdgShellIntegration::mouseReleaseEvent(QMouseEvent *event) return false; } -void XdgShellIntegration::handleStartMove(QWaylandInputDevice *inputDevice) +void XdgShellIntegration::handleStartMove(QWaylandSeat *seat) { grabberState = GrabberState::Move; - moveState.inputDevice = inputDevice; + moveState.seat = seat; moveState.initialized = false; } -void XdgShellIntegration::handleStartResize(QWaylandInputDevice *inputDevice, QWaylandXdgSurface::ResizeEdge edges) +void XdgShellIntegration::handleStartResize(QWaylandSeat *seat, QWaylandXdgSurface::ResizeEdge edges) { grabberState = GrabberState::Resize; - resizeState.inputDevice = inputDevice; + resizeState.seat = seat; resizeState.resizeEdges = edges; resizeState.initialWindowSize = m_xdgSurface->windowGeometry().size(); - resizeState.initialPosition = m_item->position(); + resizeState.initialPosition = m_item->moveItem()->position(); resizeState.initialSurfaceSize = m_item->surface()->size(); resizeState.initialized = false; } @@ -126,24 +127,24 @@ void XdgShellIntegration::handleStartResize(QWaylandInputDevice *inputDevice, QW void XdgShellIntegration::handleSetMaximized() { maximizeState.initialWindowSize = m_xdgSurface->windowGeometry().size(); - maximizeState.initialPosition = m_item->position(); + maximizeState.initialPosition = m_item->moveItem()->position(); - QWaylandOutput *output = m_item->compositor()->outputs().first(); - m_xdgSurface->requestMaximized(output->geometry().size() / output->scaleFactor()); + QWaylandOutput *output = m_item->view()->output(); + m_xdgSurface->sendMaximized(output->availableGeometry().size() / output->scaleFactor()); } void XdgShellIntegration::handleUnsetMaximized() { - m_xdgSurface->requestUnMaximized(maximizeState.initialWindowSize); + m_xdgSurface->sendUnmaximized(maximizeState.initialWindowSize); } void XdgShellIntegration::handleMaximizedChanged() { if (m_xdgSurface->maximized()) { - QWaylandOutput *output = m_item->compositor()->outputs().first(); - m_item->setPosition(output->geometry().topLeft()); + QWaylandOutput *output = m_item->view()->output(); + m_item->moveItem()->setPosition(output->position() + output->availableGeometry().topLeft()); } else { - m_item->setPosition(maximizeState.initialPosition); + m_item->moveItem()->setPosition(maximizeState.initialPosition); } } @@ -163,10 +164,32 @@ void XdgShellIntegration::handleSurfaceSizeChanged() if (resizeState.resizeEdges & QWaylandXdgSurface::ResizeEdge::LeftEdge) x += resizeState.initialSurfaceSize.width() - m_item->surface()->size().width(); - m_item->setPosition(QPointF(x, y)); + m_item->moveItem()->setPosition(QPointF(x, y)); } } +XdgPopupIntegration::XdgPopupIntegration(QWaylandQuickShellSurfaceItem *item) + : QWaylandQuickShellIntegration (item) + , m_xdgPopup(qobject_cast<QWaylandXdgPopup *>(item->shellSurface())) + , m_xdgShell(QWaylandXdgPopupPrivate::get(m_xdgPopup)->m_xdgShell) +{ + item->setSurface(m_xdgPopup->surface()); + item->moveItem()->setPosition(QPointF(m_xdgPopup->position() * item->view()->output()->scaleFactor())); + + QWaylandClient *client = m_xdgPopup->surface()->client(); + QWaylandQuickShellEventFilter::startFilter(client, [&]() { m_xdgShell->closeAllPopups(); }); + + connect(m_xdgPopup, &QWaylandXdgPopup::destroyed, this, &XdgPopupIntegration::handlePopupDestroyed); +} + +void XdgPopupIntegration::handlePopupDestroyed() +{ + QWaylandXdgShellPrivate *shellPrivate = QWaylandXdgShellPrivate::get(m_xdgShell); + auto popups = shellPrivate->m_xdgPopups; + if (popups.isEmpty()) + QWaylandQuickShellEventFilter::cancelFilter(); +} + } QT_END_NAMESPACE diff --git a/src/compositor/extensions/qwaylandxdgshellintegration_p.h b/src/compositor/extensions/qwaylandxdgshellintegration_p.h index df2fa8b8d..8a000ff6a 100644 --- a/src/compositor/extensions/qwaylandxdgshellintegration_p.h +++ b/src/compositor/extensions/qwaylandxdgshellintegration_p.h @@ -64,8 +64,8 @@ public: bool mouseReleaseEvent(QMouseEvent *event) Q_DECL_OVERRIDE; private Q_SLOTS: - void handleStartMove(QWaylandInputDevice *inputDevice); - void handleStartResize(QWaylandInputDevice *inputDevice, QWaylandXdgSurface::ResizeEdge edges); + void handleStartMove(QWaylandSeat *seat); + void handleStartResize(QWaylandSeat *seat, QWaylandXdgSurface::ResizeEdge edges); void handleSetMaximized(); void handleUnsetMaximized(); void handleMaximizedChanged(); @@ -83,13 +83,13 @@ private: GrabberState grabberState; struct { - QWaylandInputDevice *inputDevice; + QWaylandSeat *seat; QPointF initialOffset; bool initialized; } moveState; struct { - QWaylandInputDevice *inputDevice; + QWaylandSeat *seat; QWaylandXdgSurface::ResizeEdge resizeEdges; QSizeF initialWindowSize; QPointF initialMousePos; @@ -104,6 +104,20 @@ private: } maximizeState; }; +class XdgPopupIntegration : public QWaylandQuickShellIntegration +{ + Q_OBJECT +public: + XdgPopupIntegration(QWaylandQuickShellSurfaceItem *item); + +private Q_SLOTS: + void handlePopupDestroyed(); + +private: + QWaylandXdgPopup *m_xdgPopup; + QWaylandXdgShell *m_xdgShell; +}; + } QT_END_NAMESPACE diff --git a/src/compositor/global/qwaylandcompositorextension.cpp b/src/compositor/global/qwaylandcompositorextension.cpp index ddfd25837..6c7577ffc 100644 --- a/src/compositor/global/qwaylandcompositorextension.cpp +++ b/src/compositor/global/qwaylandcompositorextension.cpp @@ -96,6 +96,12 @@ void QWaylandCompositorExtension::initialize() return; } + if (!d->extension_container && parent()) { + QWaylandObject *parentObj = qobject_cast<QWaylandObject*>(parent()); + if (parentObj) + setExtensionContainer(parentObj); + } + if (!d->extension_container) { qWarning() << "QWaylandCompositorExtension:" << extensionInterface()->name << "requests to initialize with no extension container set"; return; diff --git a/src/compositor/global/qwaylandcompositorextension.h b/src/compositor/global/qwaylandcompositorextension.h index 0ba54c882..d666b4f2a 100644 --- a/src/compositor/global/qwaylandcompositorextension.h +++ b/src/compositor/global/qwaylandcompositorextension.h @@ -52,6 +52,7 @@ class QWaylandCompositorExtensionPrivate; class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandObject : public QObject { + Q_OBJECT public: virtual ~QWaylandObject(); diff --git a/src/compositor/global/qwaylandquickextension.h b/src/compositor/global/qwaylandquickextension.h index 32f4e6527..63c3d135e 100644 --- a/src/compositor/global/qwaylandquickextension.h +++ b/src/compositor/global/qwaylandquickextension.h @@ -50,6 +50,7 @@ QT_BEGIN_NAMESPACE Q_OBJECT \ Q_PROPERTY(QQmlListProperty<QObject> data READ data DESIGNABLE false) \ Q_CLASSINFO("DefaultProperty", "data") \ + Q_INTERFACES(QQmlParserStatus) \ public: \ QQmlListProperty<QObject> data() \ { \ diff --git a/src/compositor/hardware_integration/hardware_integration.pri b/src/compositor/hardware_integration/hardware_integration.pri index 2737a6f07..624190a6e 100644 --- a/src/compositor/hardware_integration/hardware_integration.pri +++ b/src/compositor/hardware_integration/hardware_integration.pri @@ -1,6 +1,4 @@ -isEmpty(QT_WAYLAND_GL_CONFIG):QT_WAYLAND_GL_CONFIG = $$(QT_WAYLAND_GL_CONFIG) - -!isEqual(QT_WAYLAND_GL_CONFIG,nogl) { +contains(QT_CONFIG, opengl) { CONFIG += wayland-scanner WAYLANDSERVERSOURCES += \ ../extensions/server-buffer-extension.xml \ @@ -24,7 +22,7 @@ isEmpty(QT_WAYLAND_GL_CONFIG):QT_WAYLAND_GL_CONFIG = $$(QT_WAYLAND_GL_CONFIG) hardware_integration/qwlserverbufferintegrationplugin.cpp \ hardware_integration/qwlhwintegration.cpp \ - DEFINES += QT_COMPOSITOR_WAYLAND_GL + DEFINES += QT_WAYLAND_COMPOSITOR_GL } else { system(echo "Qt-Compositor configured as raster only compositor") } diff --git a/src/compositor/wayland_wrapper/qwldatadevice.cpp b/src/compositor/wayland_wrapper/qwldatadevice.cpp index dea72bdcd..0d196b82e 100644 --- a/src/compositor/wayland_wrapper/qwldatadevice.cpp +++ b/src/compositor/wayland_wrapper/qwldatadevice.cpp @@ -45,7 +45,7 @@ #include "qwaylandview.h" #include <QtWaylandCompositor/QWaylandClient> #include <QtWaylandCompositor/private/qwaylandcompositor_p.h> -#include <QtWaylandCompositor/private/qwaylandinput_p.h> +#include <QtWaylandCompositor/private/qwaylandseat_p.h> #include <QtWaylandCompositor/private/qwaylandpointer_p.h> #include <QtCore/QPointF> @@ -55,16 +55,17 @@ QT_BEGIN_NAMESPACE namespace QtWayland { -DataDevice::DataDevice(QWaylandInputDevice *inputDevice) +DataDevice::DataDevice(QWaylandSeat *seat) : wl_data_device() - , m_compositor(inputDevice->compositor()) - , m_inputDevice(inputDevice) + , m_compositor(seat->compositor()) + , m_seat(seat) , m_selectionSource(0) , m_dragClient(0) , m_dragDataSource(0) , m_dragFocus(0) , m_dragFocusResource(0) , m_dragIcon(0) + , m_dragOrigin(nullptr) { } @@ -123,6 +124,11 @@ QWaylandSurface *DataDevice::dragIcon() const return m_dragIcon; } +QWaylandSurface *DataDevice::dragOrigin() const +{ + return m_dragOrigin; +} + void DataDevice::sourceDestroyed(DataSource *source) { if (m_selectionSource == source) @@ -148,6 +154,7 @@ void DataDevice::drop() } else { m_dragDataSource->cancel(); } + m_dragOrigin = nullptr; setDragIcon(nullptr); } @@ -160,11 +167,13 @@ void DataDevice::data_device_start_drag(Resource *resource, struct ::wl_resource { m_dragClient = resource->client(); m_dragDataSource = source ? DataSource::fromResource(source) : 0; + m_dragOrigin = QWaylandSurface::fromResource(origin); + QWaylandDrag *drag = m_seat->drag(); setDragIcon(icon ? QWaylandSurface::fromResource(icon) : nullptr); - Q_EMIT m_inputDevice->drag()->dragStarted(); + Q_EMIT drag->dragStarted(); + Q_EMIT m_dragOrigin->dragStarted(drag); Q_UNUSED(serial); - Q_UNUSED(origin); //### need to verify that we have an implicit grab with this serial } @@ -182,7 +191,7 @@ void DataDevice::data_device_set_selection(Resource *, struct ::wl_resource *sou if (m_selectionSource) m_selectionSource->setDevice(this); - QWaylandClient *focusClient = m_inputDevice->keyboard()->focusClient(); + QWaylandClient *focusClient = m_seat->keyboard()->focusClient(); Resource *resource = focusClient ? resourceMap().value(focusClient->client()) : 0; if (resource && m_selectionSource) { @@ -198,7 +207,7 @@ void DataDevice::setDragIcon(QWaylandSurface *icon) if (icon == m_dragIcon) return; m_dragIcon = icon; - Q_EMIT m_inputDevice->drag()->iconChanged(); + Q_EMIT m_seat->drag()->iconChanged(); } } diff --git a/src/compositor/wayland_wrapper/qwldatadevice_p.h b/src/compositor/wayland_wrapper/qwldatadevice_p.h index 2127603a8..17591ae27 100644 --- a/src/compositor/wayland_wrapper/qwldatadevice_p.h +++ b/src/compositor/wayland_wrapper/qwldatadevice_p.h @@ -49,7 +49,7 @@ // #include <QtWaylandCompositor/private/qwayland-server-wayland.h> -#include <QtWaylandCompositor/QWaylandInputDevice> +#include <QtWaylandCompositor/QWaylandSeat> QT_BEGIN_NAMESPACE @@ -57,19 +57,20 @@ namespace QtWayland { class Compositor; class DataSource; -class InputDevice; +class Seat; class Surface; class DataDevice : public QtWaylandServer::wl_data_device { public: - DataDevice(QWaylandInputDevice *inputDevice); + DataDevice(QWaylandSeat *seat); void setFocus(QWaylandClient *client); void setDragFocus(QWaylandSurface *focus, const QPointF &localPosition); QWaylandSurface *dragIcon() const; + QWaylandSurface *dragOrigin() const; void sourceDestroyed(DataSource *source); @@ -85,7 +86,7 @@ private: void setDragIcon(QWaylandSurface *icon); QWaylandCompositor *m_compositor; - QWaylandInputDevice *m_inputDevice; + QWaylandSeat *m_seat; DataSource *m_selectionSource; @@ -96,6 +97,7 @@ private: Resource *m_dragFocusResource; QWaylandSurface *m_dragIcon; + QWaylandSurface *m_dragOrigin; }; } diff --git a/src/compositor/wayland_wrapper/qwldatadevicemanager.cpp b/src/compositor/wayland_wrapper/qwldatadevicemanager.cpp index 2f40b0e43..5fed6ef18 100644 --- a/src/compositor/wayland_wrapper/qwldatadevicemanager.cpp +++ b/src/compositor/wayland_wrapper/qwldatadevicemanager.cpp @@ -39,7 +39,7 @@ #include <QtWaylandCompositor/QWaylandCompositor> #include <QtWaylandCompositor/private/qwaylandcompositor_p.h> -#include <QtWaylandCompositor/private/qwaylandinput_p.h> +#include <QtWaylandCompositor/private/qwaylandseat_p.h> #include "qwldatadevice_p.h" #include "qwldatasource_p.h" #include "qwldataoffer_p.h" @@ -199,11 +199,11 @@ void DataDeviceManager::overrideSelection(const QMimeData &mimeData) m_compositorOwnsSelection = true; - QWaylandInputDevice *dev = m_compositor->defaultInputDevice(); + QWaylandSeat *dev = m_compositor->defaultSeat(); QWaylandSurface *focusSurface = dev->keyboardFocus(); if (focusSurface) offerFromCompositorToClient( - QWaylandInputDevicePrivate::get(dev)->dataDevice()->resourceMap().value(focusSurface->waylandClient())->handle); + QWaylandSeatPrivate::get(dev)->dataDevice()->resourceMap().value(focusSurface->waylandClient())->handle); } bool DataDeviceManager::offerFromCompositorToClient(wl_resource *clientDataDeviceResource) @@ -243,8 +243,8 @@ void DataDeviceManager::data_device_manager_create_data_source(Resource *resourc void DataDeviceManager::data_device_manager_get_data_device(Resource *resource, uint32_t id, struct ::wl_resource *seat) { - QWaylandInputDevice *input_device = QWaylandInputDevice::fromSeatResource(seat); - QWaylandInputDevicePrivate::get(input_device)->clientRequestedDataDevice(this, resource->client(), id); + QWaylandSeat *input_device = QWaylandSeat::fromSeatResource(seat); + QWaylandSeatPrivate::get(input_device)->clientRequestedDataDevice(this, resource->client(), id); } void DataDeviceManager::comp_accept(wl_client *, wl_resource *, uint32_t, const char *) diff --git a/src/compositor/wayland_wrapper/qwlsurfacebuffer.cpp b/src/compositor/wayland_wrapper/qwlsurfacebuffer.cpp index 240ce01bc..df2dded2f 100644 --- a/src/compositor/wayland_wrapper/qwlsurfacebuffer.cpp +++ b/src/compositor/wayland_wrapper/qwlsurfacebuffer.cpp @@ -36,7 +36,7 @@ #include "qwlsurfacebuffer_p.h" -#ifdef QT_COMPOSITOR_WAYLAND_GL +#ifdef QT_WAYLAND_COMPOSITOR_GL #include "hardware_integration/qwlclientbufferintegration_p.h" #include <qpa/qplatformopenglcontext.h> #endif @@ -44,7 +44,7 @@ #include <QtCore/QDebug> #include <wayland-server-protocol.h> -#include "qwaylandshmformathelper_p.h" +#include "qwaylandsharedmemoryformathelper_p.h" #include <QtWaylandCompositor/private/qwaylandcompositor_p.h> @@ -83,8 +83,10 @@ void SurfaceBuffer::initialize(struct ::wl_resource *buffer) m_destroy_listener.surfaceBuffer = this; m_destroy_listener.listener.notify = destroy_listener_callback; if (buffer) { +#ifdef QT_WAYLAND_COMPOSITOR_GL if (ClientBufferIntegration *integration = QWaylandCompositorPrivate::get(m_compositor)->clientBufferIntegration()) integration->initializeBuffer(buffer); +#endif wl_signal_add(&buffer->destroy_signal, &m_destroy_listener.listener); } } @@ -167,22 +169,26 @@ QSize SurfaceBuffer::size() const int height = wl_shm_buffer_get_height(shmBuffer); return QSize(width, height); } +#ifdef QT_WAYLAND_COMPOSITOR_GL if (ClientBufferIntegration *integration = QWaylandCompositorPrivate::get(m_compositor)->clientBufferIntegration()) { return integration->bufferSize(m_buffer); } +#endif return QSize(); } QWaylandSurface::Origin SurfaceBuffer::origin() const { - if (isShm()) { + if (isSharedMemory()) { return QWaylandSurface::OriginTopLeft; } +#ifdef QT_WAYLAND_COMPOSITOR_GL if (ClientBufferIntegration *integration = QWaylandCompositorPrivate::get(m_compositor)->clientBufferIntegration()) { return integration->origin(m_buffer); } +#endif return QWaylandSurface::OriginTopLeft; } @@ -201,18 +207,21 @@ QImage SurfaceBuffer::image() const QWaylandBufferRef::BufferFormatEgl SurfaceBuffer::bufferFormatEgl() const { - Q_ASSERT(isShm() == false); + Q_ASSERT(isSharedMemory() == false); +#ifdef QT_WAYLAND_COMPOSITOR_GL if (QtWayland::ClientBufferIntegration *clientInt = QWaylandCompositorPrivate::get(m_compositor)->clientBufferIntegration()) return clientInt->bufferFormat(m_buffer); +#endif return QWaylandBufferRef::BufferFormatEgl_Null; } +#ifdef QT_WAYLAND_COMPOSITOR_GL void SurfaceBuffer::bindToTexture() const { Q_ASSERT(m_compositor); - if (isShm()) { + if (isSharedMemory()) { QImage image = this->image(); if (image.hasAlphaChannel()) { if (image.format() != QImage::Format_RGBA8888) { @@ -245,6 +254,7 @@ void SurfaceBuffer::updateTexture() const if (QtWayland::ClientBufferIntegration *clientInt = QWaylandCompositorPrivate::get(m_compositor)->clientBufferIntegration()) clientInt->updateTextureForBuffer(m_buffer); } +#endif } diff --git a/src/compositor/wayland_wrapper/qwlsurfacebuffer_p.h b/src/compositor/wayland_wrapper/qwlsurfacebuffer_p.h index 95e7e8158..e0a7d021f 100644 --- a/src/compositor/wayland_wrapper/qwlsurfacebuffer_p.h +++ b/src/compositor/wayland_wrapper/qwlsurfacebuffer_p.h @@ -101,13 +101,15 @@ public: QSize size() const; QWaylandSurface::Origin origin() const; - bool isShm() const { return wl_shm_buffer_get(m_buffer); } + bool isSharedMemory() const { return wl_shm_buffer_get(m_buffer); } QImage image() const; QWaylandBufferRef::BufferFormatEgl bufferFormatEgl() const; +#ifdef QT_WAYLAND_COMPOSITOR_GL void bindToTexture() const; uint textureForPlane(int plane) const; void updateTexture() const; +#endif static bool hasContent(SurfaceBuffer *buffer) { return buffer && buffer->waylandBufferHandle(); } private: |