parent
424e08ab3b
commit
f217e468e9
@ -1 +1 @@
|
||||
SOURCES/qtwayland-everywhere-opensource-src-5.15.3.tar.xz
|
||||
SOURCES/qtwayland-everywhere-opensource-src-5.15.9.tar.xz
|
||||
|
@ -1 +1 @@
|
||||
021b5c6fa4f5dc4c3cc87da9a380da100a30ffdf SOURCES/qtwayland-everywhere-opensource-src-5.15.3.tar.xz
|
||||
dcaac92b52d681c9d13330e78fcd745005269fdc SOURCES/qtwayland-everywhere-opensource-src-5.15.9.tar.xz
|
||||
|
@ -1,38 +0,0 @@
|
||||
From 610af8f0ba9de42cb22228e4e4b3fd77275e3e17 Mon Sep 17 00:00:00 2001
|
||||
From: Weng Xuetian <wengxt@gmail.com>
|
||||
Date: Tue, 9 Mar 2021 10:43:59 -0800
|
||||
Subject: [PATCH 01/40] Use qWarning and _exit() instead of qFatal for wayland
|
||||
error
|
||||
|
||||
This type of error is likely to happen upon system logout. qFatal would
|
||||
trigger sigabrt and leave unnecessary coredump on the system. Using
|
||||
qWarning here would make it consistent with xcb's io error.
|
||||
|
||||
Pick-to: 5.15 6.0 6.1
|
||||
Change-Id: I571ba007bf2453486b81837cccdbefa5f181b63d
|
||||
Reviewed-by: David Edmundson <davidedmundson@kde.org>
|
||||
---
|
||||
src/client/qwaylanddisplay.cpp | 5 +++--
|
||||
1 file changed, 3 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/src/client/qwaylanddisplay.cpp b/src/client/qwaylanddisplay.cpp
|
||||
index fe094f6f..f10c1f79 100644
|
||||
--- a/src/client/qwaylanddisplay.cpp
|
||||
+++ b/src/client/qwaylanddisplay.cpp
|
||||
@@ -206,10 +206,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()
|
||||
--
|
||||
2.35.1
|
||||
|
@ -1,40 +0,0 @@
|
||||
From d353938c1a07a803656489cada8683e31f8f1c62 Mon Sep 17 00:00:00 2001
|
||||
From: Jan Grulich <jgrulich@redhat.com>
|
||||
Date: Wed, 10 Feb 2021 17:11:27 +0100
|
||||
Subject: [PATCH 02/40] Translate opaque area with frame margins
|
||||
|
||||
The opaque area doesn't take window decorations into account, which may
|
||||
result into possible graphical artefacts.
|
||||
|
||||
Pick-to: 5.15 6.0 6.1
|
||||
Change-Id: I1606e8256e7e204dad927931eb1221b576e227fd
|
||||
Reviewed-by: David Edmundson <davidedmundson@kde.org>
|
||||
---
|
||||
src/client/qwaylandwindow.cpp | 8 +++++---
|
||||
1 file changed, 5 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/src/client/qwaylandwindow.cpp b/src/client/qwaylandwindow.cpp
|
||||
index e875af3a..2af39977 100644
|
||||
--- a/src/client/qwaylandwindow.cpp
|
||||
+++ b/src/client/qwaylandwindow.cpp
|
||||
@@ -1234,12 +1234,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);
|
||||
}
|
||||
--
|
||||
2.35.1
|
||||
|
@ -1,97 +0,0 @@
|
||||
From 11e9bd41951ec9f229e20566f821aa39ca011352 Mon Sep 17 00:00:00 2001
|
||||
From: David Edmundson <davidedmundson@kde.org>
|
||||
Date: Mon, 14 Sep 2020 17:08:39 +0100
|
||||
Subject: [PATCH 03/40] Client: Send exposeEvent to parent on subsurface
|
||||
position changes
|
||||
|
||||
When a subsurface is moved, we need the parent window to commit to apply
|
||||
that move. Ideally we want this in sync with any potential rendering on
|
||||
the parent window.
|
||||
|
||||
Currently the code calls requestUpdate() which acts more like a frame
|
||||
callback; it will only do something if the main QWindow considers itself
|
||||
dirty.
|
||||
|
||||
We want to force a repaint, which is semantically more similar to an
|
||||
ExposeEvent.
|
||||
|
||||
Fixes: QTBUG-86177
|
||||
Pick-to: 5.15
|
||||
Change-Id: I30bdfa357beee860ce2b00a256eaea6d040dd55c
|
||||
Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io>
|
||||
---
|
||||
src/client/qwaylandwindow.cpp | 7 ++++-
|
||||
tests/auto/client/surface/tst_surface.cpp | 33 +++++++++++++++++++----
|
||||
2 files changed, 34 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/src/client/qwaylandwindow.cpp b/src/client/qwaylandwindow.cpp
|
||||
index 2af39977..e96d8fe9 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);
|
||||
+ }
|
||||
}
|
||||
}
|
||||
|
||||
diff --git a/tests/auto/client/surface/tst_surface.cpp b/tests/auto/client/surface/tst_surface.cpp
|
||||
index b8a65f15..95e4e609 100644
|
||||
--- a/tests/auto/client/surface/tst_surface.cpp
|
||||
+++ b/tests/auto/client/surface/tst_surface.cpp
|
||||
@@ -167,17 +167,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)
|
||||
--
|
||||
2.35.1
|
||||
|
@ -1,39 +0,0 @@
|
||||
From 50a9256db8cd43665cf74cf94a293d1c05375d33 Mon Sep 17 00:00:00 2001
|
||||
From: Jan Grulich <jgrulich@redhat.com>
|
||||
Date: Thu, 11 Feb 2021 15:12:32 +0100
|
||||
Subject: [PATCH 04/40] Get correct decoration margins region
|
||||
|
||||
Size we use to calculate margins region already contains size including
|
||||
margins. This resulted into bigger region and not properly damaging
|
||||
region we need to update.
|
||||
|
||||
Pick-to: 5.15 6.0 6.1
|
||||
Change-Id: Id1b7f4cd2a7b894b82db09c5af2b2d1f1f43fa2a
|
||||
Reviewed-by: David Edmundson <davidedmundson@kde.org>
|
||||
---
|
||||
src/client/qwaylandabstractdecoration.cpp | 8 ++++----
|
||||
1 file changed, 4 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/src/client/qwaylandabstractdecoration.cpp b/src/client/qwaylandabstractdecoration.cpp
|
||||
index 87dd6cea..b6ee43c9 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;
|
||||
}
|
||||
|
||||
--
|
||||
2.35.1
|
||||
|
@ -1,41 +0,0 @@
|
||||
From f408482e4364293e5ab9889854a759796436971d Mon Sep 17 00:00:00 2001
|
||||
From: Aleix Pol <aleixpol@kde.org>
|
||||
Date: Mon, 23 Nov 2020 20:07:02 +0100
|
||||
Subject: [PATCH 05/40] xdgshell: Tell the compositor the screen we're
|
||||
expecting to fill
|
||||
|
||||
The xdgshell protocol allows us to tell the output to fill. This makes
|
||||
it possible to use fullscreen confidently on systems with multiple
|
||||
screens knowing that our windows won't be overlapping one another by
|
||||
calling setScreen accordingly before QWindow::showFullScreen.
|
||||
|
||||
Pick-to: 6.1 6.0 5.15
|
||||
Change-Id: I757854c3698639472f3a25ef298ddcca031e1ed5
|
||||
Reviewed-by: David Edmundson <davidedmundson@kde.org>
|
||||
---
|
||||
.../shellintegration/xdg-shell/qwaylandxdgshell.cpp | 9 ++++++---
|
||||
1 file changed, 6 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp b/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp
|
||||
index 1c762944..3a1569f7 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();
|
||||
}
|
||||
|
||||
--
|
||||
2.35.1
|
||||
|
@ -1,257 +0,0 @@
|
||||
From d6dd815014564f235fb972eb72d28ccca6cf3549 Mon Sep 17 00:00:00 2001
|
||||
From: Aleix Pol <aleixpol@kde.org>
|
||||
Date: Wed, 10 Mar 2021 01:09:13 +0100
|
||||
Subject: [PATCH 06/40] client: Allow QWaylandInputContext to accept composed
|
||||
key combinations
|
||||
|
||||
At the moment, we are forcing user to choose to either compose or use
|
||||
the text-input channel. This patch brings some of the QComposeInputContext
|
||||
functionality in order to let applications understand dead key
|
||||
combinations like they are supposed to.
|
||||
|
||||
Having it in QWaylandInputContext rather than in QWaylandInputDevice
|
||||
should solve the problems 3aedd01271dc4f4a13103d632df224971ab2b6df had
|
||||
with 57c4af2b18c0fb1d266b245a107fa6cb876b9d9e, because we are doing it
|
||||
in the input context rather than before. This way, if the user is
|
||||
overriding the input method (e.g. by setting QT_IM_MODULE), all the key
|
||||
strokes will still be properly forwarded to the module to use.
|
||||
|
||||
This in turn allows us to solve https://bugs.kde.org/show_bug.cgi?id=411729
|
||||
and https://bugs.kde.org/show_bug.cgi?id=405388 since we don't need to
|
||||
choose anymore between physical and virual keyboards anymore.
|
||||
|
||||
Pick-to: 5.15
|
||||
Change-Id: I8601f5d7ae21edf4b3a1191fa75877286e505588
|
||||
Reviewed-by: David Edmundson <davidedmundson@kde.org>
|
||||
---
|
||||
src/client/qwaylanddisplay_p.h | 3 -
|
||||
src/client/qwaylandinputcontext.cpp | 95 ++++++++++++++++++++++++++++-
|
||||
src/client/qwaylandinputcontext_p.h | 21 +++++++
|
||||
src/client/qwaylandinputdevice.cpp | 2 +-
|
||||
src/client/qwaylandintegration.cpp | 8 +--
|
||||
5 files changed, 119 insertions(+), 10 deletions(-)
|
||||
|
||||
diff --git a/src/client/qwaylanddisplay_p.h b/src/client/qwaylanddisplay_p.h
|
||||
index 188e9131..3b092bc8 100644
|
||||
--- a/src/client/qwaylanddisplay_p.h
|
||||
+++ b/src/client/qwaylanddisplay_p.h
|
||||
@@ -175,8 +175,6 @@ public:
|
||||
QWaylandHardwareIntegration *hardwareIntegration() const { return mHardwareIntegration.data(); }
|
||||
QWaylandXdgOutputManagerV1 *xdgOutputManager() const { return mXdgOutputManager.data(); }
|
||||
|
||||
- bool usingInputContextFromCompositor() const { return mUsingInputContextFromCompositor; }
|
||||
-
|
||||
struct RegistryGlobal {
|
||||
uint32_t id;
|
||||
QString interface;
|
||||
@@ -282,7 +280,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 e9afe05e..ef5aa375 100644
|
||||
--- a/src/client/qwaylandinputcontext.cpp
|
||||
+++ b/src/client/qwaylandinputcontext.cpp
|
||||
@@ -406,6 +406,8 @@ bool QWaylandInputContext::isValid() const
|
||||
void QWaylandInputContext::reset()
|
||||
{
|
||||
qCDebug(qLcQpaInputMethods) << Q_FUNC_INFO;
|
||||
+ if (m_composeState)
|
||||
+ xkb_compose_state_reset(m_composeState);
|
||||
|
||||
QPlatformInputContext::reset();
|
||||
|
||||
@@ -526,9 +528,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 +568,92 @@ 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
|
||||
diff --git a/src/client/qwaylandinputcontext_p.h b/src/client/qwaylandinputcontext_p.h
|
||||
index 10132dfe..50db6344 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 ed4a0eb4..ae045f4f 100644
|
||||
--- a/src/client/qwaylandinputdevice.cpp
|
||||
+++ b/src/client/qwaylandinputdevice.cpp
|
||||
@@ -1201,7 +1201,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);
|
||||
diff --git a/src/client/qwaylandintegration.cpp b/src/client/qwaylandintegration.cpp
|
||||
index 7ad8e05e..c53ccb78 100644
|
||||
--- a/src/client/qwaylandintegration.cpp
|
||||
+++ b/src/client/qwaylandintegration.cpp
|
||||
@@ -474,13 +474,11 @@ 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();
|
||||
}
|
||||
|
||||
--
|
||||
2.35.1
|
||||
|
@ -1,31 +0,0 @@
|
||||
From 82720c9d7e0a706793f9716144347171820ddf4d Mon Sep 17 00:00:00 2001
|
||||
From: Albert Astals Cid <albert.astals.cid@kdab.com>
|
||||
Date: Mon, 10 May 2021 14:38:49 +0200
|
||||
Subject: [PATCH 09/40] Include locale.h for setlocale/LC_CTYPE
|
||||
|
||||
Pick-to: 5.15
|
||||
Change-Id: Iced32a31a63cec71008549c1e0961d59ffc45a37
|
||||
Reviewed-by: Aleix Pol Gonzalez <aleixpol@kde.org>
|
||||
(cherry picked from commit e9522eda46028f351d87311d898ab985856970b0)
|
||||
---
|
||||
src/client/qwaylandinputcontext.cpp | 4 ++++
|
||||
1 file changed, 4 insertions(+)
|
||||
|
||||
diff --git a/src/client/qwaylandinputcontext.cpp b/src/client/qwaylandinputcontext.cpp
|
||||
index ef5aa375..503fd735 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")
|
||||
--
|
||||
2.35.1
|
||||
|
@ -1,44 +0,0 @@
|
||||
From 537c5d43941d26d89ebf00f6abf7f12f9bac1caf Mon Sep 17 00:00:00 2001
|
||||
From: Aleix Pol <aleixpol@kde.org>
|
||||
Date: Tue, 13 Jul 2021 13:32:15 +0200
|
||||
Subject: [PATCH 16/40] Do not update the mask if we do not have a surface
|
||||
|
||||
mMask serves as a cache to remember what we've sent, the source of truth
|
||||
for the value is window()->mask().
|
||||
No need to store values that we are going to discard, because it will
|
||||
confuse the state of newly created windows.
|
||||
|
||||
Change-Id: I6aa3da82c7f09c7ef90d0f7060f292fb042730f0
|
||||
Pick-to: 5.15 6.2
|
||||
Reviewed-by: David Edmundson <davidedmundson@kde.org>
|
||||
(cherry picked from commit 962f87190c682562b369c5ebd93dc9ce0915ed7a)
|
||||
---
|
||||
src/client/qwaylandwindow.cpp | 7 ++++---
|
||||
1 file changed, 4 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/src/client/qwaylandwindow.cpp b/src/client/qwaylandwindow.cpp
|
||||
index e96d8fe9..bd70f4af 100644
|
||||
--- a/src/client/qwaylandwindow.cpp
|
||||
+++ b/src/client/qwaylandwindow.cpp
|
||||
@@ -464,14 +464,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);
|
||||
|
||||
--
|
||||
2.35.1
|
||||
|
@ -1,31 +0,0 @@
|
||||
From 8d673fe2edebe2c5bf338a779ef22ae212dc244a Mon Sep 17 00:00:00 2001
|
||||
From: Paul Olav Tvete <paul.tvete@qt.io>
|
||||
Date: Tue, 14 Sep 2021 11:56:23 +0200
|
||||
Subject: [PATCH 18/40] Wayland client: Fix crash when windows are shown/hidden
|
||||
during drag
|
||||
|
||||
Fixes: QTBUG-87624
|
||||
Pick-to: 6.2 5.15
|
||||
Change-Id: I1b9443df091878abcd4fbe9c55927cb819aebd59
|
||||
Reviewed-by: David Edmundson <davidedmundson@kde.org>
|
||||
(cherry picked from commit c64c5d3849b40617e1de0295f8690f354cab2b3a)
|
||||
---
|
||||
src/client/qwaylanddatadevice.cpp | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/client/qwaylanddatadevice.cpp b/src/client/qwaylanddatadevice.cpp
|
||||
index 54a69c3c..bbd2d568 100644
|
||||
--- a/src/client/qwaylanddatadevice.cpp
|
||||
+++ b/src/client/qwaylanddatadevice.cpp
|
||||
@@ -169,7 +169,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
|
||||
|
||||
--
|
||||
2.35.1
|
||||
|
@ -1,40 +0,0 @@
|
||||
From 1e0519c6465335dd380ad8d8209969c71eb78d48 Mon Sep 17 00:00:00 2001
|
||||
From: Rodney Dawes <dobey.pwns@gmail.com>
|
||||
Date: Fri, 15 Oct 2021 12:55:33 -0400
|
||||
Subject: [PATCH 21/40] Fix the logic for decoding modifiers map in Wayland
|
||||
text input protocol
|
||||
|
||||
Correctly check for the flags in the modifiers map when we get it from
|
||||
the compositor, instead of modifying the map in the for loop conditional.
|
||||
|
||||
[ChangeLog][QWaylandInputContext] Fix modifiers map decoding
|
||||
logic when receiving the map from the compositor.
|
||||
|
||||
Fixes: QTBUG-97094
|
||||
Pick-to: 6.2 5.15 5.12
|
||||
Change-Id: Idad19f7b1f4560d40abbb5b31032360cfe915261
|
||||
Reviewed-by: Paul Olav Tvete <paul.tvete@qt.io>
|
||||
---
|
||||
src/client/qwaylandinputcontext.cpp | 6 ++++--
|
||||
1 file changed, 4 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/src/client/qwaylandinputcontext.cpp b/src/client/qwaylandinputcontext.cpp
|
||||
index 503fd735..e290baa2 100644
|
||||
--- a/src/client/qwaylandinputcontext.cpp
|
||||
+++ b/src/client/qwaylandinputcontext.cpp
|
||||
@@ -387,8 +387,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;
|
||||
}
|
||||
--
|
||||
2.35.1
|
||||
|
@ -0,0 +1,59 @@
|
||||
From c6639e225f45564def8f6729c83887ab73495e59 Mon Sep 17 00:00:00 2001
|
||||
From: Paul Olav Tvete <paul.tvete@qt.io>
|
||||
Date: Tue, 15 Mar 2022 15:59:15 +0100
|
||||
Subject: [PATCH 24/55] Revert "Client: Remove mWaitingForUpdateDelivery"
|
||||
|
||||
The reverted commit introduces a severe performance regression
|
||||
when a client window is resized while a QtQuick renderthread
|
||||
animation is running.
|
||||
|
||||
This reverts commit feb1a5c207c13d0bf87c0d8ad039279dbf8cee9e.
|
||||
|
||||
Fixes: QTBUG-101726
|
||||
Change-Id: Ib5b52ce06efec8c86fada1623c2af82099e57fc6
|
||||
Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io>
|
||||
---
|
||||
src/client/qwaylandwindow.cpp | 12 +++++++++---
|
||||
src/client/qwaylandwindow_p.h | 1 +
|
||||
2 files changed, 10 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/src/client/qwaylandwindow.cpp b/src/client/qwaylandwindow.cpp
|
||||
index 69319228..a87e11aa 100644
|
||||
--- a/src/client/qwaylandwindow.cpp
|
||||
+++ b/src/client/qwaylandwindow.cpp
|
||||
@@ -658,11 +658,17 @@ void QWaylandWindow::handleFrameCallback()
|
||||
sendExposeEvent(QRect(QPoint(), geometry().size()));
|
||||
if (wasExposed && hasPendingUpdateRequest())
|
||||
deliverUpdateRequest();
|
||||
+
|
||||
+ mWaitingForUpdateDelivery = false;
|
||||
};
|
||||
|
||||
- // Queued connection, to make sure we don't call handleUpdate() from inside waitForFrameSync()
|
||||
- // in the single-threaded case.
|
||||
- QMetaObject::invokeMethod(this, doHandleExpose, Qt::QueuedConnection);
|
||||
+ if (!mWaitingForUpdateDelivery) {
|
||||
+ // Queued connection, to make sure we don't call handleUpdate() from inside waitForFrameSync()
|
||||
+ // in the single-threaded case.
|
||||
+ mWaitingForUpdateDelivery = true;
|
||||
+ QMetaObject::invokeMethod(this, doHandleExpose, Qt::QueuedConnection);
|
||||
+ }
|
||||
+
|
||||
|
||||
mFrameSyncWait.notify_all();
|
||||
}
|
||||
diff --git a/src/client/qwaylandwindow_p.h b/src/client/qwaylandwindow_p.h
|
||||
index cf7ce879..54ac67a9 100644
|
||||
--- a/src/client/qwaylandwindow_p.h
|
||||
+++ b/src/client/qwaylandwindow_p.h
|
||||
@@ -228,6 +228,7 @@ protected:
|
||||
WId mWindowId;
|
||||
bool mWaitingForFrameCallback = false;
|
||||
bool mFrameCallbackTimedOut = false; // Whether the frame callback has timed out
|
||||
+ bool mWaitingForUpdateDelivery = false;
|
||||
int mFrameCallbackCheckIntervalTimerId = -1;
|
||||
QElapsedTimer mFrameCallbackElapsedTimer;
|
||||
struct ::wl_callback *mFrameCallback = nullptr;
|
||||
--
|
||||
2.40.0
|
||||
|
@ -1,29 +0,0 @@
|
||||
From 5ea11ccde21448f5c61978bf52e2f3db79a7143c Mon Sep 17 00:00:00 2001
|
||||
From: Weng Xuetian <wengxt@gmail.com>
|
||||
Date: Sat, 18 Dec 2021 23:42:49 -0800
|
||||
Subject: [PATCH 24/40] Set preedit cursor when cursor equals to 0
|
||||
|
||||
Pick-to: 6.3 6.2 5.15
|
||||
Change-Id: I832fbb22d973b36ac4ab51570fc53bc2e4c3ed58
|
||||
Reviewed-by: Liang Qi <liang.qi@qt.io>
|
||||
(cherry picked from commit 719a55be13bdadfa659a732755f280e276a894bd)
|
||||
---
|
||||
src/shared/qwaylandinputmethodeventbuilder.cpp | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/shared/qwaylandinputmethodeventbuilder.cpp b/src/shared/qwaylandinputmethodeventbuilder.cpp
|
||||
index 526d0ef4..25be2509 100644
|
||||
--- a/src/shared/qwaylandinputmethodeventbuilder.cpp
|
||||
+++ b/src/shared/qwaylandinputmethodeventbuilder.cpp
|
||||
@@ -151,7 +151,7 @@ QInputMethodEvent QWaylandInputMethodEventBuilder::buildPreedit(const QString &t
|
||||
{
|
||||
QList<QInputMethodEvent::Attribute> attributes;
|
||||
|
||||
- if (m_preeditCursor < 0) {
|
||||
+ if (m_preeditCursor <= 0) {
|
||||
attributes.append(QInputMethodEvent::Attribute(QInputMethodEvent::Cursor, 0, 0, QVariant()));
|
||||
} else if (m_preeditCursor > 0) {
|
||||
attributes.append(QInputMethodEvent::Attribute(QInputMethodEvent::Cursor, indexFromWayland(text, m_preeditCursor), 1, QVariant()));
|
||||
--
|
||||
2.35.1
|
||||
|
@ -0,0 +1,59 @@
|
||||
From 2c403a8522db9aa6a9f365dba5f8ef5af205295c Mon Sep 17 00:00:00 2001
|
||||
From: Paul Olav Tvete <paul.tvete@qt.io>
|
||||
Date: Tue, 15 Mar 2022 16:53:04 +0100
|
||||
Subject: [PATCH 25/55] Fix race condition on mWaitingForUpdateDelivery
|
||||
|
||||
Change-Id: I0e91bda73722468b9339fc434fe04420b5e7d3da
|
||||
Reviewed-by: David Edmundson <davidedmundson@kde.org>
|
||||
---
|
||||
src/client/qwaylandwindow.cpp | 7 ++-----
|
||||
src/client/qwaylandwindow_p.h | 2 +-
|
||||
2 files changed, 3 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/src/client/qwaylandwindow.cpp b/src/client/qwaylandwindow.cpp
|
||||
index a87e11aa..264ca59b 100644
|
||||
--- a/src/client/qwaylandwindow.cpp
|
||||
+++ b/src/client/qwaylandwindow.cpp
|
||||
@@ -652,24 +652,21 @@ void QWaylandWindow::handleFrameCallback()
|
||||
|
||||
// The rest can wait until we can run it on the correct thread
|
||||
auto doHandleExpose = [this]() {
|
||||
+ mWaitingForUpdateDelivery.storeRelease(false);
|
||||
bool wasExposed = isExposed();
|
||||
mFrameCallbackTimedOut = false;
|
||||
if (!wasExposed && isExposed()) // Did setting mFrameCallbackTimedOut make the window exposed?
|
||||
sendExposeEvent(QRect(QPoint(), geometry().size()));
|
||||
if (wasExposed && hasPendingUpdateRequest())
|
||||
deliverUpdateRequest();
|
||||
-
|
||||
- mWaitingForUpdateDelivery = false;
|
||||
};
|
||||
|
||||
- if (!mWaitingForUpdateDelivery) {
|
||||
+ if (mWaitingForUpdateDelivery.testAndSetAcquire(false, true)) {
|
||||
// Queued connection, to make sure we don't call handleUpdate() from inside waitForFrameSync()
|
||||
// in the single-threaded case.
|
||||
- mWaitingForUpdateDelivery = true;
|
||||
QMetaObject::invokeMethod(this, doHandleExpose, Qt::QueuedConnection);
|
||||
}
|
||||
|
||||
-
|
||||
mFrameSyncWait.notify_all();
|
||||
}
|
||||
|
||||
diff --git a/src/client/qwaylandwindow_p.h b/src/client/qwaylandwindow_p.h
|
||||
index 54ac67a9..c0a76345 100644
|
||||
--- a/src/client/qwaylandwindow_p.h
|
||||
+++ b/src/client/qwaylandwindow_p.h
|
||||
@@ -228,7 +228,7 @@ protected:
|
||||
WId mWindowId;
|
||||
bool mWaitingForFrameCallback = false;
|
||||
bool mFrameCallbackTimedOut = false; // Whether the frame callback has timed out
|
||||
- bool mWaitingForUpdateDelivery = false;
|
||||
+ QAtomicInt mWaitingForUpdateDelivery = false;
|
||||
int mFrameCallbackCheckIntervalTimerId = -1;
|
||||
QElapsedTimer mFrameCallbackElapsedTimer;
|
||||
struct ::wl_callback *mFrameCallback = nullptr;
|
||||
--
|
||||
2.40.0
|
||||
|
@ -0,0 +1,48 @@
|
||||
From 2f0528fc51a378bdd8a3ff93d996765fccf54cce Mon Sep 17 00:00:00 2001
|
||||
From: Kenneth Topp <ken@bllue.org>
|
||||
Date: Mon, 4 Apr 2022 09:36:21 -0400
|
||||
Subject: [PATCH 26/55] use poll(2) when reading from clipboard
|
||||
|
||||
change clipboard read away from select(2) call which can fail when
|
||||
an application has large number of open files
|
||||
|
||||
Change-Id: I6d98c6bb11cdd5b6171b01cfeb0044dd41cf9fb5
|
||||
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
|
||||
(cherry picked from commit 829a9f62a96721c142f53e12a8812e8231b20317)
|
||||
---
|
||||
src/client/qwaylanddataoffer.cpp | 15 ++++++++-------
|
||||
1 file changed, 8 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/src/client/qwaylanddataoffer.cpp b/src/client/qwaylanddataoffer.cpp
|
||||
index c9e158cc..fe0ea8c9 100644
|
||||
--- a/src/client/qwaylanddataoffer.cpp
|
||||
+++ b/src/client/qwaylanddataoffer.cpp
|
||||
@@ -188,17 +188,18 @@ QVariant QWaylandMimeData::retrieveData_sys(const QString &mimeType, QVariant::T
|
||||
|
||||
int QWaylandMimeData::readData(int fd, QByteArray &data) const
|
||||
{
|
||||
- fd_set readset;
|
||||
- FD_ZERO(&readset);
|
||||
- FD_SET(fd, &readset);
|
||||
- struct timeval timeout;
|
||||
+ struct pollfd readset;
|
||||
+ readset.fd = fd;
|
||||
+ readset.events = POLLIN;
|
||||
+ struct timespec timeout;
|
||||
timeout.tv_sec = 1;
|
||||
- timeout.tv_usec = 0;
|
||||
+ timeout.tv_nsec = 0;
|
||||
+
|
||||
|
||||
Q_FOREVER {
|
||||
- int ready = select(FD_SETSIZE, &readset, nullptr, nullptr, &timeout);
|
||||
+ int ready = qt_safe_poll(&readset, 1, &timeout);
|
||||
if (ready < 0) {
|
||||
- qWarning() << "QWaylandDataOffer: select() failed";
|
||||
+ qWarning() << "QWaylandDataOffer: qt_safe_poll() failed";
|
||||
return -1;
|
||||
} else if (ready == 0) {
|
||||
qWarning("QWaylandDataOffer: timeout reading from pipe");
|
||||
--
|
||||
2.40.0
|
||||
|
@ -0,0 +1,31 @@
|
||||
From 2197557879ae1e3459e715dbc20b21e8652cb972 Mon Sep 17 00:00:00 2001
|
||||
From: Ulf Hermann <ulf.hermann@qt.io>
|
||||
Date: Tue, 22 Feb 2022 12:31:08 +0100
|
||||
Subject: [PATCH 27/55] Reduce memory leakage
|
||||
|
||||
We need to clean up the event queue when we're done.
|
||||
|
||||
Change-Id: I13a9eb77e978f4eab227a3a28dab8ebc8de94405
|
||||
Reviewed-by: David Edmundson <davidedmundson@kde.org>
|
||||
(cherry picked from commit 1264e5f565d8fb7ac200e4b00531ab876922458f)
|
||||
---
|
||||
src/client/qwaylanddisplay.cpp | 3 +++
|
||||
1 file changed, 3 insertions(+)
|
||||
|
||||
diff --git a/src/client/qwaylanddisplay.cpp b/src/client/qwaylanddisplay.cpp
|
||||
index d371ffec..1b9ec699 100644
|
||||
--- a/src/client/qwaylanddisplay.cpp
|
||||
+++ b/src/client/qwaylanddisplay.cpp
|
||||
@@ -381,6 +381,9 @@ QWaylandDisplay::~QWaylandDisplay(void)
|
||||
#endif
|
||||
if (mDisplay)
|
||||
wl_display_disconnect(mDisplay);
|
||||
+
|
||||
+ if (m_frameEventQueue)
|
||||
+ wl_event_queue_destroy(m_frameEventQueue);
|
||||
}
|
||||
|
||||
// Steps which is called just after constructor. This separates registry_global() out of the constructor
|
||||
--
|
||||
2.40.0
|
||||
|
@ -0,0 +1,32 @@
|
||||
From d9b04ba05ed479b577579e6a34d97fb906791f69 Mon Sep 17 00:00:00 2001
|
||||
From: Sam James <sam@gentoo.org>
|
||||
Date: Sat, 18 Jun 2022 17:11:11 +0100
|
||||
Subject: [PATCH 28/55] Fix build with libcxx (missing array include)
|
||||
|
||||
Bug: https://bugs.gentoo.org/833488
|
||||
|
||||
Task-number: QTBUG-104435
|
||||
Change-Id: I06384761a5560b81b675e6c4ae498bb93dcb4f4f
|
||||
Pick-to: 5.15 6.2 6.3 6.4
|
||||
Reviewed-by: Marc Mutz <marc.mutz@qt.io>
|
||||
(cherry picked from commit 5065013b0c2346b5918a2681ae2e58046140e8a7)
|
||||
---
|
||||
.../compositor/linux-dmabuf-unstable-v1/linuxdmabuf.h | 2 ++
|
||||
1 file changed, 2 insertions(+)
|
||||
|
||||
diff --git a/src/hardwareintegration/compositor/linux-dmabuf-unstable-v1/linuxdmabuf.h b/src/hardwareintegration/compositor/linux-dmabuf-unstable-v1/linuxdmabuf.h
|
||||
index 56a710c3..c6a8b6c6 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>
|
||||
|
||||
--
|
||||
2.40.0
|
||||
|
@ -0,0 +1,401 @@
|
||||
From 9265dae0d87eaf2a0dfc8a67c46f6c11bd14d2ab Mon Sep 17 00:00:00 2001
|
||||
From: Weng Xuetian <wengxt@gmail.com>
|
||||
Date: Wed, 20 Jul 2022 15:57:40 -0700
|
||||
Subject: [PATCH 29/55] Only close popup in the the hierchary
|
||||
|
||||
Imagine following event sequences:
|
||||
1. a tooltip is shown. activePopups = {tooltip}
|
||||
2. user click menu bar to show the menu, QMenu::setVisible is called.
|
||||
now activePopups(tooltip, menu}
|
||||
3. tooltip visibility changed to false.
|
||||
4. closePopups() close both tooltip and menu.
|
||||
|
||||
This is a common pattern under wayland that menu is shown as a invisible
|
||||
state. This patch tries to memorize the surface hierchary used to create
|
||||
the popup role. And only close those popups whose ancesotor is hidden.
|
||||
|
||||
Pick-to: 6.4
|
||||
Change-Id: I78aa0b4e32a5812603e003e756d8bcd202e94af4
|
||||
Reviewed-by: David Edmundson <davidedmundson@kde.org>
|
||||
(cherry picked from commit f8e3257e9b1e22d52e9c221c62b8d9b6dd1151a3)
|
||||
---
|
||||
src/client/qwaylandwindow.cpp | 33 ++++---
|
||||
src/client/qwaylandwindow_p.h | 6 ++
|
||||
.../xdg-shell-v5/qwaylandxdgpopupv5.cpp | 5 +-
|
||||
.../xdg-shell-v5/qwaylandxdgpopupv5_p.h | 3 +-
|
||||
.../xdg-shell-v5/qwaylandxdgshellv5.cpp | 2 +-
|
||||
.../xdg-shell-v6/qwaylandxdgshellv6.cpp | 3 +
|
||||
.../xdg-shell/qwaylandxdgshell.cpp | 22 +++--
|
||||
.../xdg-shell/qwaylandxdgshell_p.h | 5 +-
|
||||
tests/auto/client/xdgshell/tst_xdgshell.cpp | 87 +++++++++++++++++++
|
||||
9 files changed, 136 insertions(+), 30 deletions(-)
|
||||
|
||||
diff --git a/src/client/qwaylandwindow.cpp b/src/client/qwaylandwindow.cpp
|
||||
index 264ca59b..9e82c174 100644
|
||||
--- a/src/client/qwaylandwindow.cpp
|
||||
+++ b/src/client/qwaylandwindow.cpp
|
||||
@@ -239,6 +239,7 @@ bool QWaylandWindow::shouldCreateSubSurface() const
|
||||
|
||||
void QWaylandWindow::reset()
|
||||
{
|
||||
+ closeChildPopups();
|
||||
delete mShellSurface;
|
||||
mShellSurface = nullptr;
|
||||
delete mSubSurfaceWindow;
|
||||
@@ -397,21 +398,6 @@ void QWaylandWindow::sendExposeEvent(const QRect &rect)
|
||||
mLastExposeGeometry = rect;
|
||||
}
|
||||
|
||||
-
|
||||
-static QVector<QPointer<QWaylandWindow>> activePopups;
|
||||
-
|
||||
-void QWaylandWindow::closePopups(QWaylandWindow *parent)
|
||||
-{
|
||||
- while (!activePopups.isEmpty()) {
|
||||
- auto popup = activePopups.takeLast();
|
||||
- if (popup.isNull())
|
||||
- continue;
|
||||
- if (popup.data() == parent)
|
||||
- return;
|
||||
- popup->reset();
|
||||
- }
|
||||
-}
|
||||
-
|
||||
QPlatformScreen *QWaylandWindow::calculateScreenFromSurfaceEvents() const
|
||||
{
|
||||
QReadLocker lock(&mSurfaceLock);
|
||||
@@ -431,8 +417,6 @@ void QWaylandWindow::setVisible(bool visible)
|
||||
lastVisible = visible;
|
||||
|
||||
if (visible) {
|
||||
- if (window()->type() == Qt::Popup || window()->type() == Qt::ToolTip)
|
||||
- activePopups << this;
|
||||
initWindow();
|
||||
|
||||
setGeometry(windowGeometry());
|
||||
@@ -441,7 +425,6 @@ void QWaylandWindow::setVisible(bool visible)
|
||||
// QWaylandShmBackingStore::beginPaint().
|
||||
} else {
|
||||
sendExposeEvent(QRect());
|
||||
- closePopups(this);
|
||||
reset();
|
||||
}
|
||||
}
|
||||
@@ -1297,6 +1280,20 @@ void QWaylandWindow::setOpaqueArea(const QRegion &opaqueArea)
|
||||
wl_region_destroy(region);
|
||||
}
|
||||
|
||||
+void QWaylandWindow::addChildPopup(QWaylandWindow *surface) {
|
||||
+ mChildPopups.append(surface);
|
||||
+}
|
||||
+
|
||||
+void QWaylandWindow::removeChildPopup(QWaylandWindow *surface) {
|
||||
+ mChildPopups.removeAll(surface);
|
||||
+}
|
||||
+
|
||||
+void QWaylandWindow::closeChildPopups() {
|
||||
+ while (!mChildPopups.isEmpty()) {
|
||||
+ auto popup = mChildPopups.takeLast();
|
||||
+ popup->reset();
|
||||
+ }
|
||||
+}
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
diff --git a/src/client/qwaylandwindow_p.h b/src/client/qwaylandwindow_p.h
|
||||
index c0a76345..2be87bc0 100644
|
||||
--- a/src/client/qwaylandwindow_p.h
|
||||
+++ b/src/client/qwaylandwindow_p.h
|
||||
@@ -207,6 +207,10 @@ public:
|
||||
void handleUpdate();
|
||||
void deliverUpdateRequest() override;
|
||||
|
||||
+ void addChildPopup(QWaylandWindow* child);
|
||||
+ void removeChildPopup(QWaylandWindow* child);
|
||||
+ void closeChildPopups();
|
||||
+
|
||||
public slots:
|
||||
void applyConfigure();
|
||||
|
||||
@@ -262,6 +266,8 @@ protected:
|
||||
QWaylandBuffer *mQueuedBuffer = nullptr;
|
||||
QRegion mQueuedBufferDamage;
|
||||
|
||||
+ QList<QPointer<QWaylandWindow>> mChildPopups;
|
||||
+
|
||||
private:
|
||||
void setGeometry_helper(const QRect &rect);
|
||||
void initWindow();
|
||||
diff --git a/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgpopupv5.cpp b/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgpopupv5.cpp
|
||||
index 85d25e3c..60bdd491 100644
|
||||
--- a/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgpopupv5.cpp
|
||||
+++ b/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgpopupv5.cpp
|
||||
@@ -47,18 +47,21 @@ QT_BEGIN_NAMESPACE
|
||||
|
||||
namespace QtWaylandClient {
|
||||
|
||||
-QWaylandXdgPopupV5::QWaylandXdgPopupV5(struct ::xdg_popup_v5 *popup, QWaylandWindow *window)
|
||||
+QWaylandXdgPopupV5::QWaylandXdgPopupV5(struct ::xdg_popup_v5 *popup, QWaylandWindow* parent, QWaylandWindow *window)
|
||||
: QWaylandShellSurface(window)
|
||||
, QtWayland::xdg_popup_v5(popup)
|
||||
+ , m_parent(parent)
|
||||
, m_window(window)
|
||||
{
|
||||
if (window->display()->windowExtension())
|
||||
m_extendedWindow = new QWaylandExtendedSurface(window);
|
||||
+ m_parent->addChildPopup(m_window);
|
||||
}
|
||||
|
||||
QWaylandXdgPopupV5::~QWaylandXdgPopupV5()
|
||||
{
|
||||
xdg_popup_destroy(object());
|
||||
+ m_parent->removeChildPopup(m_window);
|
||||
delete m_extendedWindow;
|
||||
}
|
||||
|
||||
diff --git a/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgpopupv5_p.h b/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgpopupv5_p.h
|
||||
index 7494f6a6..d85f130b 100644
|
||||
--- a/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgpopupv5_p.h
|
||||
+++ b/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgpopupv5_p.h
|
||||
@@ -70,7 +70,7 @@ class Q_WAYLAND_CLIENT_EXPORT QWaylandXdgPopupV5 : public QWaylandShellSurface
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
- QWaylandXdgPopupV5(struct ::xdg_popup_v5 *popup, QWaylandWindow *window);
|
||||
+ QWaylandXdgPopupV5(struct ::xdg_popup_v5 *popup, QWaylandWindow* parent, QWaylandWindow *window);
|
||||
~QWaylandXdgPopupV5() override;
|
||||
|
||||
protected:
|
||||
@@ -78,6 +78,7 @@ protected:
|
||||
|
||||
private:
|
||||
QWaylandExtendedSurface *m_extendedWindow = nullptr;
|
||||
+ QWaylandWindow *m_parent = nullptr;
|
||||
QWaylandWindow *m_window = nullptr;
|
||||
};
|
||||
|
||||
diff --git a/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgshellv5.cpp b/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgshellv5.cpp
|
||||
index 7e242c4a..def8452a 100644
|
||||
--- a/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgshellv5.cpp
|
||||
+++ b/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgshellv5.cpp
|
||||
@@ -84,7 +84,7 @@ QWaylandXdgPopupV5 *QWaylandXdgShellV5::createXdgPopup(QWaylandWindow *window, Q
|
||||
int x = position.x() + parentWindow->frameMargins().left();
|
||||
int y = position.y() + parentWindow->frameMargins().top();
|
||||
|
||||
- auto popup = new QWaylandXdgPopupV5(get_xdg_popup(window->wlSurface(), parentSurface, seat, m_popupSerial, x, y), window);
|
||||
+ auto popup = new QWaylandXdgPopupV5(get_xdg_popup(window->wlSurface(), parentSurface, seat, m_popupSerial, x, y), parentWindow, window);
|
||||
m_popups.append(window);
|
||||
QObject::connect(popup, &QWaylandXdgPopupV5::destroyed, [this, window](){
|
||||
m_popups.removeOne(window);
|
||||
diff --git a/src/plugins/shellintegration/xdg-shell-v6/qwaylandxdgshellv6.cpp b/src/plugins/shellintegration/xdg-shell-v6/qwaylandxdgshellv6.cpp
|
||||
index 8c371661..151c78e3 100644
|
||||
--- a/src/plugins/shellintegration/xdg-shell-v6/qwaylandxdgshellv6.cpp
|
||||
+++ b/src/plugins/shellintegration/xdg-shell-v6/qwaylandxdgshellv6.cpp
|
||||
@@ -174,6 +174,7 @@ QWaylandXdgSurfaceV6::Popup::Popup(QWaylandXdgSurfaceV6 *xdgSurface, QWaylandXdg
|
||||
, m_xdgSurface(xdgSurface)
|
||||
, m_parent(parent)
|
||||
{
|
||||
+ m_parent->window()->addChildPopup(m_xdgSurface->window());
|
||||
}
|
||||
|
||||
QWaylandXdgSurfaceV6::Popup::~Popup()
|
||||
@@ -181,6 +182,8 @@ QWaylandXdgSurfaceV6::Popup::~Popup()
|
||||
if (isInitialized())
|
||||
destroy();
|
||||
|
||||
+ m_parent->window()->removeChildPopup(m_xdgSurface->window());
|
||||
+
|
||||
if (m_grabbing) {
|
||||
auto *shell = m_xdgSurface->m_shell;
|
||||
Q_ASSERT(shell->m_topmostGrabbingPopup == this);
|
||||
diff --git a/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp b/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp
|
||||
index b7383e19..962001b3 100644
|
||||
--- a/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp
|
||||
+++ b/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp
|
||||
@@ -195,12 +195,17 @@ QtWayland::xdg_toplevel::resize_edge QWaylandXdgSurface::Toplevel::convertToResi
|
||||
| ((edges & Qt::RightEdge) ? resize_edge_right : 0));
|
||||
}
|
||||
|
||||
-QWaylandXdgSurface::Popup::Popup(QWaylandXdgSurface *xdgSurface, QWaylandXdgSurface *parent,
|
||||
+QWaylandXdgSurface::Popup::Popup(QWaylandXdgSurface *xdgSurface, QWaylandWindow *parent,
|
||||
QtWayland::xdg_positioner *positioner)
|
||||
- : xdg_popup(xdgSurface->get_popup(parent->object(), positioner->object()))
|
||||
- , m_xdgSurface(xdgSurface)
|
||||
+ : m_xdgSurface(xdgSurface)
|
||||
+ , m_parentXdgSurface(qobject_cast<QWaylandXdgSurface *>(parent->shellSurface()))
|
||||
, m_parent(parent)
|
||||
{
|
||||
+
|
||||
+ init(xdgSurface->get_popup(m_parentXdgSurface ? m_parentXdgSurface->object() : nullptr, positioner->object()));
|
||||
+ if (m_parent) {
|
||||
+ m_parent->addChildPopup(m_xdgSurface->window());
|
||||
+ }
|
||||
}
|
||||
|
||||
QWaylandXdgSurface::Popup::~Popup()
|
||||
@@ -208,10 +213,14 @@ QWaylandXdgSurface::Popup::~Popup()
|
||||
if (isInitialized())
|
||||
destroy();
|
||||
|
||||
+ if (m_parent) {
|
||||
+ m_parent->removeChildPopup(m_xdgSurface->window());
|
||||
+ }
|
||||
+
|
||||
if (m_grabbing) {
|
||||
auto *shell = m_xdgSurface->m_shell;
|
||||
Q_ASSERT(shell->m_topmostGrabbingPopup == this);
|
||||
- shell->m_topmostGrabbingPopup = m_parent->m_popup;
|
||||
+ shell->m_topmostGrabbingPopup = m_parentXdgSurface ? m_parentXdgSurface->m_popup : nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -393,8 +402,6 @@ void QWaylandXdgSurface::setPopup(QWaylandWindow *parent)
|
||||
{
|
||||
Q_ASSERT(!m_toplevel && !m_popup);
|
||||
|
||||
- auto parentXdgSurface = static_cast<QWaylandXdgSurface *>(parent->shellSurface());
|
||||
-
|
||||
auto positioner = new QtWayland::xdg_positioner(m_shell->create_positioner());
|
||||
// set_popup expects a position relative to the parent
|
||||
QPoint transientPos = m_window->geometry().topLeft(); // this is absolute
|
||||
@@ -411,8 +418,9 @@ void QWaylandXdgSurface::setPopup(QWaylandWindow *parent)
|
||||
| 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);
|
||||
+ m_popup = new Popup(this, parent, positioner);
|
||||
positioner->destroy();
|
||||
+
|
||||
delete positioner;
|
||||
}
|
||||
|
||||
diff --git a/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell_p.h b/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell_p.h
|
||||
index 96785205..4b518f0a 100644
|
||||
--- a/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell_p.h
|
||||
+++ b/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell_p.h
|
||||
@@ -131,14 +131,15 @@ private:
|
||||
|
||||
class Popup : public QtWayland::xdg_popup {
|
||||
public:
|
||||
- Popup(QWaylandXdgSurface *xdgSurface, QWaylandXdgSurface *parent, QtWayland::xdg_positioner *positioner);
|
||||
+ Popup(QWaylandXdgSurface *xdgSurface, QWaylandWindow *parent, QtWayland::xdg_positioner *positioner);
|
||||
~Popup() override;
|
||||
|
||||
void grab(QWaylandInputDevice *seat, uint serial);
|
||||
void xdg_popup_popup_done() override;
|
||||
|
||||
QWaylandXdgSurface *m_xdgSurface = nullptr;
|
||||
- QWaylandXdgSurface *m_parent = nullptr;
|
||||
+ QWaylandXdgSurface *m_parentXdgSurface = nullptr;
|
||||
+ QWaylandWindow *m_parent = nullptr;
|
||||
bool m_grabbing = false;
|
||||
};
|
||||
|
||||
diff --git a/tests/auto/client/xdgshell/tst_xdgshell.cpp b/tests/auto/client/xdgshell/tst_xdgshell.cpp
|
||||
index 73d1eb9c..747875b4 100644
|
||||
--- a/tests/auto/client/xdgshell/tst_xdgshell.cpp
|
||||
+++ b/tests/auto/client/xdgshell/tst_xdgshell.cpp
|
||||
@@ -46,6 +46,7 @@ private slots:
|
||||
void configureStates();
|
||||
void popup();
|
||||
void tooltipOnPopup();
|
||||
+ void tooltipAndSiblingPopup();
|
||||
void switchPopups();
|
||||
void hidePopupParent();
|
||||
void pongs();
|
||||
@@ -346,6 +347,92 @@ void tst_xdgshell::tooltipOnPopup()
|
||||
QCOMPOSITOR_TRY_COMPARE(xdgPopup(0), nullptr);
|
||||
}
|
||||
|
||||
+void tst_xdgshell::tooltipAndSiblingPopup()
|
||||
+{
|
||||
+ class ToolTip : public QRasterWindow {
|
||||
+ public:
|
||||
+ explicit ToolTip(QWindow *parent) {
|
||||
+ setTransientParent(parent);
|
||||
+ setFlags(Qt::ToolTip);
|
||||
+ resize(100, 100);
|
||||
+ show();
|
||||
+ }
|
||||
+ void mousePressEvent(QMouseEvent *event) override {
|
||||
+ QRasterWindow::mousePressEvent(event);
|
||||
+ m_popup = new QRasterWindow;
|
||||
+ m_popup->setTransientParent(transientParent());
|
||||
+ m_popup->setFlags(Qt::Popup);
|
||||
+ m_popup->resize(100, 100);
|
||||
+ m_popup->show();
|
||||
+ }
|
||||
+
|
||||
+ QRasterWindow *m_popup = nullptr;
|
||||
+ };
|
||||
+
|
||||
+ class Window : public QRasterWindow {
|
||||
+ public:
|
||||
+ void mousePressEvent(QMouseEvent *event) override {
|
||||
+ QRasterWindow::mousePressEvent(event);
|
||||
+ m_tooltip = new ToolTip(this);
|
||||
+ }
|
||||
+ ToolTip *m_tooltip = nullptr;
|
||||
+ };
|
||||
+
|
||||
+ Window window;
|
||||
+ window.resize(200, 200);
|
||||
+ window.show();
|
||||
+
|
||||
+ QCOMPOSITOR_TRY_VERIFY(xdgToplevel());
|
||||
+ exec([=] { xdgToplevel()->sendCompleteConfigure(); });
|
||||
+ QCOMPOSITOR_TRY_VERIFY(xdgToplevel()->m_xdgSurface->m_committedConfigureSerial);
|
||||
+
|
||||
+ exec([=] {
|
||||
+ auto *surface = xdgToplevel()->surface();
|
||||
+ auto *p = pointer();
|
||||
+ auto *c = client();
|
||||
+ p->sendEnter(surface, {100, 100});
|
||||
+ p->sendFrame(c);
|
||||
+ p->sendButton(client(), BTN_LEFT, Pointer::button_state_pressed);
|
||||
+ p->sendButton(client(), BTN_LEFT, Pointer::button_state_released);
|
||||
+ p->sendFrame(c);
|
||||
+ p->sendLeave(surface);
|
||||
+ p->sendFrame(c);
|
||||
+ });
|
||||
+
|
||||
+ QCOMPOSITOR_TRY_VERIFY(xdgPopup());
|
||||
+ exec([=] { xdgPopup()->sendCompleteConfigure(QRect(100, 100, 100, 100)); });
|
||||
+ QCOMPOSITOR_TRY_VERIFY(xdgPopup()->m_xdgSurface->m_committedConfigureSerial);
|
||||
+ QCOMPOSITOR_TRY_VERIFY(!xdgPopup()->m_grabbed);
|
||||
+
|
||||
+ exec([=] {
|
||||
+ auto *surface = xdgPopup()->surface();
|
||||
+ auto *p = pointer();
|
||||
+ auto *c = client();
|
||||
+ p->sendEnter(surface, {100, 100});
|
||||
+ p->sendFrame(c);
|
||||
+ p->sendButton(client(), BTN_LEFT, Pointer::button_state_pressed);
|
||||
+ p->sendButton(client(), BTN_LEFT, Pointer::button_state_released);
|
||||
+ p->sendFrame(c);
|
||||
+ });
|
||||
+
|
||||
+ QCOMPOSITOR_TRY_VERIFY(xdgPopup(1));
|
||||
+ exec([=] { xdgPopup(1)->sendCompleteConfigure(QRect(100, 100, 100, 100)); });
|
||||
+ QCOMPOSITOR_TRY_VERIFY(xdgPopup(1)->m_xdgSurface->m_committedConfigureSerial);
|
||||
+ QCOMPOSITOR_TRY_VERIFY(xdgPopup(1)->m_grabbed);
|
||||
+
|
||||
+ // Close the middle tooltip (it should not close the sibling popup)
|
||||
+ window.m_tooltip->close();
|
||||
+
|
||||
+ QCOMPOSITOR_TRY_COMPARE(xdgPopup(1), nullptr);
|
||||
+ // Verify the remaining xdg surface is a grab popup..
|
||||
+ QCOMPOSITOR_TRY_VERIFY(xdgPopup(0));
|
||||
+ QCOMPOSITOR_TRY_VERIFY(xdgPopup(0)->m_grabbed);
|
||||
+
|
||||
+ window.m_tooltip->m_popup->close();
|
||||
+ QCOMPOSITOR_TRY_COMPARE(xdgPopup(1), nullptr);
|
||||
+ QCOMPOSITOR_TRY_COMPARE(xdgPopup(0), nullptr);
|
||||
+}
|
||||
+
|
||||
// QTBUG-65680
|
||||
void tst_xdgshell::switchPopups()
|
||||
{
|
||||
--
|
||||
2.40.0
|
||||
|
@ -0,0 +1,28 @@
|
||||
From 08ce7a21017e1f9553cd0f4af1316e38709d5553 Mon Sep 17 00:00:00 2001
|
||||
From: Ville Voutilainen <ville.voutilainen@qt.io>
|
||||
Date: Mon, 18 Jan 2021 12:31:31 +0200
|
||||
Subject: [PATCH 30/55] Build fixes for GCC 11
|
||||
|
||||
Task-number: QTBUG-89977
|
||||
Change-Id: I7e3d0964087865e8062f539f851a61f3df017dae
|
||||
Reviewed-by: David Edmundson <davidedmundson@kde.org>
|
||||
(cherry picked from commit 1aa6ec2c778504d96543f6cdc2b9199a7b066fc1)
|
||||
---
|
||||
tests/auto/client/shared/corecompositor.cpp | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/tests/auto/client/shared/corecompositor.cpp b/tests/auto/client/shared/corecompositor.cpp
|
||||
index 5c6c83ba..fa9b7662 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 {
|
||||
|
||||
--
|
||||
2.40.0
|
||||
|
@ -1,39 +0,0 @@
|
||||
From e6b30f42f8eec2ecc10395593dbfff354acd5425 Mon Sep 17 00:00:00 2001
|
||||
From: Inho Lee <inho.lee@qt.io>
|
||||
Date: Mon, 1 Nov 2021 14:23:58 +0100
|
||||
Subject: [PATCH 32/40] Do not create decorations when the shellSurface is not
|
||||
ready
|
||||
|
||||
A cases reported that client windows try to make decorations
|
||||
when their shell surfaces are null.
|
||||
Since the surfaces' requests for decorations should be applied,
|
||||
those case will be failed to create decorations.
|
||||
|
||||
This patch was modified by Paul Tvete's advice.
|
||||
(paul.tvete@qt.io)
|
||||
|
||||
Pick-to: 6.2 5.15
|
||||
Task-number: QTBUG-97608
|
||||
Change-Id: I2563dbd73b730f81cc411857af07da99ceb2d063
|
||||
Reviewed-by: Paul Olav Tvete <paul.tvete@qt.io>
|
||||
(cherry picked from commit 246f0c0bc01dd059bf8165e81f7b49efa36e4d95)
|
||||
---
|
||||
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 ac01dc05..acfe390e 100644
|
||||
--- a/src/client/qwaylandwindow.cpp
|
||||
+++ b/src/client/qwaylandwindow.cpp
|
||||
@@ -813,7 +813,7 @@ bool QWaylandWindow::createDecoration()
|
||||
decoration = false;
|
||||
if (mSubSurfaceWindow)
|
||||
decoration = false;
|
||||
- if (mShellSurface && !mShellSurface->wantsDecorations())
|
||||
+ if (!mShellSurface || !mShellSurface->wantsDecorations())
|
||||
decoration = false;
|
||||
|
||||
bool hadDecoration = mWindowDecoration;
|
||||
--
|
||||
2.35.1
|
||||
|
@ -0,0 +1,116 @@
|
||||
From bdf04e01153aeda2c2bafa059dd21dc377eb82e1 Mon Sep 17 00:00:00 2001
|
||||
From: David Edmundson <davidedmundson@kde.org>
|
||||
Date: Fri, 5 Aug 2022 15:00:31 +0100
|
||||
Subject: [PATCH 33/55] Client: clear focus on touch cancel
|
||||
|
||||
When we get a touch_cancel event all touches should be treated as
|
||||
lifted.
|
||||
|
||||
The next frame call focus is set, with no pending touch points but
|
||||
without having gone through touch_up. We call mPendingTouchPoints.last()
|
||||
without guards even though it is potentially now empty.
|
||||
|
||||
Change-Id: I3719f9507c5d397d8641692271d878076b7c23b8
|
||||
Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
|
||||
Reviewed-by: Liang Qi <liang.qi@qt.io>
|
||||
Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io>
|
||||
(cherry picked from commit dbdcd92363b44d89440dcb195d8cb9e6c34f0ddf)
|
||||
---
|
||||
src/client/qwaylandinputdevice.cpp | 1 +
|
||||
tests/auto/client/seatv5/tst_seatv5.cpp | 30 +++++++++++++++++++++++
|
||||
tests/auto/client/shared/coreprotocol.cpp | 7 ++++++
|
||||
tests/auto/client/shared/coreprotocol.h | 1 +
|
||||
4 files changed, 39 insertions(+)
|
||||
|
||||
diff --git a/src/client/qwaylandinputdevice.cpp b/src/client/qwaylandinputdevice.cpp
|
||||
index 5d704795..5b880984 100644
|
||||
--- a/src/client/qwaylandinputdevice.cpp
|
||||
+++ b/src/client/qwaylandinputdevice.cpp
|
||||
@@ -1392,6 +1392,7 @@ void QWaylandInputDevice::Touch::touch_cancel()
|
||||
if (touchExt)
|
||||
touchExt->touchCanceled();
|
||||
|
||||
+ mFocus = nullptr;
|
||||
QWindowSystemInterface::handleTouchCancelEvent(nullptr, mParent->mTouchDevice);
|
||||
}
|
||||
|
||||
diff --git a/tests/auto/client/seatv5/tst_seatv5.cpp b/tests/auto/client/seatv5/tst_seatv5.cpp
|
||||
index 9312c2e5..b063e0d9 100644
|
||||
--- a/tests/auto/client/seatv5/tst_seatv5.cpp
|
||||
+++ b/tests/auto/client/seatv5/tst_seatv5.cpp
|
||||
@@ -73,6 +73,7 @@ private slots:
|
||||
void multiTouch();
|
||||
void multiTouchUpAndMotionFrame();
|
||||
void tapAndMoveInSameFrame();
|
||||
+ void cancelTouch();
|
||||
};
|
||||
|
||||
void tst_seatv5::bindsToSeat()
|
||||
@@ -646,5 +647,34 @@ void tst_seatv5::tapAndMoveInSameFrame()
|
||||
QTRY_COMPARE(window.m_events.last().touchPoints.first().state(), Qt::TouchPointState::TouchPointReleased);
|
||||
}
|
||||
|
||||
+void tst_seatv5::cancelTouch()
|
||||
+{
|
||||
+ TouchWindow window;
|
||||
+ QCOMPOSITOR_TRY_VERIFY(xdgSurface() && xdgSurface()->m_committedConfigureSerial);
|
||||
+
|
||||
+ exec([=] {
|
||||
+ auto *t = touch();
|
||||
+ auto *c = client();
|
||||
+ t->sendDown(xdgToplevel()->surface(), {32, 32}, 1);
|
||||
+ t->sendFrame(c);
|
||||
+ t->sendCancel(c);
|
||||
+ t->sendFrame(c);
|
||||
+ });
|
||||
+
|
||||
+ QTRY_VERIFY(!window.m_events.empty());
|
||||
+ {
|
||||
+ auto e = window.m_events.takeFirst();
|
||||
+ QCOMPARE(e.type, QEvent::TouchBegin);
|
||||
+ QCOMPARE(e.touchPointStates, QEventPoint::State::Pressed);
|
||||
+ QCOMPARE(e.touchPoints.length(), 1);
|
||||
+ QCOMPARE(e.touchPoints.first().position(), QPointF(32-window.frameMargins().left(), 32-window.frameMargins().top()));
|
||||
+ }
|
||||
+ {
|
||||
+ auto e = window.m_events.takeFirst();
|
||||
+ QCOMPARE(e.type, QEvent::TouchCancel);
|
||||
+ QCOMPARE(e.touchPoints.length(), 0);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
QCOMPOSITOR_TEST_MAIN(tst_seatv5)
|
||||
#include "tst_seatv5.moc"
|
||||
diff --git a/tests/auto/client/shared/coreprotocol.cpp b/tests/auto/client/shared/coreprotocol.cpp
|
||||
index 0d988521..d1a2e7cb 100644
|
||||
--- a/tests/auto/client/shared/coreprotocol.cpp
|
||||
+++ b/tests/auto/client/shared/coreprotocol.cpp
|
||||
@@ -451,6 +451,13 @@ void Touch::sendFrame(wl_client *client)
|
||||
send_frame(r->handle);
|
||||
}
|
||||
|
||||
+void Touch::sendCancel(wl_client *client)
|
||||
+{
|
||||
+ const auto touchResources = resourceMap().values(client);
|
||||
+ for (auto *r : touchResources)
|
||||
+ send_cancel(r->handle);
|
||||
+}
|
||||
+
|
||||
uint Keyboard::sendEnter(Surface *surface)
|
||||
{
|
||||
auto serial = m_seat->m_compositor->nextSerial();
|
||||
diff --git a/tests/auto/client/shared/coreprotocol.h b/tests/auto/client/shared/coreprotocol.h
|
||||
index 296dbf47..210d8ddb 100644
|
||||
--- a/tests/auto/client/shared/coreprotocol.h
|
||||
+++ b/tests/auto/client/shared/coreprotocol.h
|
||||
@@ -364,6 +364,7 @@ public:
|
||||
uint sendUp(wl_client *client, int id);
|
||||
void sendMotion(wl_client *client, const QPointF &position, int id);
|
||||
void sendFrame(wl_client *client);
|
||||
+ void sendCancel(wl_client *client);
|
||||
|
||||
Seat *m_seat = nullptr;
|
||||
};
|
||||
--
|
||||
2.40.0
|
||||
|
@ -1,29 +0,0 @@
|
||||
From 297c4e075068bffe4a396b2553afc4798c97fb4c Mon Sep 17 00:00:00 2001
|
||||
From: Joni Poikelin <joni.poikelin@qt.io>
|
||||
Date: Thu, 3 Feb 2022 14:01:50 +0200
|
||||
Subject: [PATCH 34/40] Fix crash if no input method module could be loaded
|
||||
|
||||
Pick-to: 6.2 6.3 5.15
|
||||
Change-Id: I8f346def616606a6c5540856bd08a84ee7ed5ca2
|
||||
Reviewed-by: David Edmundson <davidedmundson@kde.org>
|
||||
(cherry picked from commit 49fb7248f6ab7de046e2179c7861951ea1169e9b)
|
||||
---
|
||||
src/client/qwaylandintegration.cpp | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/client/qwaylandintegration.cpp b/src/client/qwaylandintegration.cpp
|
||||
index 3b876047..fbf00c6b 100644
|
||||
--- a/src/client/qwaylandintegration.cpp
|
||||
+++ b/src/client/qwaylandintegration.cpp
|
||||
@@ -491,7 +491,7 @@ void QWaylandIntegration::reconfigureInputContext()
|
||||
}
|
||||
#endif
|
||||
|
||||
- qCDebug(lcQpaWayland) << "using input method:" << inputContext()->metaObject()->className();
|
||||
+ qCDebug(lcQpaWayland) << "using input method:" << (inputContext() ? inputContext()->metaObject()->className() : "<none>");
|
||||
}
|
||||
|
||||
QWaylandShellIntegration *QWaylandIntegration::createShellIntegration(const QString &integrationName)
|
||||
--
|
||||
2.35.1
|
||||
|
@ -0,0 +1,39 @@
|
||||
From e920173ee9cef08d10ad8a7e21ae7a5a2c2d7530 Mon Sep 17 00:00:00 2001
|
||||
From: David Edmundson <davidedmundson@kde.org>
|
||||
Date: Thu, 3 Feb 2022 19:42:33 +0000
|
||||
Subject: [PATCH 34/55] Guard mResizeDirty by the correctMutex
|
||||
|
||||
mResizeDirty is used in the GUI thread in setCanResize which can be
|
||||
called from the GUI thread. It is queried and set whilst the resizeLock
|
||||
is held. We need to guard our usage.
|
||||
|
||||
Change-Id: I5f8dcf8aa2cb2c4bb6274103df1da9e3e268605a
|
||||
Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io>
|
||||
(cherry picked from commit 4ac96662c936821efff2875bbe555b40612caf8a)
|
||||
---
|
||||
src/client/qwaylandwindow.cpp | 7 ++++---
|
||||
1 file changed, 4 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/src/client/qwaylandwindow.cpp b/src/client/qwaylandwindow.cpp
|
||||
index 5b7f9df9..117e3383 100644
|
||||
--- a/src/client/qwaylandwindow.cpp
|
||||
+++ b/src/client/qwaylandwindow.cpp
|
||||
@@ -358,11 +358,12 @@ void QWaylandWindow::setGeometry(const QRect &rect)
|
||||
if (mWindowDecoration)
|
||||
mWindowDecoration->update();
|
||||
|
||||
- if (mResizeAfterSwap && windowType() == Egl && mSentInitialResize)
|
||||
+ if (mResizeAfterSwap && windowType() == Egl && mSentInitialResize) {
|
||||
+ QMutexLocker lock(&mResizeLock);
|
||||
mResizeDirty = true;
|
||||
- else
|
||||
+ } else {
|
||||
QWindowSystemInterface::handleGeometryChange(window(), geometry());
|
||||
-
|
||||
+ }
|
||||
mSentInitialResize = true;
|
||||
}
|
||||
QRect exposeGeometry(QPoint(), geometry().size());
|
||||
--
|
||||
2.40.0
|
||||
|
@ -0,0 +1,72 @@
|
||||
From 1ff4219d8c58f8356d9d12824948013cdfde6ac5 Mon Sep 17 00:00:00 2001
|
||||
From: Liang Qi <liang.qi@qt.io>
|
||||
Date: Fri, 11 Mar 2022 09:17:25 +0100
|
||||
Subject: [PATCH 35/55] client: Synthesize enter/leave event for popup in
|
||||
xdg-shell
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Fixes: QTBUG-100148
|
||||
Pick-to: 6.3 6.2 5.15
|
||||
Change-Id: I45e3156d7942cff9968674c0b253d15be7235921
|
||||
Reviewed-by: Tang Haixiang <tanghaixiang@uniontech.com>
|
||||
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
|
||||
Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
|
||||
(cherry picked from commit 73d35d3117722cef8e94f0d2036c56ad0a5ddae9)
|
||||
|
||||
* asturmlechner 2022-09-08: Resolve conflict with dev branch commits
|
||||
b6a3a938abd4a7fdb7ea96a38485b53f394fba17 and
|
||||
f8e3257e9b1e22d52e9c221c62b8d9b6dd1151a3
|
||||
---
|
||||
.../xdg-shell/qwaylandxdgshell.cpp | 27 +++++++++++++++++++
|
||||
1 file changed, 27 insertions(+)
|
||||
|
||||
diff --git a/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp b/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp
|
||||
index 962001b3..ead99989 100644
|
||||
--- a/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp
|
||||
+++ b/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp
|
||||
@@ -221,6 +221,16 @@ QWaylandXdgSurface::Popup::~Popup()
|
||||
auto *shell = m_xdgSurface->m_shell;
|
||||
Q_ASSERT(shell->m_topmostGrabbingPopup == this);
|
||||
shell->m_topmostGrabbingPopup = m_parentXdgSurface ? m_parentXdgSurface->m_popup : nullptr;
|
||||
+ 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());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -442,6 +452,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)
|
||||
--
|
||||
2.40.0
|
||||
|
@ -1,35 +0,0 @@
|
||||
From d3b794920d643fc5d722f63ad52b91e8143c0de0 Mon Sep 17 00:00:00 2001
|
||||
From: Weng Xuetian <wengxt@gmail.com>
|
||||
Date: Tue, 8 Feb 2022 07:11:25 -0800
|
||||
Subject: [PATCH 36/40] Cursor position == 0 should still show the cursor
|
||||
|
||||
Otherwise the cursor would be hidden even if preedit is empty.
|
||||
Amends 719a55be13bdadfa659a732755f280e276a894bd
|
||||
|
||||
Pick-to: 5.15 6.2 6.3
|
||||
Change-Id: I320733b917779b7b51aa4a28eaea411fdb10a318
|
||||
Reviewed-by: Liang Qi <liang.qi@qt.io>
|
||||
(cherry picked from commit 31ae194e295651d9ece03408630d2358acd4f7b4)
|
||||
---
|
||||
src/shared/qwaylandinputmethodeventbuilder.cpp | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/src/shared/qwaylandinputmethodeventbuilder.cpp b/src/shared/qwaylandinputmethodeventbuilder.cpp
|
||||
index 25be2509..458d818e 100644
|
||||
--- a/src/shared/qwaylandinputmethodeventbuilder.cpp
|
||||
+++ b/src/shared/qwaylandinputmethodeventbuilder.cpp
|
||||
@@ -151,9 +151,9 @@ QInputMethodEvent QWaylandInputMethodEventBuilder::buildPreedit(const QString &t
|
||||
{
|
||||
QList<QInputMethodEvent::Attribute> attributes;
|
||||
|
||||
- if (m_preeditCursor <= 0) {
|
||||
+ 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()));
|
||||
}
|
||||
|
||||
--
|
||||
2.35.1
|
||||
|
@ -0,0 +1,29 @@
|
||||
From bf6b509011c4086cc7b1a7cfdc78dd50e446b15f Mon Sep 17 00:00:00 2001
|
||||
From: Albert Astals Cid <aacid@kde.org>
|
||||
Date: Fri, 9 Sep 2022 15:37:49 +0200
|
||||
Subject: [PATCH 36/55] Fix compile tests
|
||||
|
||||
Broken in c618467da4c06528537026e2b78f92265bce446f
|
||||
---
|
||||
tests/auto/client/seatv5/tst_seatv5.cpp | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/tests/auto/client/seatv5/tst_seatv5.cpp b/tests/auto/client/seatv5/tst_seatv5.cpp
|
||||
index b063e0d9..2ea382f1 100644
|
||||
--- a/tests/auto/client/seatv5/tst_seatv5.cpp
|
||||
+++ b/tests/auto/client/seatv5/tst_seatv5.cpp
|
||||
@@ -665,9 +665,9 @@ void tst_seatv5::cancelTouch()
|
||||
{
|
||||
auto e = window.m_events.takeFirst();
|
||||
QCOMPARE(e.type, QEvent::TouchBegin);
|
||||
- QCOMPARE(e.touchPointStates, QEventPoint::State::Pressed);
|
||||
+ QCOMPARE(e.touchPointStates, Qt::TouchPointPressed);
|
||||
QCOMPARE(e.touchPoints.length(), 1);
|
||||
- QCOMPARE(e.touchPoints.first().position(), QPointF(32-window.frameMargins().left(), 32-window.frameMargins().top()));
|
||||
+ QCOMPARE(e.touchPoints.first().pos(), QPointF(32-window.frameMargins().left(), 32-window.frameMargins().top()));
|
||||
}
|
||||
{
|
||||
auto e = window.m_events.takeFirst();
|
||||
--
|
||||
2.40.0
|
||||
|
@ -1,88 +0,0 @@
|
||||
From 3ddd4dcb1790920ce2598ebdbe14c95bdba55005 Mon Sep 17 00:00:00 2001
|
||||
From: Weng Xuetian <wengxt@gmail.com>
|
||||
Date: Wed, 22 Dec 2021 10:42:38 -0800
|
||||
Subject: [PATCH 37/40] Update the preedit styling mapping
|
||||
|
||||
- None mapping to no style.
|
||||
- Default/Underline mapping to underline.
|
||||
- Highlight/Selection mapping to background color/text color with highlight/highlight
|
||||
text with underline.
|
||||
- Active/Inactive mapping to bold text with underline.
|
||||
- Incorrect mapping to red wave underline.
|
||||
|
||||
Pick-to: 5.15 6.2 6.3
|
||||
Change-Id: Iab51d671b8f83aece8596f7f7610de19343fcceb
|
||||
Reviewed-by: Aleix Pol Gonzalez <aleixpol@kde.org>
|
||||
(cherry picked from commit f1fb5d9e568a24e213ee41e82a1142cef56f1098)
|
||||
---
|
||||
.../qwaylandinputmethodeventbuilder.cpp | 31 ++++++++++++-------
|
||||
1 file changed, 20 insertions(+), 11 deletions(-)
|
||||
|
||||
diff --git a/src/shared/qwaylandinputmethodeventbuilder.cpp b/src/shared/qwaylandinputmethodeventbuilder.cpp
|
||||
index 458d818e..f50ccf30 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;
|
||||
}
|
||||
--
|
||||
2.35.1
|
||||
|
@ -0,0 +1,40 @@
|
||||
From 137958eec28cb8209069f9a3a3ab778202773ff6 Mon Sep 17 00:00:00 2001
|
||||
From: Alexandros Frantzis <alexandros.frantzis@collabora.com>
|
||||
Date: Wed, 11 May 2022 17:12:52 +0300
|
||||
Subject: [PATCH 37/55] Use CRLF line delimiter for text/uri-list data
|
||||
|
||||
According to RFC 2483, which describes text/uri-list, the line delimiter
|
||||
must be CRLF (instead of the currently used LF). Some applications
|
||||
strictly expect the CRLF delimiter and fail to properly parse the
|
||||
uri-list otherwise (e.g., WineX11/XWayland).
|
||||
|
||||
https://datatracker.ietf.org/doc/html/rfc2483
|
||||
|
||||
5. The text/uri-list Internet Media Type
|
||||
The format of text/uri-list resources is:
|
||||
3) As for all text/* formats, lines are terminated with a CRLF pair.
|
||||
|
||||
Pick-to: 6.4 6.3 6.2 5.15
|
||||
Change-Id: I7c062224a9060028ab6293fdf172692ade28cca5
|
||||
Reviewed-by: David Edmundson <davidedmundson@kde.org>
|
||||
(cherry picked from commit bd5b0a804b91b9fbd0ce44d5d6765e07d0a50b4f)
|
||||
---
|
||||
src/shared/qwaylandmimehelper.cpp | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/shared/qwaylandmimehelper.cpp b/src/shared/qwaylandmimehelper.cpp
|
||||
index 051a91dc..e2fe1928 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);
|
||||
--
|
||||
2.40.0
|
||||
|
@ -0,0 +1,43 @@
|
||||
From 0064749af275016ae3b4b09964d8d31d756d3468 Mon Sep 17 00:00:00 2001
|
||||
From: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io>
|
||||
Date: Mon, 8 Aug 2022 12:14:01 +0200
|
||||
Subject: [PATCH 38/55] Avoid calling requestUpdate from wrong thread
|
||||
|
||||
In certain circumstances, we can get to createDecoration()
|
||||
from the render thread (from QWaylandGLContext::makeCurrent)
|
||||
|
||||
Calling requestUpdate() from this secondary thread would
|
||||
cause an assert, so we queue the call on the appropriate
|
||||
thread instead.
|
||||
|
||||
This amends af7b60ade5c4be81cbc58eb18307c017d5594071.
|
||||
|
||||
Pick-to: 5.15 6.2 6.3 6.3.2 6.4
|
||||
Fixes: QTBUG-105308
|
||||
Change-Id: I4805265f39e24eb1464897532be2025bc3c27728
|
||||
Reviewed-by: Inho Lee <inho.lee@qt.io>
|
||||
(cherry picked from commit a0c0b5b42335808c2222cbf72c1758e955731ed9)
|
||||
---
|
||||
src/client/qwaylandwindow.cpp | 6 +++++-
|
||||
1 file changed, 5 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/client/qwaylandwindow.cpp b/src/client/qwaylandwindow.cpp
|
||||
index 117e3383..4ddf9fbe 100644
|
||||
--- a/src/client/qwaylandwindow.cpp
|
||||
+++ b/src/client/qwaylandwindow.cpp
|
||||
@@ -873,7 +873,11 @@ bool QWaylandWindow::createDecoration()
|
||||
// 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.
|
||||
- window()->requestUpdate();
|
||||
+ // 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;
|
||||
--
|
||||
2.40.0
|
||||
|
@ -0,0 +1,38 @@
|
||||
From 35c03e72007630040659188b2bc7f47b1df82577 Mon Sep 17 00:00:00 2001
|
||||
From: Fushan Wen <qydwhotmail@gmail.com>
|
||||
Date: Sun, 18 Sep 2022 18:17:18 +0800
|
||||
Subject: [PATCH 39/55] Call `finishDrag()` in
|
||||
`QWaylandDataDevice::dragSourceCancelled()`
|
||||
|
||||
Drags can either get finished or cancelled. If a drag is finished
|
||||
successfully we call finish on the QBasicDrag instance, which quits
|
||||
the nested event loop. This patch adds the connection for cancelled
|
||||
drags.
|
||||
|
||||
See also: https://bugs.kde.org/show_bug.cgi?id=446111
|
||||
|
||||
Pick-to: 6.4 6.2 5.15
|
||||
Change-Id: Ib93040648da88a433d647c87adcb7a7fabcaef6c
|
||||
Reviewed-by: Liang Qi <liang.qi@qt.io>
|
||||
(cherry picked from commit c92282b865efcf8c571bb52b5f96d8ad260a1cda)
|
||||
|
||||
BUG: 446111
|
||||
---
|
||||
src/client/qwaylanddatadevice.cpp | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/src/client/qwaylanddatadevice.cpp b/src/client/qwaylanddatadevice.cpp
|
||||
index fbb5aa91..e3e60ed5 100644
|
||||
--- a/src/client/qwaylanddatadevice.cpp
|
||||
+++ b/src/client/qwaylanddatadevice.cpp
|
||||
@@ -296,6 +296,7 @@ void QWaylandDataDevice::selectionSourceCancelled()
|
||||
#if QT_CONFIG(draganddrop)
|
||||
void QWaylandDataDevice::dragSourceCancelled()
|
||||
{
|
||||
+ static_cast<QWaylandDrag *>(QGuiApplicationPrivate::platformIntegration()->drag())->finishDrag();
|
||||
m_dragSource.reset();
|
||||
}
|
||||
|
||||
--
|
||||
2.40.0
|
||||
|
@ -0,0 +1,85 @@
|
||||
From 37ad4aeaa6dce748f5f6bcc5030be187e6320ec0 Mon Sep 17 00:00:00 2001
|
||||
From: David Edmundson <davidedmundson@kde.org>
|
||||
Date: Mon, 12 Sep 2022 13:28:08 +0100
|
||||
Subject: [PATCH 40/55] Hold surface read lock throughout
|
||||
QWaylandEglWindow::updateSurface
|
||||
|
||||
QWaylandEGLWindow::updateSurface is called from both the main and render
|
||||
threads. It is called on the render thread when making the surface
|
||||
current, which could be after the window is hidden if there are cleanup
|
||||
jobs to be done.
|
||||
|
||||
Whilst the getter wlSurface() holds a read lock, it's not enough as we
|
||||
need the instance alive between the two calls and throughout the mesa
|
||||
code.
|
||||
|
||||
This potentially fixes a crash seen in mesa where we crash creating a
|
||||
surface for an invalid wl_surface object.
|
||||
|
||||
Change-Id: I497356e752ffaf3549d174f10c4c268234b02cbd
|
||||
Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io>
|
||||
(cherry picked from commit 50f1ccc66c68f9f4c0b08400747942109c16b2be)
|
||||
---
|
||||
src/client/qwaylandwindow_p.h | 6 ++++--
|
||||
.../client/wayland-egl/qwaylandeglwindow.cpp | 6 ++++--
|
||||
2 files changed, 8 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/src/client/qwaylandwindow_p.h b/src/client/qwaylandwindow_p.h
|
||||
index 2be87bc0..ea3d1995 100644
|
||||
--- a/src/client/qwaylandwindow_p.h
|
||||
+++ b/src/client/qwaylandwindow_p.h
|
||||
@@ -220,7 +220,11 @@ signals:
|
||||
|
||||
protected:
|
||||
QWaylandDisplay *mDisplay = nullptr;
|
||||
+
|
||||
+ // mSurface can be written by the main thread. Other threads should claim a read lock for access
|
||||
+ mutable QReadWriteLock mSurfaceLock;
|
||||
QScopedPointer<QWaylandSurface> mSurface;
|
||||
+
|
||||
QWaylandShellSurface *mShellSurface = nullptr;
|
||||
QWaylandSubSurface *mSubSurfaceWindow = nullptr;
|
||||
QVector<QWaylandSubSurface *> mChildren;
|
||||
@@ -294,8 +298,6 @@ private:
|
||||
|
||||
static QWaylandWindow *mMouseGrab;
|
||||
|
||||
- mutable QReadWriteLock mSurfaceLock;
|
||||
-
|
||||
friend class QWaylandSubSurface;
|
||||
};
|
||||
|
||||
diff --git a/src/hardwareintegration/client/wayland-egl/qwaylandeglwindow.cpp b/src/hardwareintegration/client/wayland-egl/qwaylandeglwindow.cpp
|
||||
index 13dd747a..872a6237 100644
|
||||
--- a/src/hardwareintegration/client/wayland-egl/qwaylandeglwindow.cpp
|
||||
+++ b/src/hardwareintegration/client/wayland-egl/qwaylandeglwindow.cpp
|
||||
@@ -40,6 +40,7 @@
|
||||
#include "qwaylandeglwindow.h"
|
||||
|
||||
#include <QtWaylandClient/private/qwaylandscreen_p.h>
|
||||
+#include <QtWaylandClient/private/qwaylandsurface_p.h>
|
||||
#include "qwaylandglcontext.h"
|
||||
|
||||
#include <QtEglSupport/private/qeglconvenience_p.h>
|
||||
@@ -115,6 +116,7 @@ void QWaylandEglWindow::updateSurface(bool create)
|
||||
}
|
||||
mOffset = QPoint();
|
||||
} else {
|
||||
+ QReadLocker locker(&mSurfaceLock);
|
||||
if (m_waylandEglWindow) {
|
||||
int current_width, current_height;
|
||||
static bool disableResizeCheck = qgetenv("QT_WAYLAND_DISABLE_RESIZECHECK").toInt();
|
||||
@@ -129,8 +131,8 @@ void QWaylandEglWindow::updateSurface(bool create)
|
||||
|
||||
m_resize = true;
|
||||
}
|
||||
- } else if (create && wlSurface()) {
|
||||
- m_waylandEglWindow = wl_egl_window_create(wlSurface(), sizeWithMargins.width(), sizeWithMargins.height());
|
||||
+ } else if (create && mSurface) {
|
||||
+ m_waylandEglWindow = wl_egl_window_create(mSurface->object(), sizeWithMargins.width(), sizeWithMargins.height());
|
||||
m_requestedSize = sizeWithMargins;
|
||||
}
|
||||
|
||||
--
|
||||
2.40.0
|
||||
|
@ -0,0 +1,109 @@
|
||||
From 1012f1d4b5753ad63da3cca1226fb034e297ae6d Mon Sep 17 00:00:00 2001
|
||||
From: Vlad Zahorodnii <vlad.zahorodnii@kde.org>
|
||||
Date: Tue, 8 Nov 2022 16:10:18 +0200
|
||||
Subject: [PATCH 41/55] Client: Ensure that wl_surface lives as long as qtquick
|
||||
render thread needs it
|
||||
|
||||
wl_surface can be destroyed while qtquick render thread still uses it.
|
||||
That can end up in eglSwapBuffers() using defunct wl_surface, which will
|
||||
eventually lead to a crash due to the compositor posting an error.
|
||||
|
||||
This is partially cherry-pick of dff579147b07cd15888a47c303e36684e9930f9f
|
||||
|
||||
Change-Id: I044f40dd64e6672027a833379b57ccd9973d8305
|
||||
---
|
||||
src/client/qwaylandwindow.cpp | 13 ++++++++++++-
|
||||
src/client/qwaylandwindow_p.h | 3 +++
|
||||
.../client/wayland-egl/qwaylandglcontext.cpp | 6 +++++-
|
||||
3 files changed, 20 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/src/client/qwaylandwindow.cpp b/src/client/qwaylandwindow.cpp
|
||||
index 4ddf9fbe..1f2d56b5 100644
|
||||
--- a/src/client/qwaylandwindow.cpp
|
||||
+++ b/src/client/qwaylandwindow.cpp
|
||||
@@ -76,6 +76,7 @@ QWaylandWindow *QWaylandWindow::mMouseGrab = nullptr;
|
||||
QWaylandWindow::QWaylandWindow(QWindow *window, QWaylandDisplay *display)
|
||||
: QPlatformWindow(window)
|
||||
, mDisplay(display)
|
||||
+ , mSurfaceLock(QReadWriteLock::Recursive)
|
||||
, mResizeAfterSwap(qEnvironmentVariableIsSet("QT_WAYLAND_RESIZE_AFTER_SWAP"))
|
||||
{
|
||||
{
|
||||
@@ -237,6 +238,16 @@ bool QWaylandWindow::shouldCreateSubSurface() const
|
||||
return QPlatformWindow::parent() != nullptr;
|
||||
}
|
||||
|
||||
+void QWaylandWindow::beginFrame()
|
||||
+{
|
||||
+ mSurfaceLock.lockForRead();
|
||||
+}
|
||||
+
|
||||
+void QWaylandWindow::endFrame()
|
||||
+{
|
||||
+ mSurfaceLock.unlock();
|
||||
+}
|
||||
+
|
||||
void QWaylandWindow::reset()
|
||||
{
|
||||
closeChildPopups();
|
||||
@@ -245,10 +256,10 @@ void QWaylandWindow::reset()
|
||||
delete mSubSurfaceWindow;
|
||||
mSubSurfaceWindow = nullptr;
|
||||
|
||||
- invalidateSurface();
|
||||
if (mSurface) {
|
||||
emit wlSurfaceDestroyed();
|
||||
QWriteLocker lock(&mSurfaceLock);
|
||||
+ invalidateSurface();
|
||||
mSurface.reset();
|
||||
}
|
||||
|
||||
diff --git a/src/client/qwaylandwindow_p.h b/src/client/qwaylandwindow_p.h
|
||||
index ea3d1995..e18609d9 100644
|
||||
--- a/src/client/qwaylandwindow_p.h
|
||||
+++ b/src/client/qwaylandwindow_p.h
|
||||
@@ -207,6 +207,9 @@ public:
|
||||
void handleUpdate();
|
||||
void deliverUpdateRequest() override;
|
||||
|
||||
+ void beginFrame();
|
||||
+ void endFrame();
|
||||
+
|
||||
void addChildPopup(QWaylandWindow* child);
|
||||
void removeChildPopup(QWaylandWindow* child);
|
||||
void closeChildPopups();
|
||||
diff --git a/src/hardwareintegration/client/wayland-egl/qwaylandglcontext.cpp b/src/hardwareintegration/client/wayland-egl/qwaylandglcontext.cpp
|
||||
index c1f45fa6..5d6fb2bf 100644
|
||||
--- a/src/hardwareintegration/client/wayland-egl/qwaylandglcontext.cpp
|
||||
+++ b/src/hardwareintegration/client/wayland-egl/qwaylandglcontext.cpp
|
||||
@@ -432,8 +432,10 @@ bool QWaylandGLContext::makeCurrent(QPlatformSurface *surface)
|
||||
return true;
|
||||
}
|
||||
|
||||
- if (window->isExposed())
|
||||
+ if (window->isExposed()) {
|
||||
+ window->beginFrame();
|
||||
window->setCanResize(false);
|
||||
+ }
|
||||
if (m_decorationsContext != EGL_NO_CONTEXT && !window->decoration())
|
||||
window->createDecoration();
|
||||
|
||||
@@ -449,6 +451,7 @@ bool QWaylandGLContext::makeCurrent(QPlatformSurface *surface)
|
||||
if (!eglMakeCurrent(m_eglDisplay, eglSurface, eglSurface, m_context)) {
|
||||
qWarning("QWaylandGLContext::makeCurrent: eglError: %x, this: %p \n", eglGetError(), this);
|
||||
window->setCanResize(true);
|
||||
+ window->endFrame();
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -502,6 +505,7 @@ void QWaylandGLContext::swapBuffers(QPlatformSurface *surface)
|
||||
eglSwapBuffers(m_eglDisplay, eglSurface);
|
||||
|
||||
window->setCanResize(true);
|
||||
+ window->endFrame();
|
||||
}
|
||||
|
||||
GLuint QWaylandGLContext::defaultFramebufferObject(QPlatformSurface *surface) const
|
||||
--
|
||||
2.40.0
|
||||
|
@ -1,33 +0,0 @@
|
||||
From 48b9dbb4d9d508895f7568531d8f0a7e63261b75 Mon Sep 17 00:00:00 2001
|
||||
From: Liang Qi <liang.qi@qt.io>
|
||||
Date: Tue, 4 Jan 2022 12:30:36 +0100
|
||||
Subject: [PATCH] client: set_constraint_adjustment() for popups in xdg
|
||||
|
||||
See also https://cgit.freedesktop.org/wayland/wayland-protocols/tree/stable/xdg-shell/xdg-shell.xml#n234 .
|
||||
|
||||
Kudos to Greg V for his original patch in jira.
|
||||
|
||||
Fixes: QTBUG-87303
|
||||
Pick-to: 5.15 6.2 6.3
|
||||
Done-with: Greg V <greg@unrelenting.technology>
|
||||
Change-Id: I57df9aedea7cc6f0b6fa142a6fc6c3bdc98324c8
|
||||
Reviewed-by: David Edmundson <davidedmundson@kde.org>
|
||||
(cherry picked from commit 59a5fe99e1569421b920d99c5b20cdafcdcf43a9)
|
||||
diff --git a/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp b/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp
|
||||
index 1c76294..3b99c4b 100644
|
||||
--- a/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp
|
||||
+++ b/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp
|
||||
@@ -410,6 +410,13 @@ 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());
|
||||
+ const QByteArray currentDesktop = qgetenv("XDG_CURRENT_DESKTOP");
|
||||
+ if (currentDesktop != QByteArray("KDE")) {
|
||||
+ 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;
|
@ -0,0 +1,90 @@
|
||||
From 61fccee064cd8cea698a530c76113f8487d11d68 Mon Sep 17 00:00:00 2001
|
||||
From: David Redondo <qt@david-redondo.de>
|
||||
Date: Wed, 8 Jun 2022 11:25:59 +0200
|
||||
Subject: [PATCH 42/55] Keep toplevel windows in the top left corner of the
|
||||
screen
|
||||
|
||||
We can't know the actual position of a window on the screen. This causes
|
||||
an issue when Widgets try to position a popup/menu absolutely and keep
|
||||
it on the screen when the screen geometry doesn't include (0,0).
|
||||
Instead report their positions always as the top left corner of
|
||||
the screen that they are on.
|
||||
This new behavior can be disabled for qt-shell or via an environment
|
||||
variable by users that rely on the old behavior.
|
||||
|
||||
Fixes: QTBUG-85297
|
||||
Change-Id: Iacb91cb03a0df87af950115760d2f41124ac06a3
|
||||
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
|
||||
Reviewed-by: David Edmundson <davidedmundson@kde.org>
|
||||
Reviewed-by: Aleix Pol Gonzalez <aleixpol@kde.org>
|
||||
(cherry picked from commit a46795a22e05722917c6ebc60ed01bebf49898ae)
|
||||
---
|
||||
src/client/qwaylandintegration.cpp | 3 +++
|
||||
src/client/qwaylandwindow.cpp | 14 +++++++++++++-
|
||||
src/client/qwaylandwindow_p.h | 3 +++
|
||||
3 files changed, 19 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/client/qwaylandintegration.cpp b/src/client/qwaylandintegration.cpp
|
||||
index fbf00c6b..54861600 100644
|
||||
--- a/src/client/qwaylandintegration.cpp
|
||||
+++ b/src/client/qwaylandintegration.cpp
|
||||
@@ -125,6 +125,9 @@ QWaylandIntegration::QWaylandIntegration()
|
||||
#endif
|
||||
|
||||
reconfigureInputContext();
|
||||
+
|
||||
+ QWaylandWindow::fixedToplevelPositions =
|
||||
+ !qEnvironmentVariableIsSet("QT_WAYLAND_DISABLE_FIXED_POSITIONS");
|
||||
}
|
||||
|
||||
QWaylandIntegration::~QWaylandIntegration()
|
||||
diff --git a/src/client/qwaylandwindow.cpp b/src/client/qwaylandwindow.cpp
|
||||
index 1f2d56b5..d3459168 100644
|
||||
--- a/src/client/qwaylandwindow.cpp
|
||||
+++ b/src/client/qwaylandwindow.cpp
|
||||
@@ -361,8 +361,13 @@ void QWaylandWindow::setGeometry_helper(const QRect &rect)
|
||||
}
|
||||
}
|
||||
|
||||
-void QWaylandWindow::setGeometry(const QRect &rect)
|
||||
+void QWaylandWindow::setGeometry(const QRect &r)
|
||||
{
|
||||
+ auto rect = r;
|
||||
+ if (fixedToplevelPositions && !QPlatformWindow::parent() && window()->type() != Qt::Popup
|
||||
+ && window()->type() != Qt::ToolTip) {
|
||||
+ rect.moveTo(screen()->geometry().topLeft());
|
||||
+ }
|
||||
setGeometry_helper(rect);
|
||||
|
||||
if (window()->isVisible() && rect.isValid()) {
|
||||
@@ -1044,6 +1049,13 @@ void QWaylandWindow::handleScreensChanged()
|
||||
|
||||
QWindowSystemInterface::handleWindowScreenChanged(window(), newScreen->QPlatformScreen::screen());
|
||||
mLastReportedScreen = newScreen;
|
||||
+ if (fixedToplevelPositions && !QPlatformWindow::parent() && window()->type() != Qt::Popup
|
||||
+ && window()->type() != Qt::ToolTip
|
||||
+ && geometry().topLeft() != newScreen->geometry().topLeft()) {
|
||||
+ auto geometry = this->geometry();
|
||||
+ geometry.moveTo(newScreen->geometry().topLeft());
|
||||
+ setGeometry(geometry);
|
||||
+ }
|
||||
|
||||
int scale = newScreen->isPlaceholder() ? 1 : static_cast<QWaylandScreen *>(newScreen)->scale();
|
||||
if (scale != mScale) {
|
||||
diff --git a/src/client/qwaylandwindow_p.h b/src/client/qwaylandwindow_p.h
|
||||
index e18609d9..a8ee2696 100644
|
||||
--- a/src/client/qwaylandwindow_p.h
|
||||
+++ b/src/client/qwaylandwindow_p.h
|
||||
@@ -98,6 +98,9 @@ public:
|
||||
QWaylandWindow(QWindow *window, QWaylandDisplay *display);
|
||||
~QWaylandWindow() override;
|
||||
|
||||
+ // Keep Toplevels position on the top left corner of their screen
|
||||
+ static inline bool fixedToplevelPositions = true;
|
||||
+
|
||||
virtual WindowType windowType() const = 0;
|
||||
virtual void ensureSize();
|
||||
WId winId() const override;
|
||||
--
|
||||
2.40.0
|
||||
|
@ -0,0 +1,103 @@
|
||||
From 3813da4b6d88320b42a7d91ae100e1567113ee72 Mon Sep 17 00:00:00 2001
|
||||
From: David Edmundson <kde@davidedmundson.co.uk>
|
||||
Date: Mon, 14 Nov 2022 10:43:25 +0000
|
||||
Subject: [PATCH 43/55] Revert "Client: Ensure that wl_surface lives as long as
|
||||
qtquick render thread needs it"
|
||||
|
||||
This reverts commit 81a7702a87f386a60a0ac8c902e203daae044d81
|
||||
---
|
||||
src/client/qwaylandwindow.cpp | 13 +------------
|
||||
src/client/qwaylandwindow_p.h | 3 ---
|
||||
.../client/wayland-egl/qwaylandglcontext.cpp | 6 +-----
|
||||
3 files changed, 2 insertions(+), 20 deletions(-)
|
||||
|
||||
diff --git a/src/client/qwaylandwindow.cpp b/src/client/qwaylandwindow.cpp
|
||||
index d3459168..f322a8d6 100644
|
||||
--- a/src/client/qwaylandwindow.cpp
|
||||
+++ b/src/client/qwaylandwindow.cpp
|
||||
@@ -76,7 +76,6 @@ QWaylandWindow *QWaylandWindow::mMouseGrab = nullptr;
|
||||
QWaylandWindow::QWaylandWindow(QWindow *window, QWaylandDisplay *display)
|
||||
: QPlatformWindow(window)
|
||||
, mDisplay(display)
|
||||
- , mSurfaceLock(QReadWriteLock::Recursive)
|
||||
, mResizeAfterSwap(qEnvironmentVariableIsSet("QT_WAYLAND_RESIZE_AFTER_SWAP"))
|
||||
{
|
||||
{
|
||||
@@ -238,16 +237,6 @@ bool QWaylandWindow::shouldCreateSubSurface() const
|
||||
return QPlatformWindow::parent() != nullptr;
|
||||
}
|
||||
|
||||
-void QWaylandWindow::beginFrame()
|
||||
-{
|
||||
- mSurfaceLock.lockForRead();
|
||||
-}
|
||||
-
|
||||
-void QWaylandWindow::endFrame()
|
||||
-{
|
||||
- mSurfaceLock.unlock();
|
||||
-}
|
||||
-
|
||||
void QWaylandWindow::reset()
|
||||
{
|
||||
closeChildPopups();
|
||||
@@ -256,10 +245,10 @@ void QWaylandWindow::reset()
|
||||
delete mSubSurfaceWindow;
|
||||
mSubSurfaceWindow = nullptr;
|
||||
|
||||
+ invalidateSurface();
|
||||
if (mSurface) {
|
||||
emit wlSurfaceDestroyed();
|
||||
QWriteLocker lock(&mSurfaceLock);
|
||||
- invalidateSurface();
|
||||
mSurface.reset();
|
||||
}
|
||||
|
||||
diff --git a/src/client/qwaylandwindow_p.h b/src/client/qwaylandwindow_p.h
|
||||
index a8ee2696..487a91a6 100644
|
||||
--- a/src/client/qwaylandwindow_p.h
|
||||
+++ b/src/client/qwaylandwindow_p.h
|
||||
@@ -210,9 +210,6 @@ public:
|
||||
void handleUpdate();
|
||||
void deliverUpdateRequest() override;
|
||||
|
||||
- void beginFrame();
|
||||
- void endFrame();
|
||||
-
|
||||
void addChildPopup(QWaylandWindow* child);
|
||||
void removeChildPopup(QWaylandWindow* child);
|
||||
void closeChildPopups();
|
||||
diff --git a/src/hardwareintegration/client/wayland-egl/qwaylandglcontext.cpp b/src/hardwareintegration/client/wayland-egl/qwaylandglcontext.cpp
|
||||
index 5d6fb2bf..c1f45fa6 100644
|
||||
--- a/src/hardwareintegration/client/wayland-egl/qwaylandglcontext.cpp
|
||||
+++ b/src/hardwareintegration/client/wayland-egl/qwaylandglcontext.cpp
|
||||
@@ -432,10 +432,8 @@ bool QWaylandGLContext::makeCurrent(QPlatformSurface *surface)
|
||||
return true;
|
||||
}
|
||||
|
||||
- if (window->isExposed()) {
|
||||
- window->beginFrame();
|
||||
+ if (window->isExposed())
|
||||
window->setCanResize(false);
|
||||
- }
|
||||
if (m_decorationsContext != EGL_NO_CONTEXT && !window->decoration())
|
||||
window->createDecoration();
|
||||
|
||||
@@ -451,7 +449,6 @@ bool QWaylandGLContext::makeCurrent(QPlatformSurface *surface)
|
||||
if (!eglMakeCurrent(m_eglDisplay, eglSurface, eglSurface, m_context)) {
|
||||
qWarning("QWaylandGLContext::makeCurrent: eglError: %x, this: %p \n", eglGetError(), this);
|
||||
window->setCanResize(true);
|
||||
- window->endFrame();
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -505,7 +502,6 @@ void QWaylandGLContext::swapBuffers(QPlatformSurface *surface)
|
||||
eglSwapBuffers(m_eglDisplay, eglSurface);
|
||||
|
||||
window->setCanResize(true);
|
||||
- window->endFrame();
|
||||
}
|
||||
|
||||
GLuint QWaylandGLContext::defaultFramebufferObject(QPlatformSurface *surface) const
|
||||
--
|
||||
2.40.0
|
||||
|
@ -0,0 +1,53 @@
|
||||
From dd605d5fec6921a7befbfe2c40c2ae87935aa9c4 Mon Sep 17 00:00:00 2001
|
||||
From: Vlad Zahorodnii <vlad.zahorodnii@kde.org>
|
||||
Date: Thu, 17 Nov 2022 15:25:37 +0200
|
||||
Subject: [PATCH 44/55] Client: Add F_SEAL_SHRINK seal to shm backing file
|
||||
|
||||
This lets libwayland-server avoid installing a SIGBUS handler when it
|
||||
wants to mmap() the backing file and access the contents of shared
|
||||
memory client buffers.
|
||||
|
||||
Change-Id: Id0b17f729799535d73e8700c5a99c32fd88a068a
|
||||
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
|
||||
Reviewed-by: David Edmundson <davidedmundson@kde.org>
|
||||
(cherry picked from commit 0c1cbb376e0cf878e3a91ab4917fe784a3b4c547)
|
||||
---
|
||||
src/client/qwaylandshmbackingstore.cpp | 8 +++++++-
|
||||
1 file changed, 7 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/client/qwaylandshmbackingstore.cpp b/src/client/qwaylandshmbackingstore.cpp
|
||||
index dc7ff670..98acd42d 100644
|
||||
--- a/src/client/qwaylandshmbackingstore.cpp
|
||||
+++ b/src/client/qwaylandshmbackingstore.cpp
|
||||
@@ -52,6 +52,7 @@
|
||||
|
||||
#include <QtWaylandClient/private/wayland-wayland-client-protocol.h>
|
||||
|
||||
+#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/mman.h>
|
||||
|
||||
@@ -61,6 +62,9 @@
|
||||
# ifndef MFD_CLOEXEC
|
||||
# define MFD_CLOEXEC 0x0001U
|
||||
# endif
|
||||
+# ifndef MFD_ALLOW_SEALING
|
||||
+# define MFD_ALLOW_SEALING 0x0002U
|
||||
+# endif
|
||||
#endif
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
@@ -75,7 +79,9 @@ QWaylandShmBuffer::QWaylandShmBuffer(QWaylandDisplay *display,
|
||||
int fd = -1;
|
||||
|
||||
#ifdef SYS_memfd_create
|
||||
- fd = syscall(SYS_memfd_create, "wayland-shm", MFD_CLOEXEC);
|
||||
+ fd = syscall(SYS_memfd_create, "wayland-shm", MFD_CLOEXEC | MFD_ALLOW_SEALING);
|
||||
+ if (fd >= 0)
|
||||
+ fcntl(fd, F_ADD_SEALS, F_SEAL_SHRINK | F_SEAL_SEAL);
|
||||
#endif
|
||||
|
||||
QScopedPointer<QFile> filePointer;
|
||||
--
|
||||
2.40.0
|
||||
|
@ -0,0 +1,31 @@
|
||||
From dea12f0bb5729de6c1a31b03b7e79710baf96b63 Mon Sep 17 00:00:00 2001
|
||||
From: Vlad Zahorodnii <vlad.zahorodnii@kde.org>
|
||||
Date: Mon, 21 Nov 2022 18:39:40 +0200
|
||||
Subject: [PATCH 45/55] Client: Call wl_output_release() upon QWaylandScreen
|
||||
destruction
|
||||
|
||||
It ensures that the proxy gets destroyed.
|
||||
|
||||
Change-Id: I915cc8814e33dd3b0405b2bf82bd12ce6b5f785b
|
||||
Reviewed-by: David Edmundson <davidedmundson@kde.org>
|
||||
(cherry picked from commit 054e54759dbd6c3e76b55d5c4a9a54f62967ad1a)
|
||||
---
|
||||
src/client/qwaylandscreen.cpp | 2 ++
|
||||
1 file changed, 2 insertions(+)
|
||||
|
||||
diff --git a/src/client/qwaylandscreen.cpp b/src/client/qwaylandscreen.cpp
|
||||
index 7c2d9be3..64ae4fe7 100644
|
||||
--- a/src/client/qwaylandscreen.cpp
|
||||
+++ b/src/client/qwaylandscreen.cpp
|
||||
@@ -81,6 +81,8 @@ QWaylandScreen::~QWaylandScreen()
|
||||
{
|
||||
if (zxdg_output_v1::isInitialized())
|
||||
zxdg_output_v1::destroy();
|
||||
+ if (wl_output::isInitialized() && wl_output_get_version(wl_output::object()) >= WL_OUTPUT_RELEASE_SINCE_VERSION)
|
||||
+ wl_output::release();
|
||||
}
|
||||
|
||||
uint QWaylandScreen::requiredEvents() const
|
||||
--
|
||||
2.40.0
|
||||
|
@ -0,0 +1,30 @@
|
||||
From 8071f24324ffa8c556068816e009a5887e1a6ddd Mon Sep 17 00:00:00 2001
|
||||
From: Vlad Zahorodnii <vlad.zahorodnii@kde.org>
|
||||
Date: Tue, 22 Nov 2022 12:33:41 +0200
|
||||
Subject: [PATCH 46/55] Client: Bump wl_output version
|
||||
|
||||
wl_output_release is available starting with wl_output v3.
|
||||
|
||||
Change-Id: I21822b26728ffb9318f1f8b4bd82ef7329682838
|
||||
Reviewed-by: David Edmundson <davidedmundson@kde.org>
|
||||
(cherry picked from commit c14916f5fd84f6b5483024b3df77592661a0f04e)
|
||||
---
|
||||
src/client/qwaylandscreen.cpp | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/client/qwaylandscreen.cpp b/src/client/qwaylandscreen.cpp
|
||||
index 64ae4fe7..5537dafd 100644
|
||||
--- a/src/client/qwaylandscreen.cpp
|
||||
+++ b/src/client/qwaylandscreen.cpp
|
||||
@@ -60,7 +60,7 @@ QWaylandXdgOutputManagerV1::QWaylandXdgOutputManagerV1(QWaylandDisplay* display,
|
||||
}
|
||||
|
||||
QWaylandScreen::QWaylandScreen(QWaylandDisplay *waylandDisplay, int version, uint32_t id)
|
||||
- : QtWayland::wl_output(waylandDisplay->wl_registry(), id, qMin(version, 2))
|
||||
+ : QtWayland::wl_output(waylandDisplay->wl_registry(), id, qMin(version, 3))
|
||||
, m_outputId(id)
|
||||
, mWaylandDisplay(waylandDisplay)
|
||||
, mOutputName(QStringLiteral("Screen%1").arg(id))
|
||||
--
|
||||
2.40.0
|
||||
|
@ -0,0 +1,166 @@
|
||||
From ef5b1f40b684927f73bc04ab84c396be074cb61e Mon Sep 17 00:00:00 2001
|
||||
From: Weng Xuetian <wengxt@gmail.com>
|
||||
Date: Sun, 27 Nov 2022 12:44:40 -0800
|
||||
Subject: [PATCH 47/55] Fix frame sync related to unprotected multithread
|
||||
access
|
||||
|
||||
There is a few crashes happens in real life that frame callback is
|
||||
double-free'd and hit an assertion in wayland-client. e.g.
|
||||
https://bugs.kde.org/show_bug.cgi?id=450003
|
||||
|
||||
This is due to the WaylandEventThread and calls to QWaylandWindow::reset
|
||||
may free and unset the mFrameCallback at the same time. mFrameSyncMutex
|
||||
should be used to protect such access.
|
||||
|
||||
Pick-to: 6.4
|
||||
Change-Id: Ie01d08d07a2f10f70606ed1935caac09cb4f0382
|
||||
(cherry picked from commit b6cbb5e323822d6e3ef5ed4dd5a4c4cc1ea85038)
|
||||
---
|
||||
src/client/qwaylandwindow.cpp | 64 ++++++++++++++++++++---------------
|
||||
src/client/qwaylandwindow_p.h | 11 +++---
|
||||
2 files changed, 43 insertions(+), 32 deletions(-)
|
||||
|
||||
diff --git a/src/client/qwaylandwindow.cpp b/src/client/qwaylandwindow.cpp
|
||||
index f322a8d6..6337db00 100644
|
||||
--- a/src/client/qwaylandwindow.cpp
|
||||
+++ b/src/client/qwaylandwindow.cpp
|
||||
@@ -252,13 +252,16 @@ void QWaylandWindow::reset()
|
||||
mSurface.reset();
|
||||
}
|
||||
|
||||
- if (mFrameCallback) {
|
||||
- wl_callback_destroy(mFrameCallback);
|
||||
- mFrameCallback = nullptr;
|
||||
- }
|
||||
+ {
|
||||
+ QMutexLocker lock(&mFrameSyncMutex);
|
||||
+ if (mFrameCallback) {
|
||||
+ wl_callback_destroy(mFrameCallback);
|
||||
+ mFrameCallback = nullptr;
|
||||
+ }
|
||||
|
||||
- mFrameCallbackElapsedTimer.invalidate();
|
||||
- mWaitingForFrameCallback = false;
|
||||
+ mFrameCallbackElapsedTimer.invalidate();
|
||||
+ mWaitingForFrameCallback = false;
|
||||
+ }
|
||||
mFrameCallbackTimedOut = false;
|
||||
|
||||
mMask = QRegion();
|
||||
@@ -633,18 +636,21 @@ const wl_callback_listener QWaylandWindow::callbackListener = {
|
||||
[](void *data, wl_callback *callback, uint32_t time) {
|
||||
Q_UNUSED(time);
|
||||
auto *window = static_cast<QWaylandWindow*>(data);
|
||||
-
|
||||
- Q_ASSERT(callback == window->mFrameCallback);
|
||||
- wl_callback_destroy(callback);
|
||||
- window->mFrameCallback = nullptr;
|
||||
-
|
||||
- window->handleFrameCallback();
|
||||
+ window->handleFrameCallback(callback);
|
||||
}
|
||||
};
|
||||
|
||||
-void QWaylandWindow::handleFrameCallback()
|
||||
+void QWaylandWindow::handleFrameCallback(wl_callback* callback)
|
||||
{
|
||||
QMutexLocker locker(&mFrameSyncMutex);
|
||||
+ if (!mFrameCallback) {
|
||||
+ // This means the callback is already unset by QWaylandWindow::reset.
|
||||
+ // The wl_callback object will be destroyed there too.
|
||||
+ return;
|
||||
+ }
|
||||
+ Q_ASSERT(callback == mFrameCallback);
|
||||
+ wl_callback_destroy(callback);
|
||||
+ mFrameCallback = nullptr;
|
||||
|
||||
mWaitingForFrameCallback = false;
|
||||
mFrameCallbackElapsedTimer.invalidate();
|
||||
@@ -1169,19 +1175,24 @@ void QWaylandWindow::timerEvent(QTimerEvent *event)
|
||||
if (event->timerId() != mFrameCallbackCheckIntervalTimerId)
|
||||
return;
|
||||
|
||||
- bool callbackTimerExpired = mFrameCallbackElapsedTimer.hasExpired(mFrameCallbackTimeout);
|
||||
- if (!mFrameCallbackElapsedTimer.isValid() || callbackTimerExpired ) {
|
||||
- killTimer(mFrameCallbackCheckIntervalTimerId);
|
||||
- mFrameCallbackCheckIntervalTimerId = -1;
|
||||
- }
|
||||
- if (mFrameCallbackElapsedTimer.isValid() && callbackTimerExpired) {
|
||||
- mFrameCallbackElapsedTimer.invalidate();
|
||||
+ {
|
||||
+ QMutexLocker lock(&mFrameSyncMutex);
|
||||
|
||||
- qCDebug(lcWaylandBackingstore) << "Didn't receive frame callback in time, window should now be inexposed";
|
||||
- mFrameCallbackTimedOut = true;
|
||||
- mWaitingForUpdate = false;
|
||||
- sendExposeEvent(QRect());
|
||||
+ bool callbackTimerExpired = mFrameCallbackElapsedTimer.hasExpired(mFrameCallbackTimeout);
|
||||
+ if (!mFrameCallbackElapsedTimer.isValid() || callbackTimerExpired ) {
|
||||
+ killTimer(mFrameCallbackCheckIntervalTimerId);
|
||||
+ mFrameCallbackCheckIntervalTimerId = -1;
|
||||
+ }
|
||||
+ if (!mFrameCallbackElapsedTimer.isValid() || !callbackTimerExpired) {
|
||||
+ return;
|
||||
+ }
|
||||
+ mFrameCallbackElapsedTimer.invalidate();
|
||||
}
|
||||
+
|
||||
+ qCDebug(lcWaylandBackingstore) << "Didn't receive frame callback in time, window should now be inexposed";
|
||||
+ mFrameCallbackTimedOut = true;
|
||||
+ mWaitingForUpdate = false;
|
||||
+ sendExposeEvent(QRect());
|
||||
}
|
||||
|
||||
void QWaylandWindow::requestUpdate()
|
||||
@@ -1224,15 +1235,14 @@ void QWaylandWindow::handleUpdate()
|
||||
{
|
||||
qCDebug(lcWaylandBackingstore) << "handleUpdate" << QThread::currentThread();
|
||||
|
||||
- if (mWaitingForFrameCallback)
|
||||
- return;
|
||||
-
|
||||
// TODO: Should sync subsurfaces avoid requesting frame callbacks?
|
||||
QReadLocker lock(&mSurfaceLock);
|
||||
if (!mSurface)
|
||||
return;
|
||||
|
||||
QMutexLocker locker(&mFrameSyncMutex);
|
||||
+ if (mWaitingForFrameCallback)
|
||||
+ return;
|
||||
|
||||
struct ::wl_surface *wrappedSurface = reinterpret_cast<struct ::wl_surface *>(wl_proxy_create_wrapper(mSurface->object()));
|
||||
wl_proxy_set_queue(reinterpret_cast<wl_proxy *>(wrappedSurface), mDisplay->frameEventQueue());
|
||||
diff --git a/src/client/qwaylandwindow_p.h b/src/client/qwaylandwindow_p.h
|
||||
index 487a91a6..2f219d8c 100644
|
||||
--- a/src/client/qwaylandwindow_p.h
|
||||
+++ b/src/client/qwaylandwindow_p.h
|
||||
@@ -237,12 +237,13 @@ protected:
|
||||
Qt::MouseButtons mMousePressedInContentArea = Qt::NoButton;
|
||||
|
||||
WId mWindowId;
|
||||
- bool mWaitingForFrameCallback = false;
|
||||
bool mFrameCallbackTimedOut = false; // Whether the frame callback has timed out
|
||||
- QAtomicInt mWaitingForUpdateDelivery = false;
|
||||
int mFrameCallbackCheckIntervalTimerId = -1;
|
||||
- QElapsedTimer mFrameCallbackElapsedTimer;
|
||||
- struct ::wl_callback *mFrameCallback = nullptr;
|
||||
+ QAtomicInt mWaitingForUpdateDelivery = false;
|
||||
+
|
||||
+ bool mWaitingForFrameCallback = false; // Protected by mFrameSyncMutex
|
||||
+ QElapsedTimer mFrameCallbackElapsedTimer; // Protected by mFrameSyncMutex
|
||||
+ struct ::wl_callback *mFrameCallback = nullptr; // Protected by mFrameSyncMutex
|
||||
QMutex mFrameSyncMutex;
|
||||
QWaitCondition mFrameSyncWait;
|
||||
|
||||
@@ -297,7 +298,7 @@ private:
|
||||
QRect mLastExposeGeometry;
|
||||
|
||||
static const wl_callback_listener callbackListener;
|
||||
- void handleFrameCallback();
|
||||
+ void handleFrameCallback(struct ::wl_callback* callback);
|
||||
|
||||
static QWaylandWindow *mMouseGrab;
|
||||
|
||||
--
|
||||
2.40.0
|
||||
|
@ -0,0 +1,66 @@
|
||||
From 21e354e7b1878a243d29466b19084083df3d0db9 Mon Sep 17 00:00:00 2001
|
||||
From: Vlad Zahorodnii <vlad.zahorodnii@kde.org>
|
||||
Date: Tue, 27 Sep 2022 22:05:07 +0300
|
||||
Subject: [PATCH 48/55] Client: Handle zwp_primary_selection_device_manager_v1
|
||||
global removal
|
||||
|
||||
The zwp_primary_selection_device_manager_v1 global can be withdrawn if
|
||||
the compositor disables the primary selection, i.e. middle click to
|
||||
paste selected text. QtWayland needs to handle that; otherwise the app
|
||||
can crash.
|
||||
|
||||
Pick-to: 6.5
|
||||
Change-Id: Idbb4db18b605f85a5951fa12c1bdf61898b0d123
|
||||
Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io>
|
||||
(cherry picked from commit 45163234a4e4baad0012d3ee07501093d98ba91c)
|
||||
---
|
||||
src/client/qwaylanddisplay.cpp | 9 +++++++++
|
||||
src/client/qwaylandprimaryselectionv1.cpp | 5 -----
|
||||
2 files changed, 9 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/src/client/qwaylanddisplay.cpp b/src/client/qwaylanddisplay.cpp
|
||||
index 6898a881..27f55965 100644
|
||||
--- a/src/client/qwaylanddisplay.cpp
|
||||
+++ b/src/client/qwaylanddisplay.cpp
|
||||
@@ -519,6 +519,8 @@ void QWaylandDisplay::registry_global(uint32_t id, const QString &interface, uin
|
||||
#if QT_CONFIG(wayland_client_primary_selection)
|
||||
} else if (interface == QStringLiteral("zwp_primary_selection_device_manager_v1")) {
|
||||
mPrimarySelectionManager.reset(new QWaylandPrimarySelectionDeviceManagerV1(this, id, 1));
|
||||
+ for (QWaylandInputDevice *inputDevice : qAsConst(mInputDevices))
|
||||
+ inputDevice->setPrimarySelectionDevice(mPrimarySelectionManager->createDevice(inputDevice));
|
||||
#endif
|
||||
} else if (interface == QStringLiteral("zwp_text_input_manager_v2") && !mClientSideInputContextRequested) {
|
||||
mTextInputManager.reset(new QtWayland::zwp_text_input_manager_v2(registry, id, 1));
|
||||
@@ -577,6 +579,13 @@ void QWaylandDisplay::registry_global_remove(uint32_t id)
|
||||
inputDevice->setTextInput(nullptr);
|
||||
mWaylandIntegration->reconfigureInputContext();
|
||||
}
|
||||
+#if QT_CONFIG(wayland_client_primary_selection)
|
||||
+ if (global.interface == QStringLiteral("zwp_primary_selection_device_manager_v1")) {
|
||||
+ mPrimarySelectionManager.reset();
|
||||
+ for (QWaylandInputDevice *inputDevice : qAsConst(mInputDevices))
|
||||
+ inputDevice->setPrimarySelectionDevice(nullptr);
|
||||
+ }
|
||||
+#endif
|
||||
mGlobals.removeAt(i);
|
||||
break;
|
||||
}
|
||||
diff --git a/src/client/qwaylandprimaryselectionv1.cpp b/src/client/qwaylandprimaryselectionv1.cpp
|
||||
index 832f9678..ea508771 100644
|
||||
--- a/src/client/qwaylandprimaryselectionv1.cpp
|
||||
+++ b/src/client/qwaylandprimaryselectionv1.cpp
|
||||
@@ -54,11 +54,6 @@ QWaylandPrimarySelectionDeviceManagerV1::QWaylandPrimarySelectionDeviceManagerV1
|
||||
: zwp_primary_selection_device_manager_v1(display->wl_registry(), id, qMin(version, uint(1)))
|
||||
, m_display(display)
|
||||
{
|
||||
- // Create devices for all seats.
|
||||
- // This only works if we get the global before all devices
|
||||
- const auto seats = m_display->inputDevices();
|
||||
- for (auto *seat : seats)
|
||||
- seat->setPrimarySelectionDevice(createDevice(seat));
|
||||
}
|
||||
|
||||
QWaylandPrimarySelectionDeviceV1 *QWaylandPrimarySelectionDeviceManagerV1::createDevice(QWaylandInputDevice *seat)
|
||||
--
|
||||
2.40.0
|
||||
|
@ -0,0 +1,26 @@
|
||||
From c12b0ed6db709e2af40ab3687d880aff5c56b5c1 Mon Sep 17 00:00:00 2001
|
||||
From: Aleix Pol <aleixpol@kde.org>
|
||||
Date: Mon, 19 Dec 2022 15:31:03 +0100
|
||||
Subject: [PATCH 49/55] Fixes the build on CentOS
|
||||
|
||||
Change-Id: I3c21972e7681be99b0f45c3ea3a57be285e4ff8e
|
||||
---
|
||||
src/client/qwaylandshmbackingstore.cpp | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/client/qwaylandshmbackingstore.cpp b/src/client/qwaylandshmbackingstore.cpp
|
||||
index 98acd42d..41cffdf7 100644
|
||||
--- a/src/client/qwaylandshmbackingstore.cpp
|
||||
+++ b/src/client/qwaylandshmbackingstore.cpp
|
||||
@@ -78,7 +78,7 @@ QWaylandShmBuffer::QWaylandShmBuffer(QWaylandDisplay *display,
|
||||
int alloc = stride * size.height();
|
||||
int fd = -1;
|
||||
|
||||
-#ifdef SYS_memfd_create
|
||||
+#if defined(SYS_memfd_create) && defined(F_SEAL_SEAL)
|
||||
fd = syscall(SYS_memfd_create, "wayland-shm", MFD_CLOEXEC | MFD_ALLOW_SEALING);
|
||||
if (fd >= 0)
|
||||
fcntl(fd, F_ADD_SEALS, F_SEAL_SHRINK | F_SEAL_SEAL);
|
||||
--
|
||||
2.40.0
|
||||
|
@ -0,0 +1,56 @@
|
||||
From d04d4c7fe2e00285e7d70da42094f213e13c6ed8 Mon Sep 17 00:00:00 2001
|
||||
From: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io>
|
||||
Date: Mon, 23 May 2022 09:47:24 +0200
|
||||
Subject: [PATCH 50/55] client: Avoid protocol error with invalid min/max size
|
||||
|
||||
If the application sets an invalid minimum and maximum size
|
||||
(where the minimum is higher than the maximum), then we
|
||||
would blindly send this over the protocol, which is a protocol
|
||||
error according to the spec. Qt compositors will warn about
|
||||
this and ignore the size, but mainly because "but there's no
|
||||
matching error defined" according to the comment. Other
|
||||
compositors may close the connection when this happens.
|
||||
|
||||
To avoid crashing the app based on bogus min/max size, we
|
||||
make sure we never send a maximum size which is less than
|
||||
the minimum size. This corresponds to the behavior of
|
||||
compositors which accept the size without raising an error:
|
||||
the minimum size takes precedence.
|
||||
|
||||
Note that 0 means "no maximum size" in the protocol, so we
|
||||
cap the value before applying this logic.
|
||||
|
||||
[ChangeLog][Client] Fixed an issue where setting an invalid
|
||||
minimum and maximum size on a window would cause some
|
||||
compositors to raise a protocol error.
|
||||
|
||||
Pick-to: 6.2 6.3
|
||||
Fixes: QTBUG-102626
|
||||
Fixes: QTBUG-103391
|
||||
Change-Id: I4004a4550a9fe3dae6a27169b4d1a9a616e21841
|
||||
Reviewed-by: David Edmundson <davidedmundson@kde.org>
|
||||
(cherry picked from commit 487de47277ccc31891f6340ce4c971c91336d9a4)
|
||||
---
|
||||
src/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp b/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp
|
||||
index ead99989..ad666129 100644
|
||||
--- a/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp
|
||||
+++ b/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp
|
||||
@@ -384,10 +384,10 @@ void QWaylandXdgSurface::setSizeHints()
|
||||
const int minHeight = qMax(0, m_window->windowMinimumSize().height());
|
||||
m_toplevel->set_min_size(minWidth, minHeight);
|
||||
|
||||
- int maxWidth = qMax(0, m_window->windowMaximumSize().width());
|
||||
+ int maxWidth = qMax(minWidth, m_window->windowMaximumSize().width());
|
||||
if (maxWidth == QWINDOWSIZE_MAX)
|
||||
maxWidth = 0;
|
||||
- int maxHeight = qMax(0, m_window->windowMaximumSize().height());
|
||||
+ int maxHeight = qMax(minHeight, m_window->windowMaximumSize().height());
|
||||
if (maxHeight == QWINDOWSIZE_MAX)
|
||||
maxHeight = 0;
|
||||
m_toplevel->set_max_size(maxWidth, maxHeight);
|
||||
--
|
||||
2.40.0
|
||||
|
@ -0,0 +1,38 @@
|
||||
From fbb9d65cf158bcf63440e9839acae9238ad4e0a7 Mon Sep 17 00:00:00 2001
|
||||
From: Vlad Zahorodnii <vlad.zahorodnii@kde.org>
|
||||
Date: Tue, 22 Nov 2022 23:27:34 +0200
|
||||
Subject: [PATCH 51/55] Client: Fix handling of Qt::BlankCursor
|
||||
|
||||
The cursor may not be properly set when a window has Qt::BlankCursor and
|
||||
it's shown. In that case, the cursor surface may not be present and
|
||||
wl_pointer.set_cursor won't be called.
|
||||
|
||||
On the other hand, wl_pointer.set_cursor must be always called when
|
||||
wl_pointer.enter is received.
|
||||
|
||||
Pick-to: 6.5
|
||||
Change-Id: I8540e7a02df1579b3380a1a1d4cfab42c1ab3104
|
||||
Reviewed-by: David Edmundson <davidedmundson@kde.org>
|
||||
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
|
||||
(cherry picked from commit e954853f0e68d78ac1a98bc3533713881496064c)
|
||||
---
|
||||
src/client/qwaylandinputdevice.cpp | 3 +--
|
||||
1 file changed, 1 insertion(+), 2 deletions(-)
|
||||
|
||||
diff --git a/src/client/qwaylandinputdevice.cpp b/src/client/qwaylandinputdevice.cpp
|
||||
index 5b880984..9a0fe49d 100644
|
||||
--- a/src/client/qwaylandinputdevice.cpp
|
||||
+++ b/src/client/qwaylandinputdevice.cpp
|
||||
@@ -310,8 +310,7 @@ void QWaylandInputDevice::Pointer::updateCursor()
|
||||
auto shape = seat()->mCursor.shape;
|
||||
|
||||
if (shape == Qt::BlankCursor) {
|
||||
- if (mCursor.surface)
|
||||
- mCursor.surface->hide();
|
||||
+ getOrCreateCursorSurface()->hide();
|
||||
return;
|
||||
}
|
||||
|
||||
--
|
||||
2.40.0
|
||||
|
@ -0,0 +1,117 @@
|
||||
From 6897f62f603df049135347cf402a7a4037092263 Mon Sep 17 00:00:00 2001
|
||||
From: Marco Martin <notmart@gmail.com>
|
||||
Date: Fri, 24 Feb 2023 17:40:48 +0100
|
||||
Subject: [PATCH 52/55] client: Force a roundtrip when an XdgOutput is not
|
||||
ready yet
|
||||
|
||||
Is possible that the server sends a surface_enter before
|
||||
all the information of the XdgOutput have been processed by the client.
|
||||
in this case the associated QScreen doesn't exist yet, causing a
|
||||
QWindow::SetScreen(nullptr), which will fall back to
|
||||
QGuiApplication::primaryScreen(), having the QWindow being assigned the
|
||||
wrong screen
|
||||
|
||||
Change-Id: I923d5d3a35484deafa6f0572f79c16c27b1f87f0
|
||||
Reviewed-by: David Edmundson <davidedmundson@kde.org>
|
||||
---
|
||||
src/client/qwaylandwindow.cpp | 2 ++
|
||||
tests/auto/client/shared/coreprotocol.cpp | 2 ++
|
||||
tests/auto/client/shared/coreprotocol.h | 3 ++
|
||||
tests/auto/client/xdgoutput/tst_xdgoutput.cpp | 35 +++++++++++++++++++
|
||||
4 files changed, 42 insertions(+)
|
||||
|
||||
diff --git a/src/client/qwaylandwindow.cpp b/src/client/qwaylandwindow.cpp
|
||||
index 6337db00..3b700002 100644
|
||||
--- a/src/client/qwaylandwindow.cpp
|
||||
+++ b/src/client/qwaylandwindow.cpp
|
||||
@@ -1042,6 +1042,8 @@ void QWaylandWindow::handleScreensChanged()
|
||||
if (newScreen == mLastReportedScreen)
|
||||
return;
|
||||
|
||||
+ if (!newScreen->isPlaceholder() && !newScreen->QPlatformScreen::screen())
|
||||
+ mDisplay->forceRoundTrip();
|
||||
QWindowSystemInterface::handleWindowScreenChanged(window(), newScreen->QPlatformScreen::screen());
|
||||
mLastReportedScreen = newScreen;
|
||||
if (fixedToplevelPositions && !QPlatformWindow::parent() && window()->type() != Qt::Popup
|
||||
diff --git a/tests/auto/client/shared/coreprotocol.cpp b/tests/auto/client/shared/coreprotocol.cpp
|
||||
index d1a2e7cb..53e12291 100644
|
||||
--- a/tests/auto/client/shared/coreprotocol.cpp
|
||||
+++ b/tests/auto/client/shared/coreprotocol.cpp
|
||||
@@ -185,6 +185,8 @@ void Output::output_bind_resource(QtWaylandServer::wl_output::Resource *resource
|
||||
|
||||
if (m_version >= WL_OUTPUT_DONE_SINCE_VERSION)
|
||||
wl_output::send_done(resource->handle);
|
||||
+
|
||||
+ Q_EMIT outputBound(resource);
|
||||
}
|
||||
|
||||
// Seat stuff
|
||||
diff --git a/tests/auto/client/shared/coreprotocol.h b/tests/auto/client/shared/coreprotocol.h
|
||||
index 210d8ddb..00c439e1 100644
|
||||
--- a/tests/auto/client/shared/coreprotocol.h
|
||||
+++ b/tests/auto/client/shared/coreprotocol.h
|
||||
@@ -273,6 +273,9 @@ public:
|
||||
OutputData m_data;
|
||||
int m_version = 1; // TODO: remove on libwayland upgrade
|
||||
|
||||
+Q_SIGNALS:
|
||||
+ void outputBound(Resource *resource);
|
||||
+
|
||||
protected:
|
||||
void output_bind_resource(Resource *resource) override;
|
||||
};
|
||||
diff --git a/tests/auto/client/xdgoutput/tst_xdgoutput.cpp b/tests/auto/client/xdgoutput/tst_xdgoutput.cpp
|
||||
index 80429608..68e8d77a 100644
|
||||
--- a/tests/auto/client/xdgoutput/tst_xdgoutput.cpp
|
||||
+++ b/tests/auto/client/xdgoutput/tst_xdgoutput.cpp
|
||||
@@ -55,6 +55,7 @@ private slots:
|
||||
void primaryScreen();
|
||||
void overrideGeometry();
|
||||
void changeGeometry();
|
||||
+ void outputCreateEnterRace();
|
||||
};
|
||||
|
||||
void tst_xdgoutput::cleanup()
|
||||
@@ -134,5 +135,39 @@ void tst_xdgoutput::changeGeometry()
|
||||
exec([=] { remove(output(1)); });
|
||||
}
|
||||
|
||||
+void tst_xdgoutput::outputCreateEnterRace()
|
||||
+{
|
||||
+ m_config.autoConfigure = true;
|
||||
+ m_config.autoEnter = false;
|
||||
+ QRasterWindow window;
|
||||
+ QSignalSpy screenChanged(&window, &QWindow::screenChanged);
|
||||
+ window.resize(400, 320);
|
||||
+ window.show();
|
||||
+ QCOMPOSITOR_TRY_VERIFY(xdgSurface() && xdgSurface()->m_committedConfigureSerial);
|
||||
+ exec([=] { xdgToplevel()->surface()->sendEnter(output(0));});
|
||||
+
|
||||
+ QTRY_COMPARE(QGuiApplication::screens().size(), 1);
|
||||
+ QScreen *primaryScreen = QGuiApplication::screens().first();
|
||||
+ QCOMPARE(window.screen(), primaryScreen);
|
||||
+
|
||||
+ auto *out = exec([=] {
|
||||
+ return add<Output>();
|
||||
+ });
|
||||
+
|
||||
+ // In Compositor Thread
|
||||
+ connect(out, &Output::outputBound, this, [this](QtWaylandServer::wl_output::Resource *resource){
|
||||
+ auto surface = xdgToplevel()->surface();
|
||||
+ surface->sendLeave(output(0));
|
||||
+ surface->QtWaylandServer::wl_surface::send_enter(surface->resource()->handle, resource->handle);
|
||||
+ }, Qt::DirectConnection);
|
||||
+
|
||||
+ QTRY_COMPARE(QGuiApplication::screens().size(), 2);
|
||||
+ QTRY_COMPARE(window.screen(), QGuiApplication::screens()[1]);
|
||||
+
|
||||
+ exec([=] { remove(out); });
|
||||
+ m_config.autoConfigure = false;
|
||||
+ m_config.autoEnter = true;
|
||||
+}
|
||||
+
|
||||
QCOMPOSITOR_TEST_MAIN(tst_xdgoutput)
|
||||
#include "tst_xdgoutput.moc"
|
||||
--
|
||||
2.40.0
|
||||
|
@ -0,0 +1,138 @@
|
||||
From 31eab11d3b6697a76cc7802d02e525c1152a42c2 Mon Sep 17 00:00:00 2001
|
||||
From: Tang Haixiang <tanghaixiang@uniontech.com>
|
||||
Date: Thu, 22 Dec 2022 15:19:53 +0800
|
||||
Subject: [PATCH 53/55] Client: Manage QMimeData lifecycle
|
||||
|
||||
QMimeData is created by user, it is not taken care of in qtwayland,
|
||||
which will cause memory leak.
|
||||
|
||||
It is now handled in qtwayland that when a new QMimeData is set,
|
||||
the previous QMimeData is freed.
|
||||
|
||||
Change-Id: Ic502021fe700c7ee10454d94f0d1868901809af7
|
||||
Reviewed-by: David Edmundson <davidedmundson@kde.org>
|
||||
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
|
||||
(cherry picked from commit 3af40c6c42703a65656fdd3322183abb2905e44d)
|
||||
---
|
||||
src/client/qwaylandclipboard.cpp | 27 +++++++++++++++++++++------
|
||||
src/client/qwaylandclipboard_p.h | 1 +
|
||||
src/client/qwaylanddatasource.cpp | 5 -----
|
||||
src/client/qwaylanddatasource_p.h | 2 --
|
||||
4 files changed, 22 insertions(+), 13 deletions(-)
|
||||
|
||||
diff --git a/src/client/qwaylandclipboard.cpp b/src/client/qwaylandclipboard.cpp
|
||||
index 81f48e05..14561c77 100644
|
||||
--- a/src/client/qwaylandclipboard.cpp
|
||||
+++ b/src/client/qwaylandclipboard.cpp
|
||||
@@ -54,10 +54,15 @@ namespace QtWaylandClient {
|
||||
QWaylandClipboard::QWaylandClipboard(QWaylandDisplay *display)
|
||||
: mDisplay(display)
|
||||
{
|
||||
+ m_clientClipboard[QClipboard::Clipboard] = nullptr;
|
||||
+ m_clientClipboard[QClipboard::Selection] = nullptr;
|
||||
}
|
||||
|
||||
QWaylandClipboard::~QWaylandClipboard()
|
||||
{
|
||||
+ if (m_clientClipboard[QClipboard::Clipboard] != m_clientClipboard[QClipboard::Selection])
|
||||
+ delete m_clientClipboard[QClipboard::Clipboard];
|
||||
+ delete m_clientClipboard[QClipboard::Selection];
|
||||
}
|
||||
|
||||
QMimeData *QWaylandClipboard::mimeData(QClipboard::Mode mode)
|
||||
@@ -69,8 +74,8 @@ QMimeData *QWaylandClipboard::mimeData(QClipboard::Mode mode)
|
||||
switch (mode) {
|
||||
case QClipboard::Clipboard:
|
||||
if (auto *dataDevice = seat->dataDevice()) {
|
||||
- if (auto *source = dataDevice->selectionSource())
|
||||
- return source->mimeData();
|
||||
+ if (dataDevice->selectionSource())
|
||||
+ return m_clientClipboard[QClipboard::Clipboard];
|
||||
if (auto *offer = dataDevice->selectionOffer())
|
||||
return offer->mimeData();
|
||||
}
|
||||
@@ -78,8 +83,8 @@ QMimeData *QWaylandClipboard::mimeData(QClipboard::Mode mode)
|
||||
case QClipboard::Selection:
|
||||
#if QT_CONFIG(wayland_client_primary_selection)
|
||||
if (auto *selectionDevice = seat->primarySelectionDevice()) {
|
||||
- if (auto *source = selectionDevice->selectionSource())
|
||||
- return source->mimeData();
|
||||
+ if (selectionDevice->selectionSource())
|
||||
+ return m_clientClipboard[QClipboard::Selection];
|
||||
if (auto *offer = selectionDevice->selectionOffer())
|
||||
return offer->mimeData();
|
||||
}
|
||||
@@ -104,17 +109,27 @@ void QWaylandClipboard::setMimeData(QMimeData *data, QClipboard::Mode mode)
|
||||
if (data && data->hasFormat(plain) && !data->hasFormat(utf8))
|
||||
data->setData(utf8, data->data(plain));
|
||||
|
||||
+ if (m_clientClipboard[mode]) {
|
||||
+ if (m_clientClipboard[QClipboard::Clipboard] != m_clientClipboard[QClipboard::Selection])
|
||||
+ delete m_clientClipboard[mode];
|
||||
+ m_clientClipboard[mode] = nullptr;
|
||||
+ }
|
||||
+
|
||||
+ m_clientClipboard[mode] = data;
|
||||
+
|
||||
switch (mode) {
|
||||
case QClipboard::Clipboard:
|
||||
if (auto *dataDevice = seat->dataDevice()) {
|
||||
- dataDevice->setSelectionSource(data ? new QWaylandDataSource(mDisplay->dndSelectionHandler(), data) : nullptr);
|
||||
+ dataDevice->setSelectionSource(data ? new QWaylandDataSource(mDisplay->dndSelectionHandler(),
|
||||
+ m_clientClipboard[QClipboard::Clipboard]) : nullptr);
|
||||
emitChanged(mode);
|
||||
}
|
||||
break;
|
||||
case QClipboard::Selection:
|
||||
#if QT_CONFIG(wayland_client_primary_selection)
|
||||
if (auto *selectionDevice = seat->primarySelectionDevice()) {
|
||||
- selectionDevice->setSelectionSource(data ? new QWaylandPrimarySelectionSourceV1(mDisplay->primarySelectionManager(), data) : nullptr);
|
||||
+ selectionDevice->setSelectionSource(data ? new QWaylandPrimarySelectionSourceV1(mDisplay->primarySelectionManager(),
|
||||
+ m_clientClipboard[QClipboard::Selection]) : nullptr);
|
||||
emitChanged(mode);
|
||||
}
|
||||
#endif
|
||||
diff --git a/src/client/qwaylandclipboard_p.h b/src/client/qwaylandclipboard_p.h
|
||||
index ce14e124..bb52683d 100644
|
||||
--- a/src/client/qwaylandclipboard_p.h
|
||||
+++ b/src/client/qwaylandclipboard_p.h
|
||||
@@ -80,6 +80,7 @@ public:
|
||||
private:
|
||||
QWaylandDisplay *mDisplay = nullptr;
|
||||
QMimeData m_emptyData;
|
||||
+ QMimeData *m_clientClipboard[2];
|
||||
};
|
||||
|
||||
}
|
||||
diff --git a/src/client/qwaylanddatasource.cpp b/src/client/qwaylanddatasource.cpp
|
||||
index 5599cbd4..e085152c 100644
|
||||
--- a/src/client/qwaylanddatasource.cpp
|
||||
+++ b/src/client/qwaylanddatasource.cpp
|
||||
@@ -71,11 +71,6 @@ QWaylandDataSource::~QWaylandDataSource()
|
||||
destroy();
|
||||
}
|
||||
|
||||
-QMimeData * QWaylandDataSource::mimeData() const
|
||||
-{
|
||||
- return m_mime_data;
|
||||
-}
|
||||
-
|
||||
void QWaylandDataSource::data_source_cancelled()
|
||||
{
|
||||
Q_EMIT cancelled();
|
||||
diff --git a/src/client/qwaylanddatasource_p.h b/src/client/qwaylanddatasource_p.h
|
||||
index 96f07bc3..14d1542d 100644
|
||||
--- a/src/client/qwaylanddatasource_p.h
|
||||
+++ b/src/client/qwaylanddatasource_p.h
|
||||
@@ -74,8 +74,6 @@ public:
|
||||
QWaylandDataSource(QWaylandDataDeviceManager *dataDeviceManager, QMimeData *mimeData);
|
||||
~QWaylandDataSource() override;
|
||||
|
||||
- QMimeData *mimeData() const;
|
||||
-
|
||||
Q_SIGNALS:
|
||||
void cancelled();
|
||||
void finished();
|
||||
--
|
||||
2.40.0
|
||||
|
@ -0,0 +1,34 @@
|
||||
From 18c2bcec31f68aafd66d7ec503ec6511ca804d07 Mon Sep 17 00:00:00 2001
|
||||
From: Aleix Pol <aleixpol@kde.org>
|
||||
Date: Mon, 6 Mar 2023 01:11:45 +0100
|
||||
Subject: [PATCH 54/55] client: Do not cast placeholder screens to
|
||||
QWaylandScreen
|
||||
|
||||
It's wrong to C-cast an object to a class that isn't theirs. Check if it
|
||||
is a placeholder first.
|
||||
|
||||
Pick-to: 5.15 6.2 6.5
|
||||
Change-Id: I45d3c423422ae6638a033fb0f4cfefc7cd4460f0
|
||||
Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io>
|
||||
Reviewed-by: David Edmundson <davidedmundson@kde.org>
|
||||
(cherry picked from commit a53f022393a1276dbf8eccbae04cb0bd6cea0160)
|
||||
---
|
||||
src/client/qwaylandnativeinterface.cpp | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/client/qwaylandnativeinterface.cpp b/src/client/qwaylandnativeinterface.cpp
|
||||
index bf54a1a0..9763c312 100644
|
||||
--- a/src/client/qwaylandnativeinterface.cpp
|
||||
+++ b/src/client/qwaylandnativeinterface.cpp
|
||||
@@ -139,7 +139,7 @@ void *QWaylandNativeInterface::nativeResourceForScreen(const QByteArray &resourc
|
||||
{
|
||||
QByteArray lowerCaseResource = resourceString.toLower();
|
||||
|
||||
- if (lowerCaseResource == "output")
|
||||
+ if (lowerCaseResource == "output" && !screen->handle()->isPlaceholder())
|
||||
return ((QWaylandScreen *) screen->handle())->output();
|
||||
|
||||
return nullptr;
|
||||
--
|
||||
2.40.0
|
||||
|
@ -0,0 +1,41 @@
|
||||
From c4c3fc69250c01cb35aaae5ea1ea2bcc8236dff0 Mon Sep 17 00:00:00 2001
|
||||
From: Vlad Zahorodnii <vlad.zahorodnii@kde.org>
|
||||
Date: Thu, 12 Jan 2023 14:49:25 +0200
|
||||
Subject: [PATCH 55/55] Client: Remove flip popup constraints
|
||||
|
||||
xdg_positioner doesn't have good anchor rect and other needed
|
||||
information so the compositor can properly flip popups. In some windows
|
||||
I see that some popups are flipped in such a way that the popups look
|
||||
"detached" from the parent window.
|
||||
|
||||
With the information that QtWayland provides so far only slide
|
||||
constraint adjustments can produce somewhat expected results. Although
|
||||
there will be still some issues near screen edges.
|
||||
|
||||
Pick-to: 6.5 6.4 6.2 5.15
|
||||
Task-number: QTBUG-87303
|
||||
Change-Id: I4021f497b78e62651fe606c4be21a387a92edd6c
|
||||
Reviewed-by: Liang Qi <liang.qi@qt.io>
|
||||
(cherry picked from commit d7a5dab0182cba19d7f59e542672aa3d1b2e859e)
|
||||
---
|
||||
src/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp | 4 +---
|
||||
1 file changed, 1 insertion(+), 3 deletions(-)
|
||||
|
||||
diff --git a/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp b/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp
|
||||
index ad666129..822b385c 100644
|
||||
--- a/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp
|
||||
+++ b/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp
|
||||
@@ -425,9 +425,7 @@ void QWaylandXdgSurface::setPopup(QWaylandWindow *parent)
|
||||
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);
|
||||
+ | QtWayland::xdg_positioner::constraint_adjustment_slide_y);
|
||||
m_popup = new Popup(this, parent, positioner);
|
||||
positioner->destroy();
|
||||
|
||||
--
|
||||
2.40.0
|
||||
|
Loading…
Reference in new issue