diff options
94 files changed, 664 insertions, 218 deletions
diff --git a/.qmake.conf b/.qmake.conf index bb8d06457..b3d5a4fed 100644 --- a/.qmake.conf +++ b/.qmake.conf @@ -4,4 +4,4 @@ DEFINES += QT_NO_FOREACH DEFINES += QT_NO_JAVA_STYLE_ITERATORS DEFINES += QT_NO_LINKED_LIST -MODULE_VERSION = 5.15.3 +MODULE_VERSION = 5.15.13 diff --git a/src/client/client.pro b/src/client/client.pro index 793a44183..e7b1dad5c 100644 --- a/src/client/client.pro +++ b/src/client/client.pro @@ -53,7 +53,6 @@ SOURCES += qwaylandintegration.cpp \ qwaylandextendedsurface.cpp \ qwaylandsubsurface.cpp \ qwaylandsurface.cpp \ - qwaylandtabletv2.cpp \ qwaylandtouch.cpp \ qwaylandqtkey.cpp \ ../shared/qwaylandmimehelper.cpp \ @@ -79,7 +78,6 @@ HEADERS += qwaylandintegration_p.h \ qwaylandextendedsurface_p.h \ qwaylandsubsurface_p.h \ qwaylandsurface_p.h \ - qwaylandtabletv2_p.h \ qwaylandtouch_p.h \ qwaylandqtkey_p.h \ qwaylandabstractdecoration_p.h \ @@ -99,6 +97,11 @@ qtConfig(clipboard) { SOURCES += qwaylandclipboard.cpp } +qtConfig(tabletevent) { + HEADERS += qwaylandtabletv2_p.h + SOURCES += qwaylandtabletv2.cpp +} + include(hardwareintegration/hardwareintegration.pri) include(shellintegration/shellintegration.pri) include(inputdeviceintegration/inputdeviceintegration.pri) diff --git a/src/client/global/qwaylandclientextension.cpp b/src/client/global/qwaylandclientextension.cpp index 125b1e19d..966096a88 100644 --- a/src/client/global/qwaylandclientextension.cpp +++ b/src/client/global/qwaylandclientextension.cpp @@ -116,3 +116,5 @@ bool QWaylandClientExtension::isActive() const } QT_END_NAMESPACE + +#include "moc_qwaylandclientextension.cpp" diff --git a/src/client/hardwareintegration/qwaylandclientbufferintegrationplugin.cpp b/src/client/hardwareintegration/qwaylandclientbufferintegrationplugin.cpp index 7aae1d0c4..e9f78ecd4 100644 --- a/src/client/hardwareintegration/qwaylandclientbufferintegrationplugin.cpp +++ b/src/client/hardwareintegration/qwaylandclientbufferintegrationplugin.cpp @@ -55,3 +55,5 @@ QWaylandClientBufferIntegrationPlugin::~QWaylandClientBufferIntegrationPlugin() } QT_END_NAMESPACE + +#include "moc_qwaylandclientbufferintegrationplugin_p.cpp" diff --git a/src/client/hardwareintegration/qwaylandserverbufferintegrationplugin.cpp b/src/client/hardwareintegration/qwaylandserverbufferintegrationplugin.cpp index cff72e7a3..3c802dd01 100644 --- a/src/client/hardwareintegration/qwaylandserverbufferintegrationplugin.cpp +++ b/src/client/hardwareintegration/qwaylandserverbufferintegrationplugin.cpp @@ -54,3 +54,5 @@ QWaylandServerBufferIntegrationPlugin::~QWaylandServerBufferIntegrationPlugin() } QT_END_NAMESPACE + +#include "moc_qwaylandserverbufferintegrationplugin_p.cpp" diff --git a/src/client/inputdeviceintegration/qwaylandinputdeviceintegrationplugin.cpp b/src/client/inputdeviceintegration/qwaylandinputdeviceintegrationplugin.cpp index 579095767..044c28926 100644 --- a/src/client/inputdeviceintegration/qwaylandinputdeviceintegrationplugin.cpp +++ b/src/client/inputdeviceintegration/qwaylandinputdeviceintegrationplugin.cpp @@ -55,3 +55,5 @@ QWaylandInputDeviceIntegrationPlugin::~QWaylandInputDeviceIntegrationPlugin() } QT_END_NAMESPACE + +#include "moc_qwaylandinputdeviceintegrationplugin_p.cpp" diff --git a/src/client/qwaylandabstractdecoration.cpp b/src/client/qwaylandabstractdecoration.cpp index 87dd6cea0..b628930df 100644 --- a/src/client/qwaylandabstractdecoration.cpp +++ b/src/client/qwaylandabstractdecoration.cpp @@ -108,11 +108,11 @@ void QWaylandAbstractDecoration::setWaylandWindow(QWaylandWindow *window) static QRegion marginsRegion(const QSize &size, const QMargins &margins) { QRegion r; - const int widthWithMargins = margins.left() + size.width() + margins.right(); - r += QRect(0, 0, widthWithMargins, margins.top()); // top - r += QRect(0, size.height()+margins.top(), widthWithMargins, margins.bottom()); //bottom + + r += QRect(0, 0, size.width(), margins.top()); // top + r += QRect(0, size.height()-margins.bottom(), size.width(), margins.bottom()); //bottom r += QRect(0, margins.top(), margins.left(), size.height()); //left - r += QRect(size.width()+margins.left(), margins.top(), margins.right(), size.height()); // right + r += QRect(size.width()-margins.left(), margins.top(), margins.right(), size.height()-margins.top()); // right return r; } @@ -216,3 +216,5 @@ QWaylandWindow *QWaylandAbstractDecoration::waylandWindow() const } QT_END_NAMESPACE + +#include "moc_qwaylandabstractdecoration_p.cpp" diff --git a/src/client/qwaylandcursor.cpp b/src/client/qwaylandcursor.cpp index 3263b17f1..e4eca9d4e 100644 --- a/src/client/qwaylandcursor.cpp +++ b/src/client/qwaylandcursor.cpp @@ -120,6 +120,8 @@ wl_cursor *QWaylandCursorTheme::requestCursor(WaylandCursor shape) {SizeAllCursor, "size_all"}, + {BlankCursor, "blank"}, + {SplitVCursor, "split_v"}, {SplitVCursor, "row-resize"}, {SplitVCursor, "sb_v_double_arrow"}, diff --git a/src/client/qwaylanddatadevice.cpp b/src/client/qwaylanddatadevice.cpp index 19944a349..1e2db786a 100644 --- a/src/client/qwaylanddatadevice.cpp +++ b/src/client/qwaylanddatadevice.cpp @@ -168,7 +168,7 @@ void QWaylandDataDevice::data_device_drop() void QWaylandDataDevice::data_device_enter(uint32_t serial, wl_surface *surface, wl_fixed_t x, wl_fixed_t y, wl_data_offer *id) { - auto *dragWaylandWindow = QWaylandWindow::fromWlSurface(surface); + auto *dragWaylandWindow = surface ? QWaylandWindow::fromWlSurface(surface) : nullptr; if (!dragWaylandWindow) return; // Ignore foreign surfaces @@ -302,3 +302,5 @@ QPoint QWaylandDataDevice::calculateDragPosition(int x, int y, QWindow *wnd) con } QT_END_NAMESPACE + +#include "moc_qwaylanddatadevice_p.cpp" diff --git a/src/client/qwaylanddatasource.cpp b/src/client/qwaylanddatasource.cpp index f45122fb9..c2bc9dc45 100644 --- a/src/client/qwaylanddatasource.cpp +++ b/src/client/qwaylanddatasource.cpp @@ -49,6 +49,7 @@ #include <unistd.h> #include <signal.h> +#include <fcntl.h> QT_BEGIN_NAMESPACE @@ -93,7 +94,15 @@ void QWaylandDataSource::data_source_send(const QString &mime_type, int32_t fd) action.sa_flags = 0; sigaction(SIGPIPE, &action, &oldAction); - write(fd, content.constData(), content.size()); + // Some compositors (e.g., mutter) make fd with O_NONBLOCK. + // Since wl_data_source.send describes that fd is closed here, + // it should be done in a loop and don't have any advantage. + // Blocking operation will be used. + // According to fcntl(2), FSETFL ignores O_WRONLY. So this + // call will just remove O_NONBLOCK. + fcntl(fd, F_SETFL, O_WRONLY); + ssize_t unused = write(fd, content.constData(), content.size()); + Q_UNUSED(unused); sigaction(SIGPIPE, &oldAction, nullptr); } close(fd); @@ -107,3 +116,5 @@ void QWaylandDataSource::data_source_target(const QString &mime_type) } QT_END_NAMESPACE + +#include "moc_qwaylanddatasource_p.cpp" diff --git a/src/client/qwaylanddatasource_p.h b/src/client/qwaylanddatasource_p.h index 25afff79c..3003da1ba 100644 --- a/src/client/qwaylanddatasource_p.h +++ b/src/client/qwaylanddatasource_p.h @@ -86,7 +86,6 @@ protected: void data_source_target(const QString &mime_type) override; private: - QWaylandDisplay *m_display = nullptr; QMimeData *m_mime_data = nullptr; }; diff --git a/src/client/qwaylanddecorationplugin.cpp b/src/client/qwaylanddecorationplugin.cpp index 15d907de9..2f8045d60 100644 --- a/src/client/qwaylanddecorationplugin.cpp +++ b/src/client/qwaylanddecorationplugin.cpp @@ -54,3 +54,5 @@ QWaylandDecorationPlugin::~QWaylandDecorationPlugin() } QT_END_NAMESPACE + +#include "moc_qwaylanddecorationplugin_p.cpp" diff --git a/src/client/qwaylanddisplay.cpp b/src/client/qwaylanddisplay.cpp index fe094f6fe..8a6d5db1d 100644 --- a/src/client/qwaylanddisplay.cpp +++ b/src/client/qwaylanddisplay.cpp @@ -69,7 +69,9 @@ #include "qwaylandextendedsurface_p.h" #include "qwaylandsubsurface_p.h" #include "qwaylandtouch_p.h" +#if QT_CONFIG(tabletevent) #include "qwaylandtabletv2_p.h" +#endif #include "qwaylandqtkey_p.h" #include <QtWaylandClient/private/qwayland-text-input-unstable-v2.h> @@ -206,10 +208,11 @@ void QWaylandDisplay::checkError() const int ecode = wl_display_get_error(mDisplay); if ((ecode == EPIPE || ecode == ECONNRESET)) { // special case this to provide a nicer error - qFatal("The Wayland connection broke. Did the Wayland compositor die?"); + qWarning("The Wayland connection broke. Did the Wayland compositor die?"); } else { - qFatal("The Wayland connection experienced a fatal error: %s", strerror(ecode)); + qWarning("The Wayland connection experienced a fatal error: %s", strerror(ecode)); } + _exit(1); } void QWaylandDisplay::flushRequests() @@ -363,8 +366,10 @@ void QWaylandDisplay::registry_global(uint32_t id, const QString &interface, uin mTouchExtension.reset(new QWaylandTouchExtension(this, id)); } else if (interface == QStringLiteral("zqt_key_v1")) { mQtKeyExtension.reset(new QWaylandQtKeyExtension(this, id)); +#if QT_CONFIG(tabletevent) } else if (interface == QStringLiteral("zwp_tablet_manager_v2")) { mTabletManager.reset(new QWaylandTabletManagerV2(this, id, qMin(1, int(version)))); +#endif #if QT_CONFIG(wayland_client_primary_selection) } else if (interface == QStringLiteral("zwp_primary_selection_device_manager_v1")) { mPrimarySelectionManager.reset(new QWaylandPrimarySelectionDeviceManagerV1(this, id, 1)); @@ -652,3 +657,5 @@ QWaylandCursorTheme *QWaylandDisplay::loadCursorTheme(const QString &name, int p } // namespace QtWaylandClient QT_END_NAMESPACE + +#include "moc_qwaylanddisplay_p.cpp" diff --git a/src/client/qwaylanddisplay_p.h b/src/client/qwaylanddisplay_p.h index 188e91318..1bad8b678 100644 --- a/src/client/qwaylanddisplay_p.h +++ b/src/client/qwaylanddisplay_p.h @@ -99,7 +99,9 @@ class QWaylandDataDeviceManager; #if QT_CONFIG(wayland_client_primary_selection) class QWaylandPrimarySelectionDeviceManagerV1; #endif +#if QT_CONFIG(tabletevent) class QWaylandTabletManagerV2; +#endif class QWaylandTouchExtension; class QWaylandQtKeyExtension; class QWaylandWindow; @@ -169,14 +171,14 @@ public: QWaylandPrimarySelectionDeviceManagerV1 *primarySelectionManager() const { return mPrimarySelectionManager.data(); } #endif QtWayland::qt_surface_extension *windowExtension() const { return mWindowExtension.data(); } +#if QT_CONFIG(tabletevent) QWaylandTabletManagerV2 *tabletManager() const { return mTabletManager.data(); } +#endif QWaylandTouchExtension *touchExtension() const { return mTouchExtension.data(); } QtWayland::zwp_text_input_manager_v2 *textInputManager() const { return mTextInputManager.data(); } QWaylandHardwareIntegration *hardwareIntegration() const { return mHardwareIntegration.data(); } QWaylandXdgOutputManagerV1 *xdgOutputManager() const { return mXdgOutputManager.data(); } - bool usingInputContextFromCompositor() const { return mUsingInputContextFromCompositor; } - struct RegistryGlobal { uint32_t id; QString interface; @@ -259,7 +261,9 @@ private: QScopedPointer<QWaylandTouchExtension> mTouchExtension; QScopedPointer<QWaylandQtKeyExtension> mQtKeyExtension; QScopedPointer<QWaylandWindowManagerIntegration> mWindowManagerIntegration; +#if QT_CONFIG(tabletevent) QScopedPointer<QWaylandTabletManagerV2> mTabletManager; +#endif #if QT_CONFIG(wayland_client_primary_selection) QScopedPointer<QWaylandPrimarySelectionDeviceManagerV1> mPrimarySelectionManager; #endif @@ -282,7 +286,6 @@ private: QReadWriteLock m_frameQueueLock; bool mClientSideInputContextRequested = !QPlatformInputContextFactory::requested().isNull(); - bool mUsingInputContextFromCompositor = false; void registry_global(uint32_t id, const QString &interface, uint32_t version) override; void registry_global_remove(uint32_t id) override; diff --git a/src/client/qwaylandinputcontext.cpp b/src/client/qwaylandinputcontext.cpp index e9afe05ed..fdf49f5c2 100644 --- a/src/client/qwaylandinputcontext.cpp +++ b/src/client/qwaylandinputcontext.cpp @@ -51,6 +51,10 @@ #include "qwaylandinputmethodeventbuilder_p.h" #include "qwaylandwindow_p.h" +#if QT_CONFIG(xkbcommon) +#include <locale.h> +#endif + QT_BEGIN_NAMESPACE Q_LOGGING_CATEGORY(qLcQpaInputMethods, "qt.qpa.input.methods") @@ -89,9 +93,12 @@ void QWaylandTextInput::reset() void QWaylandTextInput::commit() { if (QObject *o = QGuiApplication::focusObject()) { - QInputMethodEvent event; - event.setCommitString(m_preeditCommit); - QCoreApplication::sendEvent(o, &event); + if (!m_preeditCommit.isEmpty()) { + QInputMethodEvent event; + event.setCommitString(m_preeditCommit); + m_preeditCommit = QString(); + QCoreApplication::sendEvent(o, &event); + } } reset(); @@ -383,8 +390,10 @@ void QWaylandTextInput::zwp_text_input_v2_input_method_changed(uint32_t serial, Qt::KeyboardModifiers QWaylandTextInput::modifiersToQtModifiers(uint32_t modifiers) { Qt::KeyboardModifiers ret = Qt::NoModifier; - for (int i = 0; modifiers >>= 1; ++i) { - ret |= m_modifiersMap[i]; + for (int i = 0; i < m_modifiersMap.size(); ++i) { + if (modifiers & (1 << i)) { + ret |= m_modifiersMap[i]; + } } return ret; } @@ -406,6 +415,10 @@ bool QWaylandInputContext::isValid() const void QWaylandInputContext::reset() { qCDebug(qLcQpaInputMethods) << Q_FUNC_INFO; +#if QT_CONFIG(xkbcommon) + if (m_composeState) + xkb_compose_state_reset(m_composeState); +#endif QPlatformInputContext::reset(); @@ -526,9 +539,14 @@ Qt::LayoutDirection QWaylandInputContext::inputDirection() const return textInput()->inputDirection(); } -void QWaylandInputContext::setFocusObject(QObject *) +void QWaylandInputContext::setFocusObject(QObject *object) { qCDebug(qLcQpaInputMethods) << Q_FUNC_INFO; +#if QT_CONFIG(xkbcommon) + m_focusObject = object; +#else + Q_UNUSED(object); +#endif if (!textInput()) return; @@ -561,6 +579,94 @@ QWaylandTextInput *QWaylandInputContext::textInput() const return mDisplay->defaultInputDevice()->textInput(); } +#if QT_CONFIG(xkbcommon) + +void QWaylandInputContext::ensureInitialized() +{ + if (m_initialized) + return; + + if (!m_XkbContext) { + qCWarning(qLcQpaInputMethods) << "error: xkb context has not been set on" << metaObject()->className(); + return; + } + + m_initialized = true; + const char *locale = setlocale(LC_CTYPE, ""); + if (!locale) + locale = setlocale(LC_CTYPE, nullptr); + qCDebug(qLcQpaInputMethods) << "detected locale (LC_CTYPE):" << locale; + + m_composeTable = xkb_compose_table_new_from_locale(m_XkbContext, locale, XKB_COMPOSE_COMPILE_NO_FLAGS); + if (m_composeTable) + m_composeState = xkb_compose_state_new(m_composeTable, XKB_COMPOSE_STATE_NO_FLAGS); + + if (!m_composeTable) { + qCWarning(qLcQpaInputMethods, "failed to create compose table"); + return; + } + if (!m_composeState) { + qCWarning(qLcQpaInputMethods, "failed to create compose state"); + return; + } +} + +bool QWaylandInputContext::filterEvent(const QEvent *event) +{ + auto keyEvent = static_cast<const QKeyEvent *>(event); + if (keyEvent->type() != QEvent::KeyPress) + return false; + + if (!inputMethodAccepted()) + return false; + + // lazy initialization - we don't want to do this on an app startup + ensureInitialized(); + + if (!m_composeTable || !m_composeState) + return false; + + xkb_compose_state_feed(m_composeState, keyEvent->nativeVirtualKey()); + + switch (xkb_compose_state_get_status(m_composeState)) { + case XKB_COMPOSE_COMPOSING: + return true; + case XKB_COMPOSE_CANCELLED: + reset(); + return false; + case XKB_COMPOSE_COMPOSED: + { + const int size = xkb_compose_state_get_utf8(m_composeState, nullptr, 0); + QVarLengthArray<char, 32> buffer(size + 1); + xkb_compose_state_get_utf8(m_composeState, buffer.data(), buffer.size()); + QString composedText = QString::fromUtf8(buffer.constData()); + + QInputMethodEvent event; + event.setCommitString(composedText); + + if (!m_focusObject && qApp) + m_focusObject = qApp->focusObject(); + + if (m_focusObject) + QCoreApplication::sendEvent(m_focusObject, &event); + else + qCWarning(qLcQpaInputMethods, "no focus object"); + + reset(); + return true; + } + case XKB_COMPOSE_NOTHING: + return false; + default: + Q_UNREACHABLE(); + return false; + } +} + +#endif + } QT_END_NAMESPACE + +#include "moc_qwaylandinputcontext_p.cpp" diff --git a/src/client/qwaylandinputcontext_p.h b/src/client/qwaylandinputcontext_p.h index 10132dfe1..50db63447 100644 --- a/src/client/qwaylandinputcontext_p.h +++ b/src/client/qwaylandinputcontext_p.h @@ -61,6 +61,10 @@ #include <QtWaylandClient/private/qwayland-text-input-unstable-v2.h> #include <qwaylandinputmethodeventbuilder_p.h> +#include <qtwaylandclientglobal_p.h> +#if QT_CONFIG(xkbcommon) +#include <xkbcommon/xkbcommon-compose.h> +#endif struct wl_callback; struct wl_callback_listener; @@ -155,11 +159,28 @@ public: void setFocusObject(QObject *object) override; +#if QT_CONFIG(xkbcommon) + bool filterEvent(const QEvent *event) override; + + // This invokable is called from QXkbCommon::setXkbContext(). + Q_INVOKABLE void setXkbContext(struct xkb_context *context) { m_XkbContext = context; } +#endif + private: QWaylandTextInput *textInput() const; QWaylandDisplay *mDisplay = nullptr; QPointer<QWindow> mCurrentWindow; + +#if QT_CONFIG(xkbcommon) + void ensureInitialized(); + + bool m_initialized = false; + QObject *m_focusObject = nullptr; + xkb_compose_table *m_composeTable = nullptr; + xkb_compose_state *m_composeState = nullptr; + struct xkb_context *m_XkbContext = nullptr; +#endif }; } diff --git a/src/client/qwaylandinputdevice.cpp b/src/client/qwaylandinputdevice.cpp index ed4a0eb45..b0e9692bd 100644 --- a/src/client/qwaylandinputdevice.cpp +++ b/src/client/qwaylandinputdevice.cpp @@ -50,7 +50,9 @@ #if QT_CONFIG(wayland_client_primary_selection) #include "qwaylandprimaryselectionv1_p.h" #endif +#if QT_CONFIG(tabletevent) #include "qwaylandtabletv2_p.h" +#endif #include "qwaylandtouch_p.h" #include "qwaylandscreen_p.h" #include "qwaylandcursor_p.h" @@ -261,7 +263,7 @@ QString QWaylandInputDevice::Pointer::cursorThemeName() const int QWaylandInputDevice::Pointer::cursorSize() const { - constexpr int defaultCursorSize = 32; + constexpr int defaultCursorSize = 24; static const int xCursorSize = qEnvironmentVariableIntValue("XCURSOR_SIZE"); return xCursorSize > 0 ? xCursorSize : defaultCursorSize; } @@ -419,8 +421,10 @@ QWaylandInputDevice::QWaylandInputDevice(QWaylandDisplay *display, int version, if (mQDisplay->textInputManager()) mTextInput.reset(new QWaylandTextInput(mQDisplay, mQDisplay->textInputManager()->get_text_input(wl_seat()))); +#if QT_CONFIG(tabletevent) if (auto *tm = mQDisplay->tabletManager()) mTabletSeat.reset(new QWaylandTabletSeatV2(tm, this)); +#endif } QWaylandInputDevice::~QWaylandInputDevice() @@ -685,6 +689,11 @@ public: void QWaylandInputDevice::Pointer::pointer_leave(uint32_t time, struct wl_surface *surface) { + invalidateFocus(); + mButtons = Qt::NoButton; + + mParent->mTime = time; + // The event may arrive after destroying the window, indicated by // a null surface. if (!surface) @@ -696,11 +705,6 @@ void QWaylandInputDevice::Pointer::pointer_leave(uint32_t time, struct wl_surfac if (!QWaylandWindow::mouseGrab()) setFrameEvent(new LeaveEvent(window, mSurfacePos, mGlobalPos)); - - invalidateFocus(); - mButtons = Qt::NoButton; - - mParent->mTime = time; } class MotionEvent : public QWaylandPointerEvent @@ -1201,7 +1205,7 @@ void QWaylandInputDevice::Keyboard::handleKey(ulong timestamp, QEvent::Type type QPlatformInputContext *inputContext = QGuiApplicationPrivate::platformIntegration()->inputContext(); bool filtered = false; - if (inputContext && !mParent->mQDisplay->usingInputContextFromCompositor()) { + if (inputContext) { QKeyEvent event(type, key, modifiers, nativeScanCode, nativeVirtualKey, nativeModifiers, text, autorepeat, count); event.setTimestamp(timestamp); @@ -1364,7 +1368,7 @@ void QWaylandInputDevice::Touch::touch_down(uint32_t serial, void QWaylandInputDevice::Touch::touch_up(uint32_t serial, uint32_t time, int32_t id) { Q_UNUSED(serial); - Q_UNUSED(time); + mParent->mTime = time; mParent->handleTouchPoint(id, Qt::TouchPointReleased); if (allTouchPointsReleased()) { @@ -1383,8 +1387,8 @@ void QWaylandInputDevice::Touch::touch_up(uint32_t serial, uint32_t time, int32_ void QWaylandInputDevice::Touch::touch_motion(uint32_t time, int32_t id, wl_fixed_t x, wl_fixed_t y) { - Q_UNUSED(time); QPointF position(wl_fixed_to_double(x), wl_fixed_to_double(y)); + mParent->mTime = time; mParent->handleTouchPoint(id, Qt::TouchPointMoved, position); } @@ -1407,6 +1411,14 @@ void QWaylandInputDevice::handleTouchPoint(int id, Qt::TouchPointState state, co it = mTouch->mPendingTouchPoints.insert(end, QWindowSystemInterface::TouchPoint()); it->id = id; } + // If the touch points were up and down in same frame, send out frame right away + else if ((it->state == Qt::TouchPointPressed && state == Qt::TouchPointReleased) + || (it->state == Qt::TouchPointReleased && state == Qt::TouchPointPressed)) { + mTouch->touch_frame(); + it = mTouch->mPendingTouchPoints.insert(mTouch->mPendingTouchPoints.end(), QWindowSystemInterface::TouchPoint()); + it->id = id; + } + QWindowSystemInterface::TouchPoint &tp = *it; // Only moved and pressed needs to update/set position @@ -1475,7 +1487,7 @@ void QWaylandInputDevice::Touch::touch_frame() return; } - QWindowSystemInterface::handleTouchEvent(window, mParent->mTouchDevice, mPendingTouchPoints); + QWindowSystemInterface::handleTouchEvent(window, mParent->mTime, mParent->mTouchDevice, mPendingTouchPoints, mParent->modifiers()); // Prepare state for next frame const auto prevTouchPoints = mPendingTouchPoints; @@ -1494,3 +1506,5 @@ void QWaylandInputDevice::Touch::touch_frame() } QT_END_NAMESPACE + +#include "moc_qwaylandinputdevice_p.cpp" diff --git a/src/client/qwaylandinputdevice_p.h b/src/client/qwaylandinputdevice_p.h index 448d0fce5..5795f138a 100644 --- a/src/client/qwaylandinputdevice_p.h +++ b/src/client/qwaylandinputdevice_p.h @@ -89,7 +89,9 @@ class QWaylandDisplay; #if QT_CONFIG(wayland_client_primary_selection) class QWaylandPrimarySelectionDeviceV1; #endif +#if QT_CONFIG(tabletevent) class QWaylandTabletSeatV2; +#endif class QWaylandTextInput; #if QT_CONFIG(cursor) class QWaylandCursorTheme; @@ -128,8 +130,10 @@ public: QWaylandPrimarySelectionDeviceV1 *primarySelectionDevice() const; #endif +#if QT_CONFIG(tabletevent) void setTabletSeat(QWaylandTabletSeatV2 *tabletSeat); QWaylandTabletSeatV2* tabletSeat() const; +#endif void setTextInput(QWaylandTextInput *textInput); QWaylandTextInput *textInput() const; @@ -187,7 +191,9 @@ private: Touch *mTouch = nullptr; QScopedPointer<QWaylandTextInput> mTextInput; +#if QT_CONFIG(tabletevent) QScopedPointer<QWaylandTabletSeatV2> mTabletSeat; +#endif uint32_t mTime = 0; uint32_t mSerial = 0; diff --git a/src/client/qwaylandintegration.cpp b/src/client/qwaylandintegration.cpp index 7ad8e05e0..d257e2e33 100644 --- a/src/client/qwaylandintegration.cpp +++ b/src/client/qwaylandintegration.cpp @@ -474,14 +474,12 @@ void QWaylandIntegration::reconfigureInputContext() #if QT_CONFIG(xkbcommon) QXkbCommon::setXkbContext(mInputContext.data(), mDisplay->xkbContext()); + if (QWaylandInputContext* waylandInput = qobject_cast<QWaylandInputContext*>(mInputContext.get())) { + waylandInput->setXkbContext(mDisplay->xkbContext()); + } #endif - // Even if compositor-side input context handling has been requested, we fallback to - // client-side handling if compositor does not provide the text-input extension. This - // is why we need to check here which input context actually is being used. - mDisplay->mUsingInputContextFromCompositor = qobject_cast<QWaylandInputContext *>(mInputContext.data()); - - qCDebug(lcQpaWayland) << "using input method:" << inputContext()->metaObject()->className(); + qCDebug(lcQpaWayland) << "using input method:" << (inputContext() ? inputContext()->metaObject()->className() : "<none>"); } QWaylandShellIntegration *QWaylandIntegration::createShellIntegration(const QString &integrationName) diff --git a/src/client/qwaylandprimaryselectionv1.cpp b/src/client/qwaylandprimaryselectionv1.cpp index 832f96780..7805dd734 100644 --- a/src/client/qwaylandprimaryselectionv1.cpp +++ b/src/client/qwaylandprimaryselectionv1.cpp @@ -160,7 +160,8 @@ void QWaylandPrimarySelectionSourceV1::zwp_primary_selection_source_v1_send(cons action.sa_flags = 0; sigaction(SIGPIPE, &action, &oldAction); - write(fd, content.constData(), size_t(content.size())); + ssize_t unused = write(fd, content.constData(), size_t(content.size())); + Q_UNUSED(unused); sigaction(SIGPIPE, &oldAction, nullptr); } close(fd); @@ -169,3 +170,5 @@ void QWaylandPrimarySelectionSourceV1::zwp_primary_selection_source_v1_send(cons } // namespace QtWaylandClient QT_END_NAMESPACE + +#include "moc_qwaylandprimaryselectionv1_p.cpp" diff --git a/src/client/qwaylandprimaryselectionv1_p.h b/src/client/qwaylandprimaryselectionv1_p.h index 3f0a42a67..3ef58748c 100644 --- a/src/client/qwaylandprimaryselectionv1_p.h +++ b/src/client/qwaylandprimaryselectionv1_p.h @@ -113,7 +113,6 @@ protected: void zwp_primary_selection_source_v1_cancelled() override { emit cancelled(); } private: - QWaylandDisplay *m_display = nullptr; QMimeData *m_mimeData = nullptr; }; diff --git a/src/client/qwaylandshellsurface.cpp b/src/client/qwaylandshellsurface.cpp index 91cc2c2c0..6c0c95b26 100644 --- a/src/client/qwaylandshellsurface.cpp +++ b/src/client/qwaylandshellsurface.cpp @@ -64,3 +64,5 @@ void QWaylandShellSurface::sendProperty(const QString &name, const QVariant &val } QT_END_NAMESPACE + +#include "moc_qwaylandshellsurface_p.cpp" diff --git a/src/client/qwaylandsurface.cpp b/src/client/qwaylandsurface.cpp index 21e70ce4f..983cef719 100644 --- a/src/client/qwaylandsurface.cpp +++ b/src/client/qwaylandsurface.cpp @@ -124,3 +124,5 @@ void QWaylandSurface::surface_leave(wl_output *output) } // namespace QtWaylandClient QT_END_NAMESPACE + +#include "moc_qwaylandsurface_p.cpp" diff --git a/src/client/qwaylandtabletv2.cpp b/src/client/qwaylandtabletv2.cpp index eb2e865f6..58e4cd4a3 100644 --- a/src/client/qwaylandtabletv2.cpp +++ b/src/client/qwaylandtabletv2.cpp @@ -330,3 +330,5 @@ void QWaylandTabletPadV2::zwp_tablet_pad_v2_removed() } // namespace QtWaylandClient QT_END_NAMESPACE + +#include "moc_qwaylandtabletv2_p.cpp" diff --git a/src/client/qwaylandwindow.cpp b/src/client/qwaylandwindow.cpp index 9b3437023..d57094a71 100644 --- a/src/client/qwaylandwindow.cpp +++ b/src/client/qwaylandwindow.cpp @@ -342,7 +342,12 @@ void QWaylandWindow::setGeometry_helper(const QRect &rect) if (mSubSurfaceWindow) { QMargins m = QPlatformWindow::parent()->frameMargins(); mSubSurfaceWindow->set_position(rect.x() + m.left(), rect.y() + m.top()); - mSubSurfaceWindow->parent()->window()->requestUpdate(); + + QWaylandWindow *parentWindow = mSubSurfaceWindow->parent(); + if (parentWindow && parentWindow->isExposed()) { + QRect parentExposeGeometry(QPoint(), parentWindow->geometry().size()); + parentWindow->sendExposeEvent(parentExposeGeometry); + } } } @@ -365,7 +370,7 @@ void QWaylandWindow::setGeometry(const QRect &rect) if (isExposed() && !mInResizeFromApplyConfigure && exposeGeometry != mLastExposeGeometry) sendExposeEvent(exposeGeometry); - if (mShellSurface) + if (mShellSurface && isExposed()) mShellSurface->setWindowGeometry(windowContentGeometry()); if (isOpaque() && mMask.isEmpty()) @@ -411,6 +416,7 @@ void QWaylandWindow::closePopups(QWaylandWindow *parent) QPlatformScreen *QWaylandWindow::calculateScreenFromSurfaceEvents() const { + QReadLocker lock(&mSurfaceLock); if (mSurface) { if (auto *screen = mSurface->oldestEnteredScreen()) return screen; @@ -459,14 +465,15 @@ void QWaylandWindow::lower() void QWaylandWindow::setMask(const QRegion &mask) { + QReadLocker locker(&mSurfaceLock); + if (!mSurface) + return; + if (mMask == mask) return; mMask = mask; - if (!mSurface) - return; - if (mMask.isEmpty()) { mSurface->set_input_region(nullptr); @@ -550,6 +557,10 @@ void QWaylandWindow::sendRecursiveExposeEvent() void QWaylandWindow::attach(QWaylandBuffer *buffer, int x, int y) { Q_ASSERT(!buffer->committed()); + QReadLocker locker(&mSurfaceLock); + if (mSurface == nullptr) + return; + if (buffer) { handleUpdate(); buffer->setBusy(); @@ -568,6 +579,10 @@ void QWaylandWindow::attachOffset(QWaylandBuffer *buffer) void QWaylandWindow::damage(const QRect &rect) { + QReadLocker locker(&mSurfaceLock); + if (mSurface == nullptr) + return; + mSurface->damage(rect.x(), rect.y(), rect.width(), rect.height()); } @@ -598,6 +613,8 @@ void QWaylandWindow::commit(QWaylandBuffer *buffer, const QRegion &damage) qCDebug(lcWaylandBackingstore) << "Buffer already committed, ignoring."; return; } + + QReadLocker locker(&mSurfaceLock); if (!mSurface) return; @@ -611,7 +628,9 @@ void QWaylandWindow::commit(QWaylandBuffer *buffer, const QRegion &damage) void QWaylandWindow::commit() { - mSurface->commit(); + QReadLocker locker(&mSurfaceLock); + if (mSurface != nullptr) + mSurface->commit(); } const wl_callback_listener QWaylandWindow::callbackListener = { @@ -702,6 +721,7 @@ QPointF QWaylandWindow::mapFromWlSurface(const QPointF &surfacePosition) const wl_surface *QWaylandWindow::wlSurface() { + QReadLocker locker(&mSurfaceLock); return mSurface ? mSurface->object() : nullptr; } @@ -726,7 +746,8 @@ QWaylandScreen *QWaylandWindow::waylandScreen() const void QWaylandWindow::handleContentOrientationChange(Qt::ScreenOrientation orientation) { - if (mDisplay->compositorVersion() < 2) + QReadLocker locker(&mSurfaceLock); + if (mDisplay->compositorVersion() < 2 || mSurface == nullptr) return; wl_output_transform transform; @@ -800,7 +821,7 @@ bool QWaylandWindow::createDecoration() decoration = false; if (mSubSurfaceWindow) decoration = false; - if (mShellSurface && !mShellSurface->wantsDecorations()) + if (!mShellSurface || !mShellSurface->wantsDecorations()) decoration = false; bool hadDecoration = mWindowDecoration; @@ -846,7 +867,18 @@ bool QWaylandWindow::createDecoration() QMargins m = frameMargins(); subsurf->set_position(pos.x() + m.left(), pos.y() + m.top()); } - sendExposeEvent(QRect(QPoint(), geometry().size())); + setGeometry(geometry()); + + // This is a special case where the buffer is recreated, but since + // the content rect remains the same, the widgets remain the same + // size and are not redrawn, leaving the new buffer empty. As a simple + // work-around, we trigger a full extra update whenever the client-side + // window decorations are toggled while the window is showing. + // Note: createDecoration() is sometimes called from the render thread + // of Qt Quick. This is essentially wrong and could potentially cause problems, + // but until the underlying issue has been fixed, we have to use invokeMethod() + // here to avoid asserts. + QMetaObject::invokeMethod(window(), &QWindow::requestUpdate); } return mWindowDecoration; @@ -1021,7 +1053,10 @@ void QWaylandWindow::setMouseCursor(QWaylandInputDevice *device, const QCursor & void QWaylandWindow::restoreMouseCursor(QWaylandInputDevice *device) { - setMouseCursor(device, window()->cursor()); + if (const QCursor *overrideCursor = QGuiApplication::overrideCursor()) + setMouseCursor(device, *overrideCursor); + else + setMouseCursor(device, window()->cursor()); } #endif @@ -1234,12 +1269,14 @@ bool QWaylandWindow::isOpaque() const void QWaylandWindow::setOpaqueArea(const QRegion &opaqueArea) { - if (opaqueArea == mOpaqueArea || !mSurface) + const QRegion translatedOpaqueArea = opaqueArea.translated(frameMargins().left(), frameMargins().top()); + + if (translatedOpaqueArea == mOpaqueArea || !mSurface) return; - mOpaqueArea = opaqueArea; + mOpaqueArea = translatedOpaqueArea; - struct ::wl_region *region = mDisplay->createRegion(opaqueArea); + struct ::wl_region *region = mDisplay->createRegion(translatedOpaqueArea); mSurface->set_opaque_region(region); wl_region_destroy(region); } @@ -1247,3 +1284,5 @@ void QWaylandWindow::setOpaqueArea(const QRegion &opaqueArea) } QT_END_NAMESPACE + +#include "moc_qwaylandwindow_p.cpp" diff --git a/src/client/qwaylandwindow_p.h b/src/client/qwaylandwindow_p.h index 6cc1664b7..01337cff1 100644 --- a/src/client/qwaylandwindow_p.h +++ b/src/client/qwaylandwindow_p.h @@ -287,7 +287,7 @@ private: static QWaylandWindow *mMouseGrab; - QReadWriteLock mSurfaceLock; + mutable QReadWriteLock mSurfaceLock; friend class QWaylandSubSurface; }; diff --git a/src/client/qwaylandwindowmanagerintegration.cpp b/src/client/qwaylandwindowmanagerintegration.cpp index dd1acaf72..5d60624a6 100644 --- a/src/client/qwaylandwindowmanagerintegration.cpp +++ b/src/client/qwaylandwindowmanagerintegration.cpp @@ -145,3 +145,5 @@ bool QWaylandWindowManagerIntegration::openDocument(const QUrl &url) } QT_END_NAMESPACE + +#include "moc_qwaylandwindowmanagerintegration_p.cpp" diff --git a/src/client/shellintegration/qwaylandshellintegrationplugin.cpp b/src/client/shellintegration/qwaylandshellintegrationplugin.cpp index d89e61fb1..f0833251e 100644 --- a/src/client/shellintegration/qwaylandshellintegrationplugin.cpp +++ b/src/client/shellintegration/qwaylandshellintegrationplugin.cpp @@ -55,3 +55,5 @@ QWaylandShellIntegrationPlugin::~QWaylandShellIntegrationPlugin() } QT_END_NAMESPACE + +#include "moc_qwaylandshellintegrationplugin_p.cpp" diff --git a/src/compositor/compositor_api/qwaylandclient.cpp b/src/compositor/compositor_api/qwaylandclient.cpp index 2dba85faf..c89285dc0 100644 --- a/src/compositor/compositor_api/qwaylandclient.cpp +++ b/src/compositor/compositor_api/qwaylandclient.cpp @@ -79,6 +79,7 @@ public: /*! * \qmltype WaylandClient + * \instantiates QWaylandClient * \inqmlmodule QtWayland.Compositor * \since 5.8 * \brief Represents a client connecting to the WaylandCompositor. diff --git a/src/compositor/compositor_api/qwaylandcompositor.cpp b/src/compositor/compositor_api/qwaylandcompositor.cpp index 18d8da4fb..116336100 100644 --- a/src/compositor/compositor_api/qwaylandcompositor.cpp +++ b/src/compositor/compositor_api/qwaylandcompositor.cpp @@ -451,6 +451,7 @@ void QWaylandCompositorPrivate::loadServerBufferIntegration() /*! \qmltype WaylandCompositor + \instantiates QWaylandCompositor \inqmlmodule QtWayland.Compositor \since 5.8 \brief Manages the Wayland display server. diff --git a/src/compositor/compositor_api/qwaylandoutput.cpp b/src/compositor/compositor_api/qwaylandoutput.cpp index 0f5e79d83..f061afa39 100644 --- a/src/compositor/compositor_api/qwaylandoutput.cpp +++ b/src/compositor/compositor_api/qwaylandoutput.cpp @@ -249,6 +249,7 @@ QWaylandOutput::QWaylandOutput() /*! \qmltype WaylandOutput + \instantiates QWaylandOutput \inqmlmodule QtWayland.Compositor \since 5.8 \brief Provides access to a displayable area managed by the compositor. diff --git a/src/compositor/compositor_api/qwaylandpointer.cpp b/src/compositor/compositor_api/qwaylandpointer.cpp index 9e8bfff15..fa00bbf4a 100644 --- a/src/compositor/compositor_api/qwaylandpointer.cpp +++ b/src/compositor/compositor_api/qwaylandpointer.cpp @@ -418,3 +418,5 @@ void QWaylandPointer::pointerFocusChanged(QWaylandView *newFocus, QWaylandView * } QT_END_NAMESPACE + +#include "moc_qwaylandpointer.cpp" diff --git a/src/compositor/compositor_api/qwaylandquickcompositor.cpp b/src/compositor/compositor_api/qwaylandquickcompositor.cpp index db1cf00f2..30d2b5772 100644 --- a/src/compositor/compositor_api/qwaylandquickcompositor.cpp +++ b/src/compositor/compositor_api/qwaylandquickcompositor.cpp @@ -168,3 +168,5 @@ void QWaylandQuickCompositor::grabSurface(QWaylandSurfaceGrabber *grabber, const } QT_END_NAMESPACE + +#include "moc_qwaylandquickcompositor.cpp" diff --git a/src/compositor/compositor_api/qwaylandquickhardwarelayer.cpp b/src/compositor/compositor_api/qwaylandquickhardwarelayer.cpp index 55ac61cfa..ea6efb128 100644 --- a/src/compositor/compositor_api/qwaylandquickhardwarelayer.cpp +++ b/src/compositor/compositor_api/qwaylandquickhardwarelayer.cpp @@ -166,3 +166,5 @@ void QWaylandQuickHardwareLayer::disableSceneGraphPainting() } QT_END_NAMESPACE + +#include "moc_qwaylandquickhardwarelayer_p.cpp" diff --git a/src/compositor/compositor_api/qwaylandquickitem.cpp b/src/compositor/compositor_api/qwaylandquickitem.cpp index 15f0195c0..0fb7e3269 100644 --- a/src/compositor/compositor_api/qwaylandquickitem.cpp +++ b/src/compositor/compositor_api/qwaylandquickitem.cpp @@ -253,6 +253,16 @@ void QWaylandBufferMaterial::ensureTextures(int count) m_textures << nullptr; } } + +void QWaylandBufferMaterial::setBufferRef(QWaylandQuickItem *surfaceItem, const QWaylandBufferRef &ref) +{ + Q_UNUSED(surfaceItem); + m_bufferRef = ref; + for (int plane = 0; plane < bufferTypes[ref.bufferFormatEgl()].planeCount; plane++) + if (auto texture = ref.toOpenGLTexture(plane)) + setTextureForPlane(plane, texture); + bind(); +} #endif // QT_CONFIG(opengl) QMutex *QWaylandQuickItemPrivate::mutex = nullptr; @@ -319,6 +329,7 @@ private: /*! * \qmltype WaylandQuickItem + * \instantiates QWaylandQuickItem * \inqmlmodule QtWayland.Compositor * \since 5.8 * \brief Provides a Qt Quick item that represents a WaylandView. @@ -736,7 +747,9 @@ void QWaylandQuickItem::handleSubsurfaceAdded(QWaylandSurface *childSurface) childItem->setSurface(childSurface); childItem->setVisible(true); childItem->setParentItem(this); + childItem->setParent(this); connect(childSurface, &QWaylandSurface::subsurfacePositionChanged, childItem, &QWaylandQuickItem::handleSubsurfacePosition); + connect(childSurface, &QWaylandSurface::destroyed, childItem, &QObject::deleteLater); } else { bool success = QMetaObject::invokeMethod(d->subsurfaceHandler, "handleSubsurfaceAdded", Q_ARG(QWaylandSurface *, childSurface)); if (!success) @@ -1408,13 +1421,20 @@ QSGNode *QWaylandQuickItem::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeDat if (d->newTexture) { d->newTexture = false; - for (int plane = 0; plane < bufferTypes[ref.bufferFormatEgl()].planeCount; plane++) - if (auto texture = ref.toOpenGLTexture(plane)) - material->setTextureForPlane(plane, texture); - material->bind(); + material->setBufferRef(this, ref); } - QSGGeometry::updateTexturedRectGeometry(geometry, rect, QRectF(0, 0, 1, 1)); + const QSize surfaceSize = ref.size() / surface()->bufferScale(); + const QRectF sourceGeometry = surface()->sourceGeometry(); + const QRectF normalizedCoordinates = + sourceGeometry.isValid() + ? QRectF(sourceGeometry.x() / surfaceSize.width(), + sourceGeometry.y() / surfaceSize.height(), + sourceGeometry.width() / surfaceSize.width(), + sourceGeometry.height() / surfaceSize.height()) + : QRectF(0, 0, 1, 1); + + QSGGeometry::updateTexturedRectGeometry(geometry, rect, normalizedCoordinates); node->setGeometry(geometry); node->setFlag(QSGNode::OwnsGeometry, true); @@ -1600,3 +1620,5 @@ void QWaylandQuickItemPrivate::placeBelowParent() } QT_END_NAMESPACE + +#include "moc_qwaylandquickitem.cpp" diff --git a/src/compositor/compositor_api/qwaylandquickitem_p.h b/src/compositor/compositor_api/qwaylandquickitem_p.h index a75cdb2ba..a507cec0a 100644 --- a/src/compositor/compositor_api/qwaylandquickitem_p.h +++ b/src/compositor/compositor_api/qwaylandquickitem_p.h @@ -80,6 +80,7 @@ public: ~QWaylandBufferMaterial() override; void setTextureForPlane(int plane, QOpenGLTexture *texture); + void setBufferRef(QWaylandQuickItem *surfaceItem, const QWaylandBufferRef &ref); void bind(); @@ -92,6 +93,7 @@ private: const QWaylandBufferRef::BufferFormatEgl m_format; QVarLengthArray<QOpenGLTexture*, 3> m_textures; + QWaylandBufferRef m_bufferRef; }; #endif // QT_CONFIG(opengl) diff --git a/src/compositor/compositor_api/qwaylandquickoutput.cpp b/src/compositor/compositor_api/qwaylandquickoutput.cpp index acb907960..c3909acc6 100644 --- a/src/compositor/compositor_api/qwaylandquickoutput.cpp +++ b/src/compositor/compositor_api/qwaylandquickoutput.cpp @@ -164,3 +164,5 @@ void QWaylandQuickOutput::doFrameCallbacks() sendFrameCallbacks(); } QT_END_NAMESPACE + +#include "moc_qwaylandquickoutput.cpp" diff --git a/src/compositor/compositor_api/qwaylandquicksurface.cpp b/src/compositor/compositor_api/qwaylandquicksurface.cpp index 8808b6a42..67f92f547 100644 --- a/src/compositor/compositor_api/qwaylandquicksurface.cpp +++ b/src/compositor/compositor_api/qwaylandquicksurface.cpp @@ -118,3 +118,5 @@ void QWaylandQuickSurface::setClientRenderingEnabled(bool enabled) } QT_END_NAMESPACE + +#include "moc_qwaylandquicksurface.cpp" diff --git a/src/compositor/compositor_api/qwaylandresource.cpp b/src/compositor/compositor_api/qwaylandresource.cpp index 585b238cd..b8a47d64b 100644 --- a/src/compositor/compositor_api/qwaylandresource.cpp +++ b/src/compositor/compositor_api/qwaylandresource.cpp @@ -41,3 +41,5 @@ QWaylandResource::QWaylandResource(wl_resource *resource) } QT_END_NAMESPACE + +#include "moc_qwaylandresource.cpp" diff --git a/src/compositor/compositor_api/qwaylandseat.cpp b/src/compositor/compositor_api/qwaylandseat.cpp index 83d0335c4..1e50a1be5 100644 --- a/src/compositor/compositor_api/qwaylandseat.cpp +++ b/src/compositor/compositor_api/qwaylandseat.cpp @@ -136,6 +136,7 @@ void QWaylandSeatPrivate::seat_get_touch(wl_seat::Resource *resource, uint32_t i /*! * \qmltype WaylandSeat + * \instantiates QWaylandSeat * \inqmlmodule QtWayland.Compositor * \since 5.8 * \brief Provides access to keyboard, mouse, and touch input. @@ -763,3 +764,5 @@ void QWaylandSeat::handleMouseFocusDestroyed() */ QT_END_NAMESPACE + +#include "moc_qwaylandseat.cpp" diff --git a/src/compositor/compositor_api/qwaylandsurface.cpp b/src/compositor/compositor_api/qwaylandsurface.cpp index d9ebac92a..43db66021 100644 --- a/src/compositor/compositor_api/qwaylandsurface.cpp +++ b/src/compositor/compositor_api/qwaylandsurface.cpp @@ -335,6 +335,7 @@ QtWayland::ClientBuffer *QWaylandSurfacePrivate::getBuffer(struct ::wl_resource /*! * \qmltype WaylandSurface + * \instantiates QWaylandSurface * \inqmlmodule QtWayland.Compositor * \since 5.8 * \brief Represents a rectangular area on an output device. @@ -1067,3 +1068,5 @@ void QWaylandSurfacePrivate::Subsurface::subsurface_set_desync(wl_subsurface::Re */ QT_END_NAMESPACE + +#include "moc_qwaylandsurface.cpp" diff --git a/src/compositor/compositor_api/qwaylandsurfacegrabber.cpp b/src/compositor/compositor_api/qwaylandsurfacegrabber.cpp index fd530cba5..889aad14c 100644 --- a/src/compositor/compositor_api/qwaylandsurfacegrabber.cpp +++ b/src/compositor/compositor_api/qwaylandsurfacegrabber.cpp @@ -109,3 +109,5 @@ void QWaylandSurfaceGrabber::grab() } QT_END_NAMESPACE + +#include "moc_qwaylandsurfacegrabber.cpp" diff --git a/src/compositor/compositor_api/qwaylandtouch.cpp b/src/compositor/compositor_api/qwaylandtouch.cpp index 87edaf9da..149ff7147 100644 --- a/src/compositor/compositor_api/qwaylandtouch.cpp +++ b/src/compositor/compositor_api/qwaylandtouch.cpp @@ -234,3 +234,5 @@ void QWaylandTouch::addClient(QWaylandClient *client, uint32_t id, uint32_t vers } QT_END_NAMESPACE + +#include "moc_qwaylandtouch.cpp" diff --git a/src/compositor/compositor_api/qwaylandview.cpp b/src/compositor/compositor_api/qwaylandview.cpp index 844da7c5d..241fc5c40 100644 --- a/src/compositor/compositor_api/qwaylandview.cpp +++ b/src/compositor/compositor_api/qwaylandview.cpp @@ -54,6 +54,7 @@ void QWaylandViewPrivate::markSurfaceAsDestroyed(QWaylandSurface *surface) /*! * \qmltype WaylandView + * \instantiates QWaylandView * \inqmlmodule QtWayland.Compositor * \since 5.8 * \brief Represents a view of a surface on an output. @@ -388,3 +389,5 @@ struct wl_resource *QWaylandView::surfaceResource() const } QT_END_NAMESPACE + +#include "moc_qwaylandview.cpp" diff --git a/src/compositor/extensions/qwaylandidleinhibitv1.cpp b/src/compositor/extensions/qwaylandidleinhibitv1.cpp index 3d7e4d135..c0c8de631 100644 --- a/src/compositor/extensions/qwaylandidleinhibitv1.cpp +++ b/src/compositor/extensions/qwaylandidleinhibitv1.cpp @@ -51,6 +51,7 @@ QT_BEGIN_NAMESPACE /*! \qmltype IdleInhibitManagerV1 + \instantiates QWaylandIdleInhibitManagerV1 \inqmlmodule QtWayland.Compositor \since 5.14 \brief Provides an extension that allows to inhibit the idle behavior of the compositor. @@ -181,3 +182,5 @@ void QWaylandIdleInhibitManagerV1Private::Inhibitor::zwp_idle_inhibitor_v1_destr } QT_END_NAMESPACE + +#include "moc_qwaylandidleinhibitv1.cpp" diff --git a/src/compositor/extensions/qwaylandiviapplication.cpp b/src/compositor/extensions/qwaylandiviapplication.cpp index 50242ab19..2dc6d3708 100644 --- a/src/compositor/extensions/qwaylandiviapplication.cpp +++ b/src/compositor/extensions/qwaylandiviapplication.cpp @@ -40,6 +40,7 @@ QT_BEGIN_NAMESPACE /*! * \qmltype IviApplication * \inqmlmodule QtWayland.Compositor + * \instantiates QWaylandIviApplication * \since 5.8 * \brief Provides a shell extension for embedded-style user interfaces. * @@ -203,3 +204,5 @@ void QWaylandIviApplicationPrivate::ivi_application_surface_create(QtWaylandServ } QT_END_NAMESPACE + +#include "moc_qwaylandiviapplication.cpp" diff --git a/src/compositor/extensions/qwaylandivisurface.cpp b/src/compositor/extensions/qwaylandivisurface.cpp index 81a7da107..a3f08559d 100644 --- a/src/compositor/extensions/qwaylandivisurface.cpp +++ b/src/compositor/extensions/qwaylandivisurface.cpp @@ -46,6 +46,7 @@ QWaylandSurfaceRole QWaylandIviSurfacePrivate::s_role("ivi_surface"); /*! * \qmltype IviSurface * \inqmlmodule QtWayland.Compositor + * \instantiates QWaylandIviSurface * \since 5.8 * \brief Provides a simple way to identify and resize a surface. * @@ -231,3 +232,5 @@ void QWaylandIviSurfacePrivate::ivi_surface_destroy(QtWaylandServer::ivi_surface } QT_END_NAMESPACE + +#include "moc_qwaylandivisurface.cpp" diff --git a/src/compositor/extensions/qwaylandivisurfaceintegration.cpp b/src/compositor/extensions/qwaylandivisurfaceintegration.cpp index f8cba9962..4287c3012 100644 --- a/src/compositor/extensions/qwaylandivisurfaceintegration.cpp +++ b/src/compositor/extensions/qwaylandivisurfaceintegration.cpp @@ -60,3 +60,5 @@ void IviSurfaceIntegration::handleIviSurfaceDestroyed() } QT_END_NAMESPACE + +#include "moc_qwaylandivisurfaceintegration_p.cpp" diff --git a/src/compositor/extensions/qwaylandqtwindowmanager.cpp b/src/compositor/extensions/qwaylandqtwindowmanager.cpp index d44dd456b..665099ad7 100644 --- a/src/compositor/extensions/qwaylandqtwindowmanager.cpp +++ b/src/compositor/extensions/qwaylandqtwindowmanager.cpp @@ -139,3 +139,5 @@ QByteArray QWaylandQtWindowManager::interfaceName() } QT_END_NAMESPACE + +#include "moc_qwaylandqtwindowmanager.cpp" diff --git a/src/compositor/extensions/qwaylandquickshellintegration.cpp b/src/compositor/extensions/qwaylandquickshellintegration.cpp index 100e4bd59..fa7b8aabb 100644 --- a/src/compositor/extensions/qwaylandquickshellintegration.cpp +++ b/src/compositor/extensions/qwaylandquickshellintegration.cpp @@ -80,6 +80,8 @@ * \sa QObject::eventFilter() */ +QT_BEGIN_NAMESPACE + QWaylandQuickShellIntegration::QWaylandQuickShellIntegration(QObject *parent) : QObject(parent) { @@ -88,3 +90,7 @@ QWaylandQuickShellIntegration::QWaylandQuickShellIntegration(QObject *parent) QWaylandQuickShellIntegration::~QWaylandQuickShellIntegration() { } + +QT_END_NAMESPACE + +#include "moc_qwaylandquickshellintegration.cpp" diff --git a/src/compositor/extensions/qwaylandquickshellsurfaceitem.cpp b/src/compositor/extensions/qwaylandquickshellsurfaceitem.cpp index 4952cef66..e9fdaa9ff 100644 --- a/src/compositor/extensions/qwaylandquickshellsurfaceitem.cpp +++ b/src/compositor/extensions/qwaylandquickshellsurfaceitem.cpp @@ -52,6 +52,7 @@ QWaylandQuickShellSurfaceItem *QWaylandQuickShellSurfaceItemPrivate::maybeCreate /*! * \qmltype ShellSurfaceItem + * \instantiates QWaylandQuickShellSurfaceItem * \inherits WaylandQuickItem * \inqmlmodule QtWayland.Compositor * \since 5.8 @@ -313,3 +314,7 @@ void QWaylandQuickShellEventFilter::timerEvent(QTimerEvent *event) } QT_END_NAMESPACE + +#include "moc_qwaylandquickshellsurfaceitem_p.cpp" + +#include "moc_qwaylandquickshellsurfaceitem.cpp" diff --git a/src/compositor/extensions/qwaylandquickxdgoutputv1.cpp b/src/compositor/extensions/qwaylandquickxdgoutputv1.cpp index b61cc490e..440773d4d 100644 --- a/src/compositor/extensions/qwaylandquickxdgoutputv1.cpp +++ b/src/compositor/extensions/qwaylandquickxdgoutputv1.cpp @@ -33,6 +33,8 @@ #include "qwaylandquickxdgoutputv1.h" #include "qwaylandxdgoutputv1_p.h" +QT_BEGIN_NAMESPACE + QWaylandQuickXdgOutputV1::QWaylandQuickXdgOutputV1() : QWaylandXdgOutputV1() { @@ -64,3 +66,7 @@ void QWaylandQuickXdgOutputV1::componentComplete() } } } + +QT_END_NAMESPACE + +#include "moc_qwaylandquickxdgoutputv1.cpp" diff --git a/src/compositor/extensions/qwaylandshell.cpp b/src/compositor/extensions/qwaylandshell.cpp index 45f80114e..a29dd5195 100644 --- a/src/compositor/extensions/qwaylandshell.cpp +++ b/src/compositor/extensions/qwaylandshell.cpp @@ -103,3 +103,5 @@ QWaylandShell::QWaylandShell(QWaylandObject *container, QWaylandCompositorExtens } QT_END_NAMESPACE + +#include "moc_qwaylandshell.cpp" diff --git a/src/compositor/extensions/qwaylandshellsurface.cpp b/src/compositor/extensions/qwaylandshellsurface.cpp index 74194b35e..268f1fe46 100644 --- a/src/compositor/extensions/qwaylandshellsurface.cpp +++ b/src/compositor/extensions/qwaylandshellsurface.cpp @@ -31,6 +31,7 @@ /*! * \qmltype ShellSurface + * \instantiates QWaylandShellSurface * \inqmlmodule QtWayland.Compositor * \since 5.8 * \brief Provides a common interface for surface roles specified by shell extensions. @@ -81,3 +82,9 @@ * * This property holds the window type of the QWaylandShellSurface. */ + +QT_BEGIN_NAMESPACE + +QT_END_NAMESPACE + +#include "moc_qwaylandshellsurface.cpp" diff --git a/src/compositor/extensions/qwaylandtextinput.cpp b/src/compositor/extensions/qwaylandtextinput.cpp index 5f6adac9d..deb70df4d 100644 --- a/src/compositor/extensions/qwaylandtextinput.cpp +++ b/src/compositor/extensions/qwaylandtextinput.cpp @@ -602,3 +602,5 @@ QByteArray QWaylandTextInput::interfaceName() } QT_END_NAMESPACE + +#include "moc_qwaylandtextinput.cpp" diff --git a/src/compositor/extensions/qwaylandtextinputmanager.cpp b/src/compositor/extensions/qwaylandtextinputmanager.cpp index 495ebae84..3fb2aec09 100644 --- a/src/compositor/extensions/qwaylandtextinputmanager.cpp +++ b/src/compositor/extensions/qwaylandtextinputmanager.cpp @@ -51,6 +51,8 @@ void QWaylandTextInputManagerPrivate::zwp_text_input_manager_v2_get_text_input(R textInput = new QWaylandTextInput(seat, compositor); } textInput->add(resource->client(), id, wl_resource_get_version(resource->handle)); + if (!textInput->isInitialized()) + textInput->initialize(); } QWaylandTextInputManager::QWaylandTextInputManager() @@ -87,3 +89,5 @@ QByteArray QWaylandTextInputManager::interfaceName() } QT_END_NAMESPACE + +#include "moc_qwaylandtextinputmanager.cpp" diff --git a/src/compositor/extensions/qwaylandviewporter.cpp b/src/compositor/extensions/qwaylandviewporter.cpp index b98274b1b..43cfff400 100644 --- a/src/compositor/extensions/qwaylandviewporter.cpp +++ b/src/compositor/extensions/qwaylandviewporter.cpp @@ -149,14 +149,16 @@ void QWaylandViewporterPrivate::Viewport::checkCommittedState() return; } - QRectF max = QRectF(QPointF(), m_surface->bufferSize() / m_surface->bufferScale()); - // We can't use QRectF.contains, because that would return false for values on the border - if (max.united(source) != max) { - wl_resource_post_error(resource()->handle, error_out_of_buffer, - "source %f,%f, %fx%f extends outside attached buffer %fx%f", - source.x(), source.y(), source.width(), source.height(), - max.width(), max.height()); - return; + if (m_surface->bufferSize().isValid()) { + QRectF max = QRectF(QPointF(), m_surface->bufferSize() / m_surface->bufferScale()); + // We can't use QRectF.contains, because that would return false for values on the border + if (max.united(source) != max) { + wl_resource_post_error(resource()->handle, error_out_of_buffer, + "source %f,%f, %fx%f extends outside attached buffer %fx%f", + source.x(), source.y(), source.width(), source.height(), + max.width(), max.height()); + return; + } } } @@ -234,3 +236,5 @@ void QWaylandViewporterPrivate::Viewport::wp_viewport_set_destination(QtWaylandS } QT_END_NAMESPACE + +#include "moc_qwaylandviewporter.cpp" diff --git a/src/compositor/extensions/qwaylandwlshell.cpp b/src/compositor/extensions/qwaylandwlshell.cpp index 6eb1c06e4..0c8467cb7 100644 --- a/src/compositor/extensions/qwaylandwlshell.cpp +++ b/src/compositor/extensions/qwaylandwlshell.cpp @@ -245,6 +245,7 @@ void QWaylandWlShellSurfacePrivate::shell_surface_set_class(Resource *resource, /*! * \qmltype WlShell * \inqmlmodule QtWayland.Compositor + * \instantiates QWaylandWlShell * \since 5.8 * \brief Provides an extension for desktop-style user interfaces. * @@ -414,6 +415,7 @@ QByteArray QWaylandWlShell::interfaceName() /*! * \qmltype WlShellSurface * \inqmlmodule QtWayland.Compositor + * \instantiates QWaylandWlShellSurface * \since 5.8 * \brief Provides a \c wl_shell_surface that offers desktop-style compositor-specific features to a surface. * @@ -699,3 +701,5 @@ QWaylandWlShellSurface *QWaylandWlShellSurface::fromResource(wl_resource *resour } QT_END_NAMESPACE + +#include "moc_qwaylandwlshell.cpp" diff --git a/src/compositor/extensions/qwaylandwlshellintegration.cpp b/src/compositor/extensions/qwaylandwlshellintegration.cpp index 3853d7eec..21ca53ba6 100644 --- a/src/compositor/extensions/qwaylandwlshellintegration.cpp +++ b/src/compositor/extensions/qwaylandwlshellintegration.cpp @@ -333,3 +333,5 @@ bool WlShellIntegration::filterMouseReleaseEvent(QMouseEvent *event) } QT_END_NAMESPACE + +#include "moc_qwaylandwlshellintegration_p.cpp" diff --git a/src/compositor/extensions/qwaylandxdgdecorationv1.cpp b/src/compositor/extensions/qwaylandxdgdecorationv1.cpp index 9fb2c955c..d81f52415 100644 --- a/src/compositor/extensions/qwaylandxdgdecorationv1.cpp +++ b/src/compositor/extensions/qwaylandxdgdecorationv1.cpp @@ -40,6 +40,7 @@ QT_BEGIN_NAMESPACE /*! \qmltype XdgDecorationManagerV1 \inqmlmodule QtWayland.Compositor + \instantiates QWaylandXdgDecorationManagerV1 \since 5.12 \brief Provides an extension for negotiation of server-side and client-side window decorations. @@ -251,3 +252,5 @@ void QWaylandXdgToplevelDecorationV1::handleClientPreferredModeChanged() } QT_END_NAMESPACE + +#include "moc_qwaylandxdgdecorationv1.cpp" diff --git a/src/compositor/extensions/qwaylandxdgoutputv1.cpp b/src/compositor/extensions/qwaylandxdgoutputv1.cpp index a78a9f62f..2a91e7dba 100644 --- a/src/compositor/extensions/qwaylandxdgoutputv1.cpp +++ b/src/compositor/extensions/qwaylandxdgoutputv1.cpp @@ -39,6 +39,7 @@ QT_BEGIN_NAMESPACE /*! * \qmltype XdgOutputManagerV1 * \inqmlmodule QtWayland.Compositor + * \instantiates QWaylandXdgOutputManagerV1 * \since 5.14 * \brief Provides an extension for describing outputs in a desktop oriented fashion. * @@ -586,3 +587,5 @@ void QWaylandXdgOutputV1Private::zxdg_output_v1_destroy(Resource *resource) } QT_END_NAMESPACE + +#include "moc_qwaylandxdgoutputv1.cpp" diff --git a/src/compositor/extensions/qwaylandxdgshell.cpp b/src/compositor/extensions/qwaylandxdgshell.cpp index e18885294..3ec73df1d 100644 --- a/src/compositor/extensions/qwaylandxdgshell.cpp +++ b/src/compositor/extensions/qwaylandxdgshell.cpp @@ -135,6 +135,7 @@ void QWaylandXdgShellPrivate::xdg_wm_base_pong(Resource *resource, uint32_t seri /*! * \qmltype XdgShell * \inqmlmodule QtWayland.Compositor + * \instantiates QWaylandXdgShell * \since 5.12 * \brief Provides an extension for desktop-style user interfaces. * @@ -455,6 +456,7 @@ void QWaylandXdgSurfacePrivate::xdg_surface_set_window_geometry(QtWaylandServer: /*! * \qmltype XdgSurface * \inqmlmodule QtWayland.Compositor + * \instantiates QWaylandXdgSurface * \since 5.12 * \brief XdgSurface provides desktop-style compositor-specific features to an xdg surface. * @@ -704,6 +706,7 @@ QWaylandQuickShellIntegration *QWaylandXdgSurface::createIntegration(QWaylandQui /*! * \qmltype XdgToplevel * \inqmlmodule QtWayland.Compositor + * \instantiates QWaylandXdgToplevel * \since 5.12 * \brief XdgToplevel represents the toplevel window specific parts of an xdg surface. * @@ -1541,6 +1544,7 @@ void QWaylandXdgToplevelPrivate::xdg_toplevel_set_minimized(QtWaylandServer::xdg /*! * \qmltype XdgPopup * \inqmlmodule QtWayland.Compositor + * \instantiates QWaylandXdgPopup * \since 5.12 * \brief XdgPopup represents the popup specific parts of and xdg surface. * @@ -2126,3 +2130,5 @@ Qt::Edges QWaylandXdgPositioner::convertToEdges(QWaylandXdgPositioner::gravity g QT_END_NAMESPACE + +#include "moc_qwaylandxdgshell.cpp" diff --git a/src/compositor/extensions/qwaylandxdgshellintegration.cpp b/src/compositor/extensions/qwaylandxdgshellintegration.cpp index a30eb228e..8be97f261 100644 --- a/src/compositor/extensions/qwaylandxdgshellintegration.cpp +++ b/src/compositor/extensions/qwaylandxdgshellintegration.cpp @@ -311,3 +311,5 @@ void XdgPopupIntegration::handleGeometryChanged() } QT_END_NAMESPACE + +#include "moc_qwaylandxdgshellintegration_p.cpp" diff --git a/src/compositor/extensions/qwlqtkey.cpp b/src/compositor/extensions/qwlqtkey.cpp index 03a97c7ee..030f760d9 100644 --- a/src/compositor/extensions/qwlqtkey.cpp +++ b/src/compositor/extensions/qwlqtkey.cpp @@ -69,3 +69,5 @@ bool QtKeyExtensionGlobal::postQtKeyEvent(QKeyEvent *event, QWaylandSurface *sur } QT_END_NAMESPACE + +#include "moc_qwlqtkey_p.cpp" diff --git a/src/compositor/extensions/qwlqttouch.cpp b/src/compositor/extensions/qwlqttouch.cpp index b47af06c1..5d080bafa 100644 --- a/src/compositor/extensions/qwlqttouch.cpp +++ b/src/compositor/extensions/qwlqttouch.cpp @@ -153,3 +153,5 @@ void TouchExtensionGlobal::touch_extension_destroy_resource(Resource *resource) } QT_END_NAMESPACE + +#include "moc_qwlqttouch_p.cpp" diff --git a/src/compositor/extensions/qwltexturesharingextension.cpp b/src/compositor/extensions/qwltexturesharingextension.cpp index bbd18e1a5..5e3b31300 100644 --- a/src/compositor/extensions/qwltexturesharingextension.cpp +++ b/src/compositor/extensions/qwltexturesharingextension.cpp @@ -484,4 +484,6 @@ void QWaylandTextureSharingExtension::dumpBufferInfo() QT_END_NAMESPACE +#include "moc_qwltexturesharingextension_p.cpp" + #include "qwltexturesharingextension.moc" diff --git a/src/compositor/global/qwaylandcompositorextension.cpp b/src/compositor/global/qwaylandcompositorextension.cpp index 6fc665130..a8141e542 100644 --- a/src/compositor/global/qwaylandcompositorextension.cpp +++ b/src/compositor/global/qwaylandcompositorextension.cpp @@ -176,3 +176,5 @@ void QWaylandObject::removeExtension(QWaylandCompositorExtension *extension) } QT_END_NAMESPACE + +#include "moc_qwaylandcompositorextension.cpp" diff --git a/src/compositor/hardware_integration/qwlclientbufferintegrationplugin.cpp b/src/compositor/hardware_integration/qwlclientbufferintegrationplugin.cpp index 8a90139d0..800b1ce24 100644 --- a/src/compositor/hardware_integration/qwlclientbufferintegrationplugin.cpp +++ b/src/compositor/hardware_integration/qwlclientbufferintegrationplugin.cpp @@ -45,3 +45,5 @@ ClientBufferIntegrationPlugin::~ClientBufferIntegrationPlugin() } QT_END_NAMESPACE + +#include "moc_qwlclientbufferintegrationplugin_p.cpp" diff --git a/src/compositor/hardware_integration/qwlhardwarelayerintegration.cpp b/src/compositor/hardware_integration/qwlhardwarelayerintegration.cpp index 7f346e1df..be24e9012 100644 --- a/src/compositor/hardware_integration/qwlhardwarelayerintegration.cpp +++ b/src/compositor/hardware_integration/qwlhardwarelayerintegration.cpp @@ -36,3 +36,5 @@ namespace QtWayland { } QT_END_NAMESPACE + +#include "moc_qwlhardwarelayerintegration_p.cpp" diff --git a/src/compositor/hardware_integration/qwlhardwarelayerintegrationplugin.cpp b/src/compositor/hardware_integration/qwlhardwarelayerintegrationplugin.cpp index 4106434ab..7f347c3e6 100644 --- a/src/compositor/hardware_integration/qwlhardwarelayerintegrationplugin.cpp +++ b/src/compositor/hardware_integration/qwlhardwarelayerintegrationplugin.cpp @@ -45,3 +45,5 @@ HardwareLayerIntegrationPlugin::~HardwareLayerIntegrationPlugin() } QT_END_NAMESPACE + +#include "moc_qwlhardwarelayerintegrationplugin_p.cpp" diff --git a/src/compositor/hardware_integration/qwlserverbufferintegrationplugin.cpp b/src/compositor/hardware_integration/qwlserverbufferintegrationplugin.cpp index 0d047d4f1..2bfc0e920 100644 --- a/src/compositor/hardware_integration/qwlserverbufferintegrationplugin.cpp +++ b/src/compositor/hardware_integration/qwlserverbufferintegrationplugin.cpp @@ -46,3 +46,5 @@ ServerBufferIntegrationPlugin::~ServerBufferIntegrationPlugin() QT_END_NAMESPACE +#include "moc_qwlserverbufferintegrationplugin_p.cpp" + diff --git a/src/compositor/wayland_wrapper/qwldatadevicemanager.cpp b/src/compositor/wayland_wrapper/qwldatadevicemanager.cpp index d72bdf36d..a1dbfc767 100644 --- a/src/compositor/wayland_wrapper/qwldatadevicemanager.cpp +++ b/src/compositor/wayland_wrapper/qwldatadevicemanager.cpp @@ -271,3 +271,5 @@ const struct wl_data_offer_interface DataDeviceManager::compositor_offer_interfa } //namespace QT_END_NAMESPACE + +#include "moc_qwldatadevicemanager_p.cpp" diff --git a/src/hardwareintegration/client/brcm-egl/qwaylandbrcmeglwindow.cpp b/src/hardwareintegration/client/brcm-egl/qwaylandbrcmeglwindow.cpp index 1230b067a..3e3ede314 100644 --- a/src/hardwareintegration/client/brcm-egl/qwaylandbrcmeglwindow.cpp +++ b/src/hardwareintegration/client/brcm-egl/qwaylandbrcmeglwindow.cpp @@ -185,14 +185,14 @@ void QWaylandBrcmEglWindow::createEglSurfaces() m_count = window()->format().swapBehavior() == QSurfaceFormat::TripleBuffer ? 3 : 2; - m_eglConfig = q_configFromGLFormat(m_eglIntegration->eglDisplay(), brcmFixFormat(window()->format()), true, EGL_PIXMAP_BIT); + EGLConfig eglConfig = q_configFromGLFormat(m_eglIntegration->eglDisplay(), brcmFixFormat(window()->format()), true, EGL_PIXMAP_BIT); - m_format = q_glFormatFromConfig(m_eglIntegration->eglDisplay(), m_eglConfig); + m_format = q_glFormatFromConfig(m_eglIntegration->eglDisplay(), eglConfig); EGLint pixel_format = EGL_PIXEL_FORMAT_ARGB_8888_BRCM; EGLint rt; - eglGetConfigAttrib(m_eglIntegration->eglDisplay(), m_eglConfig, EGL_RENDERABLE_TYPE, &rt); + eglGetConfigAttrib(m_eglIntegration->eglDisplay(), eglConfig, EGL_RENDERABLE_TYPE, &rt); if (rt & EGL_OPENGL_ES_BIT) { pixel_format |= EGL_PIXEL_FORMAT_RENDER_GLES_BRCM; @@ -228,7 +228,7 @@ void QWaylandBrcmEglWindow::createEglSurfaces() EGL_NONE }; - m_eglSurfaces[i] = eglCreatePixmapSurface(m_eglIntegration->eglDisplay(), m_eglConfig, (EGLNativePixmapType)&m_globalImages[5*i], attrs); + m_eglSurfaces[i] = eglCreatePixmapSurface(m_eglIntegration->eglDisplay(), eglConfig, (EGLNativePixmapType)&m_globalImages[5*i], attrs); if (m_eglSurfaces[i] == EGL_NO_SURFACE) qFatal("eglCreatePixmapSurface failed: %x, global image id: %d %d\n", eglGetError(), m_globalImages[5*i], m_globalImages[5*i+1]); m_buffers[i] = new QWaylandBrcmBuffer(mDisplay, m_eglIntegration->waylandBrcm(), size, &m_globalImages[5*i], 5, m_eventQueue); diff --git a/src/hardwareintegration/client/brcm-egl/qwaylandbrcmeglwindow.h b/src/hardwareintegration/client/brcm-egl/qwaylandbrcmeglwindow.h index 634b4e2d0..08994255a 100644 --- a/src/hardwareintegration/client/brcm-egl/qwaylandbrcmeglwindow.h +++ b/src/hardwareintegration/client/brcm-egl/qwaylandbrcmeglwindow.h @@ -77,8 +77,6 @@ private: const QWaylandWindow *m_parentWindow = nullptr; - EGLConfig m_eglConfig = 0; - EGLint m_globalImages[3*5]; EGLSurface m_eglSurfaces[3]; diff --git a/src/hardwareintegration/client/wayland-egl/qwaylandeglwindow.cpp b/src/hardwareintegration/client/wayland-egl/qwaylandeglwindow.cpp index 7889f575f..e00c28c3b 100644 --- a/src/hardwareintegration/client/wayland-egl/qwaylandeglwindow.cpp +++ b/src/hardwareintegration/client/wayland-egl/qwaylandeglwindow.cpp @@ -57,17 +57,8 @@ namespace QtWaylandClient { QWaylandEglWindow::QWaylandEglWindow(QWindow *window, QWaylandDisplay *display) : QWaylandWindow(window, display) , m_clientBufferIntegration(static_cast<QWaylandEglClientBufferIntegration *>(mDisplay->clientBufferIntegration())) + , m_format(window->requestedFormat()) { - QSurfaceFormat fmt = window->requestedFormat(); - if (mDisplay->supportsWindowDecoration()) - fmt.setAlphaBufferSize(8); - m_eglConfig = q_configFromGLFormat(m_clientBufferIntegration->eglDisplay(), fmt); - m_format = q_glFormatFromConfig(m_clientBufferIntegration->eglDisplay(), m_eglConfig, fmt); - - // Do not create anything from here. This platform window may belong to a - // RasterGLSurface window which may have pure raster content. In this case, where the - // window is never actually made current, creating a wl_egl_window and EGL surface - // should be avoided. } QWaylandEglWindow::~QWaylandEglWindow() @@ -143,7 +134,13 @@ void QWaylandEglWindow::updateSurface(bool create) if (!m_eglSurface && m_waylandEglWindow && create) { EGLNativeWindowType eglw = (EGLNativeWindowType) m_waylandEglWindow; - m_eglSurface = eglCreateWindowSurface(m_clientBufferIntegration->eglDisplay(), m_eglConfig, eglw, 0); + QSurfaceFormat fmt = window()->requestedFormat(); + + if (mDisplay->supportsWindowDecoration()) + fmt.setAlphaBufferSize(8); + EGLConfig eglConfig = q_configFromGLFormat(m_clientBufferIntegration->eglDisplay(), fmt); + m_format = q_glFormatFromConfig(m_clientBufferIntegration->eglDisplay(), eglConfig); + m_eglSurface = eglCreateWindowSurface(m_clientBufferIntegration->eglDisplay(), eglConfig, eglw, 0); if (Q_UNLIKELY(m_eglSurface == EGL_NO_SURFACE)) qCWarning(lcQpaWayland, "Could not create EGL surface (EGL error 0x%x)\n", eglGetError()); } @@ -212,3 +209,5 @@ void QWaylandEglWindow::bindContentFBO() } QT_END_NAMESPACE + +#include "moc_qwaylandeglwindow.cpp" diff --git a/src/hardwareintegration/client/wayland-egl/qwaylandeglwindow.h b/src/hardwareintegration/client/wayland-egl/qwaylandeglwindow.h index 5b1f4d56f..2fccbcea5 100644 --- a/src/hardwareintegration/client/wayland-egl/qwaylandeglwindow.h +++ b/src/hardwareintegration/client/wayland-egl/qwaylandeglwindow.h @@ -80,10 +80,7 @@ private: QWaylandEglClientBufferIntegration *m_clientBufferIntegration = nullptr; struct wl_egl_window *m_waylandEglWindow = nullptr; - const QWaylandWindow *m_parentWindow = nullptr; - EGLSurface m_eglSurface = EGL_NO_SURFACE; - EGLConfig m_eglConfig; mutable bool m_resize = false; mutable QOpenGLFramebufferObject *m_contentFBO = nullptr; diff --git a/src/hardwareintegration/client/wayland-egl/qwaylandglcontext.cpp b/src/hardwareintegration/client/wayland-egl/qwaylandglcontext.cpp index 681f82f4a..c1f45fa69 100644 --- a/src/hardwareintegration/client/wayland-egl/qwaylandglcontext.cpp +++ b/src/hardwareintegration/client/wayland-egl/qwaylandglcontext.cpp @@ -192,7 +192,6 @@ public: } void blit(QWaylandEglWindow *window) { - Q_ASSERT(window->wlSurface()); QOpenGLTextureCache *cache = QOpenGLTextureCache::cacheForContext(m_context->context()); QSize surfaceSize = window->surfaceSize(); @@ -406,6 +405,8 @@ void QWaylandGLContext::updateGLFormat() QWaylandGLContext::~QWaylandGLContext() { delete m_blitter; + if (m_decorationsContext != EGL_NO_CONTEXT) + eglDestroyContext(m_eglDisplay, m_decorationsContext); eglDestroyContext(m_eglDisplay, m_context); } diff --git a/src/hardwareintegration/client/xcomposite-egl/qwaylandxcompositeeglwindow.cpp b/src/hardwareintegration/client/xcomposite-egl/qwaylandxcompositeeglwindow.cpp index a7377830f..d72c1bea8 100644 --- a/src/hardwareintegration/client/xcomposite-egl/qwaylandxcompositeeglwindow.cpp +++ b/src/hardwareintegration/client/xcomposite-egl/qwaylandxcompositeeglwindow.cpp @@ -57,7 +57,6 @@ namespace QtWaylandClient { QWaylandXCompositeEGLWindow::QWaylandXCompositeEGLWindow(QWindow *window, QWaylandXCompositeEGLClientBufferIntegration *glxIntegration) : QWaylandWindow(window, glxIntegration->waylandDisplay()) , m_glxIntegration(glxIntegration) - , m_config(q_configFromGLFormat(glxIntegration->eglDisplay(), window->format(), true, EGL_WINDOW_BIT | EGL_PIXMAP_BIT)) { } @@ -98,7 +97,9 @@ void QWaylandXCompositeEGLWindow::createEglSurface() XDestroyWindow(m_glxIntegration->xDisplay(), m_xWindow); } - VisualID visualId = QXlibEglIntegration::getCompatibleVisualId(m_glxIntegration->xDisplay(), m_glxIntegration->eglDisplay(), m_config); + EGLConfig eglConfig = q_configFromGLFormat(m_glxIntegration->eglDisplay(), window()->format(), true, EGL_WINDOW_BIT | EGL_PIXMAP_BIT); + + VisualID visualId = QXlibEglIntegration::getCompatibleVisualId(m_glxIntegration->xDisplay(), m_glxIntegration->eglDisplay(), eglConfig); XVisualInfo visualInfoTemplate; memset(&visualInfoTemplate, 0, sizeof(XVisualInfo)); @@ -118,7 +119,7 @@ void QWaylandXCompositeEGLWindow::createEglSurface() XCompositeRedirectWindow(m_glxIntegration->xDisplay(), m_xWindow, CompositeRedirectManual); XMapWindow(m_glxIntegration->xDisplay(), m_xWindow); - m_surface = eglCreateWindowSurface(m_glxIntegration->eglDisplay(), m_config, reinterpret_cast<EGLNativeWindowType>(m_xWindow), nullptr); + m_surface = eglCreateWindowSurface(m_glxIntegration->eglDisplay(), eglConfig, reinterpret_cast<EGLNativeWindowType>(m_xWindow), nullptr); if (m_surface == EGL_NO_SURFACE) { qFatal("Could not make eglsurface"); } diff --git a/src/hardwareintegration/client/xcomposite-egl/qwaylandxcompositeeglwindow.h b/src/hardwareintegration/client/xcomposite-egl/qwaylandxcompositeeglwindow.h index 0c8bcf441..316ca5758 100644 --- a/src/hardwareintegration/client/xcomposite-egl/qwaylandxcompositeeglwindow.h +++ b/src/hardwareintegration/client/xcomposite-egl/qwaylandxcompositeeglwindow.h @@ -69,7 +69,6 @@ private: QWaylandBuffer *m_buffer = nullptr; Window m_xWindow = 0; - EGLConfig m_config; EGLSurface m_surface = EGL_NO_SURFACE; }; diff --git a/src/hardwareintegration/client/xcomposite-glx/qwaylandxcompositeglxwindow.cpp b/src/hardwareintegration/client/xcomposite-glx/qwaylandxcompositeglxwindow.cpp index b0c78b631..ccc1a8b58 100644 --- a/src/hardwareintegration/client/xcomposite-glx/qwaylandxcompositeglxwindow.cpp +++ b/src/hardwareintegration/client/xcomposite-glx/qwaylandxcompositeglxwindow.cpp @@ -54,7 +54,6 @@ namespace QtWaylandClient { QWaylandXCompositeGLXWindow::QWaylandXCompositeGLXWindow(QWindow *window, QWaylandXCompositeGLXIntegration *glxIntegration) : QWaylandWindow(window, glxIntegration->waylandDisplay()) , m_glxIntegration(glxIntegration) - , m_config(qglx_findConfig(glxIntegration->xDisplay(), glxIntegration->screen(), window->format(), GLX_WINDOW_BIT | GLX_PIXMAP_BIT)) { } @@ -95,7 +94,8 @@ void QWaylandXCompositeGLXWindow::createSurface() return; } - XVisualInfo *visualInfo = glXGetVisualFromFBConfig(m_glxIntegration->xDisplay(), m_config); + GLXFBConfig glxConfig = qglx_findConfig(m_glxIntegration->xDisplay(), m_glxIntegration->screen(), window()->format(), GLX_WINDOW_BIT | GLX_PIXMAP_BIT); + XVisualInfo *visualInfo = glXGetVisualFromFBConfig(m_glxIntegration->xDisplay(), glxConfig); Colormap cmap = XCreateColormap(m_glxIntegration->xDisplay(), m_glxIntegration->rootWindow(), visualInfo->visual, AllocNone); diff --git a/src/hardwareintegration/client/xcomposite-glx/qwaylandxcompositeglxwindow.h b/src/hardwareintegration/client/xcomposite-glx/qwaylandxcompositeglxwindow.h index 45a77a299..f49602c44 100644 --- a/src/hardwareintegration/client/xcomposite-glx/qwaylandxcompositeglxwindow.h +++ b/src/hardwareintegration/client/xcomposite-glx/qwaylandxcompositeglxwindow.h @@ -70,7 +70,6 @@ private: QWaylandXCompositeGLXIntegration *m_glxIntegration = nullptr; Window m_xWindow = 0; - GLXFBConfig m_config; QWaylandBuffer *mBuffer = nullptr; }; diff --git a/src/hardwareintegration/compositor/linux-dmabuf-unstable-v1/linuxdmabuf.h b/src/hardwareintegration/compositor/linux-dmabuf-unstable-v1/linuxdmabuf.h index 56a710c3d..c6a8b6c64 100644 --- a/src/hardwareintegration/compositor/linux-dmabuf-unstable-v1/linuxdmabuf.h +++ b/src/hardwareintegration/compositor/linux-dmabuf-unstable-v1/linuxdmabuf.h @@ -41,6 +41,8 @@ #include <QtCore/QTextStream> #include <QtGui/QOpenGLTexture> +#include <array> + #include <EGL/egl.h> #include <EGL/eglext.h> diff --git a/src/hardwareintegration/compositor/linux-dmabuf-unstable-v1/linuxdmabufclientbufferintegration.cpp b/src/hardwareintegration/compositor/linux-dmabuf-unstable-v1/linuxdmabufclientbufferintegration.cpp index 74417586a..6a3beaab9 100644 --- a/src/hardwareintegration/compositor/linux-dmabuf-unstable-v1/linuxdmabufclientbufferintegration.cpp +++ b/src/hardwareintegration/compositor/linux-dmabuf-unstable-v1/linuxdmabufclientbufferintegration.cpp @@ -105,6 +105,11 @@ static QOpenGLTexture::TextureFormat openGLFormatFromBufferFormat(QWaylandBuffer } } +// Initialize the EGLImage for a dmabuf buffer which conceptually consists of a +// single plane. Note that depending on the modifiers, the buffer may be actually +// transported as multiple dmabuf planes which must be combined into a single +// EGLImage. For formats where the buffer needs to be represented as multiple +// EGLImages (e.g., various YUV formats) a different approach is required. bool LinuxDmabufClientBufferIntegration::initSimpleTexture(LinuxDmabufWlBuffer *dmabufBuffer) { bool success = true; @@ -118,79 +123,67 @@ bool LinuxDmabufClientBufferIntegration::initSimpleTexture(LinuxDmabufWlBuffer * success = false; } - for (uint32_t i = 0; i < dmabufBuffer->planesNumber(); ++i) { - QVarLengthArray<EGLint, 17> attribs; - switch (i) { - case 0: - attribs = { - EGL_WIDTH, dmabufBuffer->size().width(), - EGL_HEIGHT, dmabufBuffer->size().height(), - EGL_LINUX_DRM_FOURCC_EXT, EGLint(dmabufBuffer->drmFormat()), - EGL_DMA_BUF_PLANE0_FD_EXT, dmabufBuffer->plane(i).fd, - EGL_DMA_BUF_PLANE0_OFFSET_EXT, EGLint(dmabufBuffer->plane(i).offset), - EGL_DMA_BUF_PLANE0_PITCH_EXT, EGLint(dmabufBuffer->plane(i).stride), - EGL_DMA_BUF_PLANE0_MODIFIER_LO_EXT, EGLint(dmabufBuffer->plane(i).modifiers & 0xffffffff), - EGL_DMA_BUF_PLANE0_MODIFIER_HI_EXT, EGLint(dmabufBuffer->plane(i).modifiers >> 32), - EGL_NONE - }; - break; - case 1: - attribs = { - EGL_WIDTH, dmabufBuffer->size().width(), - EGL_HEIGHT, dmabufBuffer->size().height(), - EGL_LINUX_DRM_FOURCC_EXT, EGLint(dmabufBuffer->drmFormat()), - EGL_DMA_BUF_PLANE1_FD_EXT, dmabufBuffer->plane(i).fd, - EGL_DMA_BUF_PLANE1_OFFSET_EXT, EGLint(dmabufBuffer->plane(i).offset), - EGL_DMA_BUF_PLANE1_PITCH_EXT, EGLint(dmabufBuffer->plane(i).stride), - EGL_DMA_BUF_PLANE1_MODIFIER_LO_EXT, EGLint(dmabufBuffer->plane(i).modifiers & 0xffffffff), - EGL_DMA_BUF_PLANE1_MODIFIER_HI_EXT, EGLint(dmabufBuffer->plane(i).modifiers >> 32), - EGL_NONE - }; - break; - case 2: - attribs = { - EGL_WIDTH, dmabufBuffer->size().width(), - EGL_HEIGHT, dmabufBuffer->size().height(), - EGL_LINUX_DRM_FOURCC_EXT, EGLint(dmabufBuffer->drmFormat()), - EGL_DMA_BUF_PLANE2_FD_EXT, dmabufBuffer->plane(i).fd, - EGL_DMA_BUF_PLANE2_OFFSET_EXT, EGLint(dmabufBuffer->plane(i).offset), - EGL_DMA_BUF_PLANE2_PITCH_EXT, EGLint(dmabufBuffer->plane(i).stride), - EGL_DMA_BUF_PLANE2_MODIFIER_LO_EXT, EGLint(dmabufBuffer->plane(i).modifiers & 0xffffffff), - EGL_DMA_BUF_PLANE2_MODIFIER_HI_EXT, EGLint(dmabufBuffer->plane(i).modifiers >> 32), - EGL_NONE - }; - break; - case 3: - attribs = { - EGL_WIDTH, dmabufBuffer->size().width(), - EGL_HEIGHT, dmabufBuffer->size().height(), - EGL_LINUX_DRM_FOURCC_EXT, EGLint(dmabufBuffer->drmFormat()), - EGL_DMA_BUF_PLANE3_FD_EXT, dmabufBuffer->plane(i).fd, - EGL_DMA_BUF_PLANE3_OFFSET_EXT, EGLint(dmabufBuffer->plane(i).offset), - EGL_DMA_BUF_PLANE3_PITCH_EXT, EGLint(dmabufBuffer->plane(i).stride), - EGL_DMA_BUF_PLANE3_MODIFIER_LO_EXT, EGLint(dmabufBuffer->plane(i).modifiers & 0xffffffff), - EGL_DMA_BUF_PLANE3_MODIFIER_HI_EXT, EGLint(dmabufBuffer->plane(i).modifiers >> 32), - EGL_NONE - }; + // 6 entries for the common attribs plus 10 per possible plane, plus 1 for + // the final EGL_NONE sentinel. + QVarLengthArray<EGLint, 6 + 10 * 4 + 1> attribs; + + attribs.append(EGL_WIDTH); + attribs.append(dmabufBuffer->size().width()); + attribs.append(EGL_HEIGHT); + attribs.append(dmabufBuffer->size().height()); + attribs.append(EGL_LINUX_DRM_FOURCC_EXT); + attribs.append(EGLint(dmabufBuffer->drmFormat())); + +#define ADD_PLANE_ATTRIBS(plane_idx) { \ + attribs.append(EGL_DMA_BUF_PLANE ## plane_idx ## _FD_EXT); \ + attribs.append(dmabufBuffer->plane(plane_idx).fd); \ + attribs.append(EGL_DMA_BUF_PLANE ## plane_idx ## _OFFSET_EXT); \ + attribs.append(EGLint(dmabufBuffer->plane(plane_idx).offset)); \ + attribs.append(EGL_DMA_BUF_PLANE ## plane_idx ## _PITCH_EXT); \ + attribs.append(EGLint(dmabufBuffer->plane(plane_idx).stride)); \ + if (dmabufBuffer->plane(plane_idx).modifiers != DRM_FORMAT_MOD_INVALID) { \ + attribs.append(EGL_DMA_BUF_PLANE ## plane_idx ## _MODIFIER_LO_EXT); \ + attribs.append(EGLint(dmabufBuffer->plane(plane_idx).modifiers & 0xffffffff)); \ + attribs.append(EGL_DMA_BUF_PLANE ## plane_idx ## _MODIFIER_HI_EXT); \ + attribs.append(EGLint(dmabufBuffer->plane(plane_idx).modifiers >> 32)); \ + } \ +} + + switch (dmabufBuffer->planesNumber()) { + case 4: + ADD_PLANE_ATTRIBS(3); + Q_FALLTHROUGH(); + case 3: + ADD_PLANE_ATTRIBS(2); + Q_FALLTHROUGH(); + case 2: + ADD_PLANE_ATTRIBS(1); + Q_FALLTHROUGH(); + case 1: + ADD_PLANE_ATTRIBS(0); break; - default: - return false; - } + default: + qCWarning(qLcWaylandCompositorHardwareIntegration) << "Buffer uses invalid number of planes:" << dmabufBuffer->planesNumber(); + return false; + } - // note: EGLImageKHR does NOT take ownership of the file descriptors - EGLImageKHR image = egl_create_image(m_eglDisplay, - EGL_NO_CONTEXT, - EGL_LINUX_DMA_BUF_EXT, - (EGLClientBuffer) nullptr, - attribs.constData()); + attribs.append(EGL_NONE); - if (image == EGL_NO_IMAGE_KHR) { - qCWarning(qLcWaylandCompositorHardwareIntegration) << "failed to create EGL image for plane" << i; - success = false; - } + // note: EGLImageKHR does NOT take ownership of the file descriptors + EGLImageKHR image = egl_create_image(m_eglDisplay, + EGL_NO_CONTEXT, + EGL_LINUX_DMA_BUF_EXT, + (EGLClientBuffer) nullptr, + attribs.constData()); - dmabufBuffer->initImage(i, image); + if (image == EGL_NO_IMAGE_KHR) { + qCWarning(qLcWaylandCompositorHardwareIntegration) << "failed to create EGL image from" << + dmabufBuffer->planesNumber() << "plane(s)"; + success = false; } + + dmabufBuffer->initImage(0, image); + return success; } diff --git a/src/imports/texture-sharing/sharedtextureprovider.cpp b/src/imports/texture-sharing/sharedtextureprovider.cpp index 707e94ae6..6cd49de1d 100644 --- a/src/imports/texture-sharing/sharedtextureprovider.cpp +++ b/src/imports/texture-sharing/sharedtextureprovider.cpp @@ -319,4 +319,6 @@ QQuickImageResponse *SharedTextureProvider::requestImageResponse(const QString & QT_END_NAMESPACE +#include "moc_sharedtextureprovider.cpp" + #include "sharedtextureprovider.moc" diff --git a/src/imports/texture-sharing/texturesharingextension.cpp b/src/imports/texture-sharing/texturesharingextension.cpp index 31106d694..6011477c4 100644 --- a/src/imports/texture-sharing/texturesharingextension.cpp +++ b/src/imports/texture-sharing/texturesharingextension.cpp @@ -84,3 +84,5 @@ void TextureSharingExtension::abandonImage(const QString &key) } QT_END_NAMESPACE + +#include "moc_texturesharingextension.cpp" diff --git a/src/plugins/decorations/bradient/main.cpp b/src/plugins/decorations/bradient/main.cpp index e75fda3ce..fa8851436 100644 --- a/src/plugins/decorations/bradient/main.cpp +++ b/src/plugins/decorations/bradient/main.cpp @@ -164,13 +164,10 @@ void QWaylandBradientDecoration::paint(QPaintDevice *device) // Window icon QIcon icon = waylandWindow()->windowIcon(); if (!icon.isNull()) { - QPixmap pixmap = icon.pixmap(QSize(128, 128)); - QPixmap scaled = pixmap.scaled(22, 22, Qt::IgnoreAspectRatio, Qt::SmoothTransformation); - QRectF iconRect(0, 0, 22, 22); - p.drawPixmap(iconRect.adjusted(margins().left() + BUTTON_SPACING, 4, - margins().left() + BUTTON_SPACING, 4), - scaled, iconRect); + iconRect.adjust(margins().left() + BUTTON_SPACING, 4, + margins().left() + BUTTON_SPACING, 4), + icon.paint(&p, iconRect.toRect()); } // Window title diff --git a/src/plugins/shellintegration/wl-shell/qwaylandwlshellsurface.cpp b/src/plugins/shellintegration/wl-shell/qwaylandwlshellsurface.cpp index 8f41118d8..688255cab 100644 --- a/src/plugins/shellintegration/wl-shell/qwaylandwlshellsurface.cpp +++ b/src/plugins/shellintegration/wl-shell/qwaylandwlshellsurface.cpp @@ -288,3 +288,5 @@ void QWaylandWlShellSurface::shell_surface_popup_done() } QT_END_NAMESPACE + +#include "moc_qwaylandwlshellsurface_p.cpp" diff --git a/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp b/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp index 1c762944c..94ea573e3 100644 --- a/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp +++ b/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp @@ -178,9 +178,12 @@ void QWaylandXdgSurface::Toplevel::requestWindowStates(Qt::WindowStates states) } if (changedStates & Qt::WindowFullScreen) { - if (states & Qt::WindowFullScreen) - set_fullscreen(nullptr); - else + if (states & Qt::WindowFullScreen) { + auto screen = m_xdgSurface->window()->waylandScreen(); + if (screen) { + set_fullscreen(screen->output()); + } + } else unset_fullscreen(); } @@ -217,6 +220,16 @@ QWaylandXdgSurface::Popup::~Popup() auto *shell = m_xdgSurface->m_shell; Q_ASSERT(shell->m_topmostGrabbingPopup == this); shell->m_topmostGrabbingPopup = m_parent->m_popup; + m_grabbing = false; + + // Synthesize Qt enter/leave events for popup + QWindow *leave = nullptr; + if (m_xdgSurface && m_xdgSurface->window()) + leave = m_xdgSurface->window()->window(); + QWindowSystemInterface::handleLeaveEvent(leave); + + if (QWindow *enter = QGuiApplication::topLevelAt(QCursor::pos())) + QWindowSystemInterface::handleEnterEvent(enter, enter->mapFromGlobal(QCursor::pos()), QCursor::pos()); } } @@ -332,15 +345,16 @@ bool QWaylandXdgSurface::handleExpose(const QRegion ®ion) void QWaylandXdgSurface::applyConfigure() { - Q_ASSERT(m_pendingConfigureSerial != 0); + // It is a redundant ack_configure, so skipped. + if (m_pendingConfigureSerial == m_appliedConfigureSerial) + return; if (m_toplevel) m_toplevel->applyConfigure(); + m_appliedConfigureSerial = m_pendingConfigureSerial; m_configured = true; - ack_configure(m_pendingConfigureSerial); - - m_pendingConfigureSerial = 0; + ack_configure(m_appliedConfigureSerial); } bool QWaylandXdgSurface::wantsDecorations() const @@ -410,6 +424,10 @@ void QWaylandXdgSurface::setPopup(QWaylandWindow *parent) positioner->set_anchor(QtWayland::xdg_positioner::anchor_top_left); positioner->set_gravity(QtWayland::xdg_positioner::gravity_bottom_right); positioner->set_size(m_window->geometry().width(), m_window->geometry().height()); + positioner->set_constraint_adjustment(QtWayland::xdg_positioner::constraint_adjustment_slide_x + | QtWayland::xdg_positioner::constraint_adjustment_slide_y + | QtWayland::xdg_positioner::constraint_adjustment_flip_x + | QtWayland::xdg_positioner::constraint_adjustment_flip_y); m_popup = new Popup(this, parentXdgSurface, positioner); positioner->destroy(); delete positioner; @@ -433,6 +451,23 @@ void QWaylandXdgSurface::setGrabPopup(QWaylandWindow *parent, QWaylandInputDevic } setPopup(parent); m_popup->grab(device, serial); + + // Synthesize Qt enter/leave events for popup + if (!parent) + return; + QWindow *current = QGuiApplication::topLevelAt(QCursor::pos()); + QWindow *leave = parent->window(); + if (current != leave) + return; + + QWindowSystemInterface::handleLeaveEvent(leave); + + QWindow *enter = nullptr; + if (m_popup && m_popup->m_xdgSurface && m_popup->m_xdgSurface->window()) + enter = m_popup->m_xdgSurface->window()->window(); + + if (enter) + QWindowSystemInterface::handleEnterEvent(enter, enter->mapFromGlobal(QCursor::pos()), QCursor::pos()); } void QWaylandXdgSurface::xdg_surface_configure(uint32_t serial) @@ -488,3 +523,5 @@ void QWaylandXdgShell::handleRegistryGlobal(void *data, wl_registry *registry, u } QT_END_NAMESPACE + +#include "moc_qwaylandxdgshell_p.cpp" diff --git a/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell_p.h b/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell_p.h index 0c98be35c..96785205f 100644 --- a/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell_p.h +++ b/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell_p.h @@ -153,6 +153,7 @@ private: bool m_configured = false; QRegion m_exposeRegion; uint m_pendingConfigureSerial = 0; + uint m_appliedConfigureSerial = 0; friend class QWaylandXdgShell; }; diff --git a/src/shared/qwaylandinputmethodeventbuilder.cpp b/src/shared/qwaylandinputmethodeventbuilder.cpp index 526d0ef46..f50ccf302 100644 --- a/src/shared/qwaylandinputmethodeventbuilder.cpp +++ b/src/shared/qwaylandinputmethodeventbuilder.cpp @@ -39,7 +39,10 @@ #include "qwaylandinputmethodeventbuilder_p.h" +#include <QBrush> +#include <QGuiApplication> #include <QInputMethod> +#include <QPalette> #include <QTextCharFormat> #ifdef QT_BUILD_WAYLANDCOMPOSITOR_LIB @@ -81,32 +84,38 @@ void QWaylandInputMethodEventBuilder::addPreeditStyling(uint32_t index, uint32_t QTextCharFormat format; switch (style) { - case 0: - case 1: + case ZWP_TEXT_INPUT_V2_PREEDIT_STYLE_NONE: + break; + case ZWP_TEXT_INPUT_V2_PREEDIT_STYLE_DEFAULT: + case ZWP_TEXT_INPUT_V2_PREEDIT_STYLE_UNDERLINE: format.setFontUnderline(true); format.setUnderlineStyle(QTextCharFormat::SingleUnderline); m_preeditStyles.append(QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat, index, length, format)); break; - case 2: - case 3: + case ZWP_TEXT_INPUT_V2_PREEDIT_STYLE_ACTIVE: + case ZWP_TEXT_INPUT_V2_PREEDIT_STYLE_INACTIVE: format.setFontWeight(QFont::Bold); format.setFontUnderline(true); format.setUnderlineStyle(QTextCharFormat::SingleUnderline); m_preeditStyles.append(QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat, index, length, format)); break; - case 4: - format.setFontUnderline(true); - format.setUnderlineStyle(QTextCharFormat::SingleUnderline); - m_preeditStyles.append(QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat, index, length, format)); + case ZWP_TEXT_INPUT_V2_PREEDIT_STYLE_HIGHLIGHT: + case ZWP_TEXT_INPUT_V2_PREEDIT_STYLE_SELECTION: + { + format.setFontUnderline(true); + format.setUnderlineStyle(QTextCharFormat::SingleUnderline); + QPalette palette = qApp->palette(); + format.setBackground(QBrush(palette.color(QPalette::Active, QPalette::Highlight))); + format.setForeground(QBrush(palette.color(QPalette::Active, QPalette::HighlightedText))); + m_preeditStyles.append(QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat, index, length, format)); + } break; - case 5: + case ZWP_TEXT_INPUT_V2_PREEDIT_STYLE_INCORRECT: format.setFontUnderline(true); format.setUnderlineStyle(QTextCharFormat::WaveUnderline); format.setUnderlineColor(QColor(Qt::red)); m_preeditStyles.append(QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat, index, length, format)); break; -// case QtWayland::wl_text_input::preedit_style_selection: -// case QtWayland::wl_text_input::preedit_style_none: default: break; } @@ -153,7 +162,7 @@ QInputMethodEvent QWaylandInputMethodEventBuilder::buildPreedit(const QString &t if (m_preeditCursor < 0) { attributes.append(QInputMethodEvent::Attribute(QInputMethodEvent::Cursor, 0, 0, QVariant())); - } else if (m_preeditCursor > 0) { + } else { attributes.append(QInputMethodEvent::Attribute(QInputMethodEvent::Cursor, indexFromWayland(text, m_preeditCursor), 1, QVariant())); } diff --git a/src/shared/qwaylandmimehelper.cpp b/src/shared/qwaylandmimehelper.cpp index a5fdd34de..c5266ab3e 100644 --- a/src/shared/qwaylandmimehelper.cpp +++ b/src/shared/qwaylandmimehelper.cpp @@ -74,7 +74,7 @@ QByteArray QWaylandMimeHelper::getByteArray(QMimeData *mimeData, const QString & QList<QUrl> urls = mimeData->urls(); for (int i = 0; i < urls.count(); ++i) { content.append(urls.at(i).toEncoded()); - content.append('\n'); + content.append("\r\n"); } } else { content = mimeData->data(mimeType); diff --git a/tests/auto/client/seatv4/tst_seatv4.cpp b/tests/auto/client/seatv4/tst_seatv4.cpp index 2e17bef87..389d5fdb4 100644 --- a/tests/auto/client/seatv4/tst_seatv4.cpp +++ b/tests/auto/client/seatv4/tst_seatv4.cpp @@ -63,6 +63,7 @@ class tst_seatv4 : public QObject, private SeatV4Compositor { Q_OBJECT private slots: + void init(); void cleanup(); void bindsToSeat(); void keyboardKeyPress(); @@ -85,6 +86,12 @@ private slots: #endif }; +void tst_seatv4::init() +{ + // Remove the extra outputs to clean up for the next test + exec([&] { while (auto *o = output(1)) remove(o); }); +} + void tst_seatv4::cleanup() { QTRY_VERIFY2(isClean(), qPrintable(dirtyMessage())); @@ -135,19 +142,19 @@ void tst_seatv4::setsCursorOnEnter() window.show(); QCOMPOSITOR_TRY_VERIFY(xdgSurface() && xdgSurface()->m_committedConfigureSerial); - exec([=] { pointer()->sendEnter(xdgSurface()->m_surface, {32, 32}); }); + exec([&] { pointer()->sendEnter(xdgSurface()->m_surface, {24, 24}); }); QCOMPOSITOR_TRY_VERIFY(cursorSurface()); } void tst_seatv4::usesEnterSerial() { - QSignalSpy setCursorSpy(exec([=] { return pointer(); }), &Pointer::setCursor); + QSignalSpy setCursorSpy(exec([&] { return pointer(); }), &Pointer::setCursor); QRasterWindow window; window.resize(64, 64); window.show(); QCOMPOSITOR_TRY_VERIFY(xdgSurface() && xdgSurface()->m_committedConfigureSerial); - uint enterSerial = exec([=] { + uint enterSerial = exec([&] { return pointer()->sendEnter(xdgSurface()->m_surface, {32, 32}); }); QCOMPOSITOR_TRY_VERIFY(cursorSurface()); @@ -158,7 +165,7 @@ void tst_seatv4::usesEnterSerial() void tst_seatv4::focusDestruction() { - QSignalSpy setCursorSpy(exec([=] { return pointer(); }), &Pointer::setCursor); + QSignalSpy setCursorSpy(exec([&] { return pointer(); }), &Pointer::setCursor); QRasterWindow window; window.resize(64, 64); window.show(); @@ -166,7 +173,7 @@ void tst_seatv4::focusDestruction() // Setting a cursor now is not allowed since there has been no enter event QCOMPARE(setCursorSpy.count(), 0); - uint enterSerial = exec([=] { + uint enterSerial = exec([&] { return pointer()->sendEnter(xdgSurface()->m_surface, {32, 32}); }); QCOMPOSITOR_TRY_VERIFY(cursorSurface()); @@ -287,8 +294,6 @@ void tst_seatv4::simpleAxis() } struct Event // Because I didn't find a convenient way to copy it entirely { - Event() = default; - const QPoint pixelDelta; const QPoint angleDelta; // eights of a degree, positive is upwards, left }; @@ -298,7 +303,7 @@ void tst_seatv4::simpleAxis() WheelWindow window; QCOMPOSITOR_TRY_VERIFY(xdgSurface() && xdgSurface()->m_committedConfigureSerial); - exec([=] { + exec([&] { Surface *surface = xdgSurface()->m_surface; pointer()->sendEnter(surface, {32, 32}); wl_client *client = surface->resource()->client(); @@ -322,7 +327,7 @@ void tst_seatv4::invalidPointerEvents() window.show(); QCOMPOSITOR_TRY_VERIFY(xdgSurface() && xdgSurface()->m_committedConfigureSerial); - exec([=] { + exec([&] { auto *p = pointer(); auto *c = client(); // Purposefully send events without a wl_pointer.enter @@ -355,14 +360,14 @@ static bool supportsCursorSizes(const QVector<uint> &sizes) { auto *waylandIntegration = static_cast<QtWaylandClient::QWaylandIntegration *>(QGuiApplicationPrivate::platformIntegration()); wl_shm *shm = waylandIntegration->display()->shm()->object(); - return std::all_of(sizes.begin(), sizes.end(), [=](uint size) { + return std::all_of(sizes.begin(), sizes.end(), [&](uint size) { return supportsCursorSize(size, shm); }); } static uint defaultCursorSize() { const int xCursorSize = qEnvironmentVariableIntValue("XCURSOR_SIZE"); - return xCursorSize > 0 ? uint(xCursorSize) : 32; + return xCursorSize > 0 ? uint(xCursorSize) : 24; } void tst_seatv4::scaledCursor() @@ -384,15 +389,15 @@ void tst_seatv4::scaledCursor() window.show(); QCOMPOSITOR_TRY_VERIFY(xdgSurface() && xdgSurface()->m_committedConfigureSerial); - exec([=] { pointer()->sendEnter(xdgSurface()->m_surface, {32, 32}); }); + exec([&] { pointer()->sendEnter(xdgSurface()->m_surface, {32, 32}); }); QCOMPOSITOR_TRY_VERIFY(cursorSurface()); QCOMPOSITOR_TRY_VERIFY(cursorSurface()->m_committed.buffer); QCOMPOSITOR_TRY_COMPARE(cursorSurface()->m_committed.bufferScale, 1); - QSize unscaledPixelSize = exec([=] { + QSize unscaledPixelSize = exec([&] { return cursorSurface()->m_committed.buffer->size(); }); - exec([=] { + exec([&] { auto *surface = cursorSurface(); surface->sendEnter(getAll<Output>()[1]); surface->sendLeave(getAll<Output>()[0]); @@ -412,7 +417,7 @@ void tst_seatv4::unscaledFallbackCursor() const int screens = 4; // with scales 1, 2, 4, 8 - exec([=] { + exec([&] { for (int i = 1; i < screens; ++i) { OutputData d; d.scale = int(qPow(2, i)); @@ -425,11 +430,11 @@ void tst_seatv4::unscaledFallbackCursor() window.resize(64, 64); window.show(); QCOMPOSITOR_TRY_VERIFY(xdgSurface() && xdgSurface()->m_committedConfigureSerial); - exec([=] { pointer()->sendEnter(xdgSurface()->m_surface, {32, 32}); }); + exec([&] { pointer()->sendEnter(xdgSurface()->m_surface, {32, 32}); }); QCOMPOSITOR_TRY_VERIFY(cursorSurface()); QCOMPOSITOR_TRY_VERIFY(cursorSurface()->m_committed.buffer); QCOMPOSITOR_TRY_COMPARE(cursorSurface()->m_committed.bufferScale, 1); - QSize unscaledPixelSize = exec([=] { + QSize unscaledPixelSize = exec([&] { return cursorSurface()->m_committed.buffer->size(); }); @@ -437,7 +442,7 @@ void tst_seatv4::unscaledFallbackCursor() QCOMPARE(unscaledPixelSize.height(), int(defaultSize)); for (int i = 1; i < screens; ++i) { - exec([=] { + exec([&] { auto *surface = cursorSurface(); surface->sendEnter(getAll<Output>()[i]); surface->sendLeave(getAll<Output>()[i-1]); @@ -475,14 +480,14 @@ void tst_seatv4::bitmapCursor() window.show(); QCOMPOSITOR_TRY_VERIFY(xdgSurface() && xdgSurface()->m_committedConfigureSerial); - exec([=] { pointer()->sendEnter(xdgSurface()->m_surface, {32, 32}); }); + exec([&] { pointer()->sendEnter(xdgSurface()->m_surface, {32, 32}); }); QCOMPOSITOR_TRY_VERIFY(cursorSurface()); QCOMPOSITOR_TRY_VERIFY(cursorSurface()->m_committed.buffer); QCOMPOSITOR_COMPARE(cursorSurface()->m_committed.buffer->size(), QSize(24, 24)); QCOMPOSITOR_COMPARE(cursorSurface()->m_committed.bufferScale, 1); QCOMPOSITOR_COMPARE(pointer()->m_hotspot, QPoint(12, 12)); - exec([=] { + exec([&] { auto *surface = cursorSurface(); surface->sendEnter(getAll<Output>()[1]); surface->sendLeave(getAll<Output>()[0]); @@ -521,14 +526,14 @@ void tst_seatv4::hidpiBitmapCursor() window.show(); QCOMPOSITOR_TRY_VERIFY(xdgSurface() && xdgSurface()->m_committedConfigureSerial); - exec([=] { pointer()->sendEnter(xdgSurface()->m_surface, {32, 32}); }); + exec([&] { pointer()->sendEnter(xdgSurface()->m_surface, {32, 32}); }); QCOMPOSITOR_TRY_VERIFY(cursorSurface()); QCOMPOSITOR_TRY_VERIFY(cursorSurface()->m_committed.buffer); QCOMPOSITOR_COMPARE(cursorSurface()->m_committed.buffer->size(), QSize(48, 48)); QCOMPOSITOR_COMPARE(cursorSurface()->m_committed.bufferScale, 2); QCOMPOSITOR_COMPARE(pointer()->m_hotspot, QPoint(12, 12)); - exec([=] { + exec([&] { auto *surface = cursorSurface(); surface->sendEnter(getAll<Output>()[1]); surface->sendLeave(getAll<Output>()[0]); @@ -558,7 +563,7 @@ void tst_seatv4::hidpiBitmapCursorNonInt() window.show(); QCOMPOSITOR_TRY_VERIFY(xdgSurface() && xdgSurface()->m_committedConfigureSerial); - exec([=] { pointer()->sendEnter(xdgSurface()->m_surface, {32, 32}); }); + exec([&] { pointer()->sendEnter(xdgSurface()->m_surface, {32, 32}); }); QCOMPOSITOR_TRY_VERIFY(cursorSurface()); QCOMPOSITOR_TRY_VERIFY(cursorSurface()->m_committed.buffer); QCOMPOSITOR_COMPARE(cursorSurface()->m_committed.buffer->size(), QSize(100, 100)); @@ -576,12 +581,12 @@ void tst_seatv4::animatedCursor() window.show(); QCOMPOSITOR_TRY_VERIFY(xdgSurface() && xdgSurface()->m_committedConfigureSerial); - exec([=] { pointer()->sendEnter(xdgSurface()->m_surface, {32, 32}); }); + exec([&] { pointer()->sendEnter(xdgSurface()->m_surface, {32, 32}); }); QCOMPOSITOR_TRY_VERIFY(cursorSurface()); // We should get the first buffer without waiting for a frame callback QCOMPOSITOR_TRY_VERIFY(cursorSurface()->m_committed.buffer); - QSignalSpy bufferSpy(exec([=] { return cursorSurface(); }), &Surface::bufferCommitted); + QSignalSpy bufferSpy(exec([&] { return cursorSurface(); }), &Surface::bufferCommitted); exec([&] { // Make sure no extra buffers have arrived diff --git a/tests/auto/client/shared/corecompositor.cpp b/tests/auto/client/shared/corecompositor.cpp index 5c6c83baa..fa9b7662a 100644 --- a/tests/auto/client/shared/corecompositor.cpp +++ b/tests/auto/client/shared/corecompositor.cpp @@ -27,6 +27,7 @@ ****************************************************************************/ #include "corecompositor.h" +#include <thread> namespace MockCompositor { diff --git a/tests/auto/client/surface/tst_surface.cpp b/tests/auto/client/surface/tst_surface.cpp index b8a65f159..60c672ce7 100644 --- a/tests/auto/client/surface/tst_surface.cpp +++ b/tests/auto/client/surface/tst_surface.cpp @@ -129,6 +129,10 @@ void tst_surface::waitForFrameCallbackGl() // Make sure we follow frame callbacks for some frames for (int i = 0; i < 5; ++i) { xdgPingAndWaitForPong(); // Make sure things have happened on the client + if (!qEnvironmentVariableIntValue("QT_WAYLAND_DISABLE_WINDOWDECORATION") && i == 0) { + QCOMPARE(bufferSpy.count(), 1); + bufferSpy.removeFirst(); + } exec([&] { QVERIFY(bufferSpy.empty()); // Make sure no extra buffers have arrived QVERIFY(!xdgToplevel()->surface()->m_waitingFrameCallbacks.empty()); @@ -167,17 +171,40 @@ void tst_surface::negotiateShmFormat() void tst_surface::createSubsurface() { QRasterWindow window; - window.resize(64, 64); - window.show(); - QCOMPOSITOR_TRY_VERIFY(xdgToplevel()); - exec([=] { xdgToplevel()->sendCompleteConfigure(); }); - QCOMPOSITOR_TRY_VERIFY(xdgSurface()->m_committedConfigureSerial); + window.setObjectName("main"); + window.resize(200, 200); QRasterWindow subWindow; + subWindow.setObjectName("subwindow"); subWindow.setParent(&window); subWindow.resize(64, 64); + + window.show(); subWindow.show(); + QCOMPOSITOR_TRY_VERIFY(subSurface()); + QCOMPOSITOR_TRY_VERIFY(xdgToplevel()); + exec([=] { xdgToplevel()->sendCompleteConfigure(); }); + QCOMPOSITOR_TRY_VERIFY(xdgSurface()->m_committedConfigureSerial); + + const Surface *mainSurface = exec([=] {return surface(0);}); + const Surface *childSurface = exec([=] {return surface(1);}); + QSignalSpy mainSurfaceCommitSpy(mainSurface, &Surface::commit); + QSignalSpy childSurfaceCommitSpy(childSurface, &Surface::commit); + + // Move subsurface. The parent should redraw and commit + subWindow.setGeometry(100, 100, 64, 64); + // the toplevel should commit to indicate the subsurface moved + QCOMPOSITOR_TRY_COMPARE(mainSurfaceCommitSpy.count(), 1); + mainSurfaceCommitSpy.clear(); + childSurfaceCommitSpy.clear(); + + // Move and resize the subSurface. The parent should redraw and commit + // The child should also redraw + subWindow.setGeometry(50, 50, 80, 80); + QCOMPOSITOR_TRY_COMPARE(mainSurfaceCommitSpy.count(), 1); + QCOMPOSITOR_TRY_COMPARE(childSurfaceCommitSpy.count(), 1); + } // Used to cause a crash in libwayland (QTBUG-79674) |