diff --git a/desktop/toolkit/qt5/qt5-wayland/files/qtbug-62044.patch b/desktop/toolkit/qt5/qt5-wayland/files/qtbug-62044.patch new file mode 100644 index 0000000000..caf3f746fd --- /dev/null +++ b/desktop/toolkit/qt5/qt5-wayland/files/qtbug-62044.patch @@ -0,0 +1,50 @@ +From fd9fec4fc7f43fb939e8e5a946c7858390bbd9d3 Mon Sep 17 00:00:00 2001 +From: Johan Klokkhammer Helsing +Date: Thu, 8 Feb 2018 16:53:39 +0100 +Subject: [PATCH] Fix crash when connecting a new screen + +In QWaylandWindow::virtualSiblings, don't include screens that have not been +added yet. I.e. QWaylandScreens for which QPlatformIntegration::screenAdded has +not yet been called. + +There are two reasons why this crash wasn't covered by the +removePrimaryScreen() test. First of all, the mock output didn't send +wl_output.done events when updating the mode/geometry. These wayland events are +what causes QWindowSystemInterface::handleScreenGeometryChange() to be called +(where virtualSiblings are called). + +Furthermore, virtualSiblings is only called when the geometry actually changes, +so add a new test that changes the screen geometry of the existing screen while +a new one is being added (i.e. moves it to the right). + +Task-number: QTBUG-62044 +Change-Id: I623fbf8799d21c6b9293e7120ded301277639cc6 +Reviewed-by: David Edmundson +Reviewed-by: Aleix Pol +Reviewed-by: Paul Olav Tvete +--- + src/client/qwaylandscreen.cpp | 6 ++++-- + tests/auto/client/client/tst_client.cpp | 25 +++++++++++++++++++++++++ + tests/auto/client/shared/mockcompositor.cpp | 8 ++++++++ + tests/auto/client/shared/mockcompositor.h | 2 ++ + tests/auto/client/shared/mockoutput.cpp | 27 +++++++++++++++++++++++++-- + tests/auto/client/shared/mockoutput.h | 1 + + 6 files changed, 65 insertions(+), 4 deletions(-) + +diff --git a/src/client/qwaylandscreen.cpp b/src/client/qwaylandscreen.cpp +index fba75557..1c9ce23b 100644 +--- a/src/client/qwaylandscreen.cpp ++++ b/src/client/qwaylandscreen.cpp +@@ -138,8 +138,10 @@ QList QWaylandScreen::virtualSiblings() const + QList list; + const QList screens = mWaylandDisplay->screens(); + list.reserve(screens.count()); +- foreach (QWaylandScreen *screen, screens) +- list << screen; ++ for (QWaylandScreen *screen : qAsConst(screens)) { ++ if (screen->screen()) ++ list << screen; ++ } + return list; + } + diff --git a/desktop/toolkit/qt5/qt5-wayland/files/qtbug-66867.patch b/desktop/toolkit/qt5/qt5-wayland/files/qtbug-66867.patch new file mode 100644 index 0000000000..bb040279b4 --- /dev/null +++ b/desktop/toolkit/qt5/qt5-wayland/files/qtbug-66867.patch @@ -0,0 +1,30 @@ +From e283cc059c83cbb4fe677beaca8aebb99156ccc5 Mon Sep 17 00:00:00 2001 +From: Antonio Larrosa +Date: Mon, 5 Mar 2018 13:56:15 +0100 +Subject: Test for null pointer before using it + +Task-number: QTBUG-66867 +Change-Id: Ibbe407fa3ac32141b52fa0086e9f1ebfd27052ba +Done-with: Fabian Vogt +Reviewed-by: Johan Helsing +Reviewed-by: Jan Grulich +--- + src/client/qwaylandwindow.cpp | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/client/qwaylandwindow.cpp b/src/client/qwaylandwindow.cpp +index ecab8ffc..7d868b30 100644 +--- a/src/client/qwaylandwindow.cpp ++++ b/src/client/qwaylandwindow.cpp +@@ -785,7 +785,7 @@ static QWaylandWindow *closestShellSurfaceWindow(QWindow *window) + { + while (window) { + auto w = static_cast(window->handle()); +- if (w->shellSurface()) ++ if (w && w->shellSurface()) + return w; + window = window->transientParent() ? window->transientParent() : window->parent(); + } +-- +cgit v1.2.1 + diff --git a/desktop/toolkit/qt5/qt5-wayland/files/qtbug-67150.patch b/desktop/toolkit/qt5/qt5-wayland/files/qtbug-67150.patch new file mode 100644 index 0000000000..3af2e0852d --- /dev/null +++ b/desktop/toolkit/qt5/qt5-wayland/files/qtbug-67150.patch @@ -0,0 +1,91 @@ +From 26a6372bb0c6528358e34f8175a14ff0be47fb12 Mon Sep 17 00:00:00 2001 +From: Johan Klokkhammer Helsing +Date: Mon, 19 Mar 2018 10:21:47 +0100 +Subject: xdg-shell v5,v6 shell integrations: Fix crash when showing popups + +If a popup was shown without any input events happening first, it would cause +nullptr dereferences in both xdg-shell v5 and v6. + +Fixes crashes in: + +- tst_QAccessibility::comboBoxTest +- tst_QAccessibility::menuTest +- tst_QWindow::touchInterruptedByPopup +- tst_QFocusEvent::checkReason_Popup + +Task-number: QTBUG-67150 +Change-Id: Ib3e06326f71e4ab5f74727cb4f79626a21c34d55 +Reviewed-by: Paul Olav Tvete +--- + src/client/qwaylandxdgshell.cpp | 3 +-- + src/client/qwaylandxdgshell_p.h | 2 +- + src/client/qwaylandxdgshellintegration.cpp | 5 +++-- + src/client/qwaylandxdgshellv6.cpp | 5 +++-- + 4 files changed, 8 insertions(+), 7 deletions(-) + +diff --git a/src/client/qwaylandxdgshell.cpp b/src/client/qwaylandxdgshell.cpp +index 8b252b95..9a34e72d 100644 +--- a/src/client/qwaylandxdgshell.cpp ++++ b/src/client/qwaylandxdgshell.cpp +@@ -73,12 +73,11 @@ QWaylandXdgSurface *QWaylandXdgShell::createXdgSurface(QWaylandWindow *window) + return new QWaylandXdgSurface(this, window); + } + +-QWaylandXdgPopup *QWaylandXdgShell::createXdgPopup(QWaylandWindow *window) ++QWaylandXdgPopup *QWaylandXdgShell::createXdgPopup(QWaylandWindow *window, QWaylandInputDevice *inputDevice) + { + QWaylandWindow *parentWindow = m_popups.empty() ? window->transientParent() : m_popups.last(); + ::wl_surface *parentSurface = parentWindow->object(); + +- QWaylandInputDevice *inputDevice = window->display()->lastInputDevice(); + if (m_popupSerial == 0) + m_popupSerial = inputDevice->serial(); + ::wl_seat *seat = inputDevice->wl_seat(); +diff --git a/src/client/qwaylandxdgshell_p.h b/src/client/qwaylandxdgshell_p.h +index afbd9c59..761f2521 100644 +--- a/src/client/qwaylandxdgshell_p.h ++++ b/src/client/qwaylandxdgshell_p.h +@@ -79,7 +79,7 @@ public: + ~QWaylandXdgShell() override; + + QWaylandXdgSurface *createXdgSurface(QWaylandWindow *window); +- QWaylandXdgPopup *createXdgPopup(QWaylandWindow *window); ++ QWaylandXdgPopup *createXdgPopup(QWaylandWindow *window, QWaylandInputDevice *inputDevice); + + private: + void xdg_shell_ping(uint32_t serial) override; +diff --git a/src/client/qwaylandxdgshellintegration.cpp b/src/client/qwaylandxdgshellintegration.cpp +index 5fa4385d..ee72c2d5 100644 +--- a/src/client/qwaylandxdgshellintegration.cpp ++++ b/src/client/qwaylandxdgshellintegration.cpp +@@ -74,8 +74,9 @@ bool QWaylandXdgShellIntegration::initialize(QWaylandDisplay *display) + + QWaylandShellSurface *QWaylandXdgShellIntegration::createShellSurface(QWaylandWindow *window) + { +- if (window->window()->type() == Qt::WindowType::Popup) +- return m_xdgShell->createXdgPopup(window); ++ QWaylandInputDevice *inputDevice = window->display()->lastInputDevice(); ++ if (window->window()->type() == Qt::WindowType::Popup && inputDevice) ++ return m_xdgShell->createXdgPopup(window, inputDevice); + else + return m_xdgShell->createXdgSurface(window); + } +diff --git a/src/client/qwaylandxdgshellv6.cpp b/src/client/qwaylandxdgshellv6.cpp +index c89c8316..a166a3bc 100644 +--- a/src/client/qwaylandxdgshellv6.cpp ++++ b/src/client/qwaylandxdgshellv6.cpp +@@ -165,8 +165,9 @@ void QWaylandXdgSurfaceV6::setAppId(const QString &appId) + + void QWaylandXdgSurfaceV6::setType(Qt::WindowType type, QWaylandWindow *transientParent) + { +- if ((type == Qt::Popup || type == Qt::ToolTip) && transientParent) { +- setPopup(transientParent, m_window->display()->lastInputDevice(), m_window->display()->lastInputSerial(), type == Qt::Popup); ++ QWaylandDisplay *display = m_window->display(); ++ if ((type == Qt::Popup || type == Qt::ToolTip) && transientParent && display->lastInputDevice()) { ++ setPopup(transientParent, display->lastInputDevice(), display->lastInputSerial(), type == Qt::Popup); + } else { + setToplevel(); + if (transientParent) { +-- +cgit v1.2.1 + diff --git a/desktop/toolkit/qt5/qt5-wayland/files/qtwayland-context-create.patch b/desktop/toolkit/qt5/qt5-wayland/files/qtwayland-context-create.patch new file mode 100644 index 0000000000..33c12a8c6d --- /dev/null +++ b/desktop/toolkit/qt5/qt5-wayland/files/qtwayland-context-create.patch @@ -0,0 +1,44 @@ +From 7ce033cbf9a80d2ea5d687956da668cf4567d361 Mon Sep 17 00:00:00 2001 +From: Johan Klokkhammer Helsing +Date: Fri, 9 Mar 2018 10:30:52 +0100 +Subject: Don't try to create compatibility GL context when profile is unset + +Context creation would sometimes fail because of this. + +Change-Id: Icf73a42ee2bb984ebfc09b7ed98f094d544134b8 +Reviewed-by: Pier Luigi Fiorini +Reviewed-by: Andy Nichols +--- + .../client/wayland-egl/qwaylandglcontext.cpp | 16 ++++++++++++---- + 1 file changed, 12 insertions(+), 4 deletions(-) + +diff --git a/src/hardwareintegration/client/wayland-egl/qwaylandglcontext.cpp b/src/hardwareintegration/client/wayland-egl/qwaylandglcontext.cpp +index 740e9641..6e48659d 100644 +--- a/src/hardwareintegration/client/wayland-egl/qwaylandglcontext.cpp ++++ b/src/hardwareintegration/client/wayland-egl/qwaylandglcontext.cpp +@@ -259,10 +259,18 @@ QWaylandGLContext::QWaylandGLContext(EGLDisplay eglDisplay, QWaylandDisplay *dis + } + // Profiles are OpenGL only and mandatory in 3.2+. The value is silently ignored for < 3.2. + if (m_format.renderableType() == QSurfaceFormat::OpenGL) { +- eglContextAttrs.append(EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR); +- eglContextAttrs.append(format.profile() == QSurfaceFormat::CoreProfile +- ? EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR +- : EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT_KHR); ++ switch (format.profile()) { ++ case QSurfaceFormat::NoProfile: ++ break; ++ case QSurfaceFormat::CoreProfile: ++ eglContextAttrs.append(EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR); ++ eglContextAttrs.append(EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR); ++ break; ++ case QSurfaceFormat::CompatibilityProfile: ++ eglContextAttrs.append(EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR); ++ eglContextAttrs.append(EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT_KHR); ++ break; ++ } + } + } + eglContextAttrs.append(EGL_NONE); +-- +cgit v1.2.1 + diff --git a/desktop/toolkit/qt5/qt5-wayland/files/qtwayland-key-compose.patch b/desktop/toolkit/qt5/qt5-wayland/files/qtwayland-key-compose.patch new file mode 100644 index 0000000000..3d57269238 --- /dev/null +++ b/desktop/toolkit/qt5/qt5-wayland/files/qtwayland-key-compose.patch @@ -0,0 +1,176 @@ +From 57c4af2b18c0fb1d266b245a107fa6cb876b9d9e Mon Sep 17 00:00:00 2001 +From: Giulio Camuffo +Date: Fri, 1 May 2015 17:12:22 +0300 +Subject: Implement basic key composition support + +Use xkbcommon-compose to handle basic compose key support. We should expand on +it in the future to handle things like resetting the compose state on text +field switching. + +Task-number: QTBUG-54792 +Task-number: QTBUG-64572 +Change-Id: I9d1d5ca4c9991928e12979f69eaa477e0cb28ada +Reviewed-by: Paul Olav Tvete +--- + src/client/qwaylandinputdevice.cpp | 65 +++++++++++++++++++++++++++++++++++++- + src/client/qwaylandinputdevice_p.h | 9 ++++++ + 2 files changed, 73 insertions(+), 1 deletion(-) + +diff --git a/src/client/qwaylandinputdevice.cpp b/src/client/qwaylandinputdevice.cpp +index f6287ba8..115d6dbc 100644 +--- a/src/client/qwaylandinputdevice.cpp ++++ b/src/client/qwaylandinputdevice.cpp +@@ -70,6 +70,10 @@ + + #include + ++#if QT_CONFIG(xkbcommon_evdev) ++#include ++#endif ++ + QT_BEGIN_NAMESPACE + + namespace QtWaylandClient { +@@ -113,6 +117,7 @@ bool QWaylandInputDevice::Keyboard::createDefaultKeyMap() + qWarning() << "xkb_map_new_from_names failed, no key input"; + return false; + } ++ createComposeState(); + return true; + } + +@@ -125,11 +130,41 @@ void QWaylandInputDevice::Keyboard::releaseKeyMap() + if (mXkbContext) + xkb_context_unref(mXkbContext); + } ++ ++void QWaylandInputDevice::Keyboard::createComposeState() ++{ ++ static const char *locale = nullptr; ++ if (!locale) { ++ locale = getenv("LC_ALL"); ++ if (!locale) ++ locale = getenv("LC_CTYPE"); ++ if (!locale) ++ locale = getenv("LANG"); ++ if (!locale) ++ locale = "C"; ++ } ++ ++ mXkbComposeTable = xkb_compose_table_new_from_locale(mXkbContext, locale, XKB_COMPOSE_COMPILE_NO_FLAGS); ++ if (mXkbComposeTable) ++ mXkbComposeState = xkb_compose_state_new(mXkbComposeTable, XKB_COMPOSE_STATE_NO_FLAGS); ++} ++ ++void QWaylandInputDevice::Keyboard::releaseComposeState() ++{ ++ if (mXkbComposeState) ++ xkb_compose_state_unref(mXkbComposeState); ++ if (mXkbComposeTable) ++ xkb_compose_table_unref(mXkbComposeTable); ++ mXkbComposeState = nullptr; ++ mXkbComposeTable = nullptr; ++} ++ + #endif + + QWaylandInputDevice::Keyboard::~Keyboard() + { + #if QT_CONFIG(xkbcommon_evdev) ++ releaseComposeState(); + releaseKeyMap(); + #endif + if (mFocus) +@@ -626,6 +661,7 @@ void QWaylandInputDevice::Keyboard::keyboard_keymap(uint32_t format, int32_t fd, + + // Release the old keymap resources in the case they were already created in + // the key event or when the compositor issues a new map ++ releaseComposeState(); + releaseKeyMap(); + + mXkbContext = xkb_context_new(xkb_context_flags(0)); +@@ -634,6 +670,8 @@ void QWaylandInputDevice::Keyboard::keyboard_keymap(uint32_t format, int32_t fd, + close(fd); + + mXkbState = xkb_state_new(mXkbMap); ++ createComposeState(); ++ + #else + Q_UNUSED(format); + Q_UNUSED(fd); +@@ -717,12 +755,37 @@ void QWaylandInputDevice::Keyboard::keyboard_key(uint32_t serial, uint32_t time, + return; + } + +- const xkb_keysym_t sym = xkb_state_key_get_one_sym(mXkbState, code); ++ QString composedText; ++ xkb_keysym_t sym = xkb_state_key_get_one_sym(mXkbState, code); ++ if (mXkbComposeState) { ++ if (isDown) ++ xkb_compose_state_feed(mXkbComposeState, sym); ++ xkb_compose_status status = xkb_compose_state_get_status(mXkbComposeState); ++ ++ switch (status) { ++ case XKB_COMPOSE_COMPOSED: { ++ int size = xkb_compose_state_get_utf8(mXkbComposeState, nullptr, 0); ++ QVarLengthArray buffer(size + 1); ++ xkb_compose_state_get_utf8(mXkbComposeState, buffer.data(), buffer.size()); ++ composedText = QString::fromUtf8(buffer.constData()); ++ sym = xkb_compose_state_get_one_sym(mXkbComposeState); ++ xkb_compose_state_reset(mXkbComposeState); ++ } break; ++ case XKB_COMPOSE_COMPOSING: ++ case XKB_COMPOSE_CANCELLED: ++ return; ++ case XKB_COMPOSE_NOTHING: ++ break; ++ } ++ } + + Qt::KeyboardModifiers modifiers = mParent->modifiers(); + + std::tie(qtkey, text) = QWaylandXkb::keysymToQtKey(sym, modifiers); + ++ if (!composedText.isNull()) ++ text = composedText; ++ + sendKey(window->window(), time, type, qtkey, modifiers, code, sym, mNativeModifiers, text); + #else + // Generic fallback for single hard keys: Assume 'key' is a Qt key code. +diff --git a/src/client/qwaylandinputdevice_p.h b/src/client/qwaylandinputdevice_p.h +index adff3f11..07d261f3 100644 +--- a/src/client/qwaylandinputdevice_p.h ++++ b/src/client/qwaylandinputdevice_p.h +@@ -77,6 +77,11 @@ + struct wl_cursor_image; + #endif + ++#if QT_CONFIG(xkbcommon_evdev) ++struct xkb_compose_state; ++struct xkb_compose_table; ++#endif ++ + QT_BEGIN_NAMESPACE + + namespace QtWaylandClient { +@@ -208,6 +213,8 @@ public: + xkb_context *mXkbContext; + xkb_keymap *mXkbMap; + xkb_state *mXkbState; ++ xkb_compose_table *mXkbComposeTable = nullptr; ++ xkb_compose_state *mXkbComposeState = nullptr; + #endif + uint32_t mNativeModifiers; + +@@ -229,6 +236,8 @@ private: + #if QT_CONFIG(xkbcommon_evdev) + bool createDefaultKeyMap(); + void releaseKeyMap(); ++ void createComposeState(); ++ void releaseComposeState(); + #endif + + }; +-- +cgit v1.2.1 + diff --git a/desktop/toolkit/qt5/qt5-wayland/pspec.xml b/desktop/toolkit/qt5/qt5-wayland/pspec.xml index 6029e9f5af..2ac26b0f02 100644 --- a/desktop/toolkit/qt5/qt5-wayland/pspec.xml +++ b/desktop/toolkit/qt5/qt5-wayland/pspec.xml @@ -30,6 +30,13 @@ wayland-client wayland-cursor + + qtbug-62044.patch + qtbug-66867.patch + qtbug-67150.patch + qtwayland-context-create.patch + qtwayland-key-compose.patch + @@ -84,7 +91,7 @@ 2018-09-03 5.10.1 - Version bump. + Version bump Mustafa Cinasal muscnsl@gmail.com