update to upstream version 5.15.10
(cherry picked from commit 3ef2ecbbb5a40b7122a6e7a08adad8d60d5771aa)
This commit is contained in:
parent
f5037acecd
commit
64fc445fd5
@ -1,7 +1,7 @@
|
|||||||
From d5186701e27ad6f09f3944809cec2a25c5328026 Mon Sep 17 00:00:00 2001
|
From d7ea7592e47828d2f806bb372db705a1f3b9f948 Mon Sep 17 00:00:00 2001
|
||||||
From: Vlad Zahorodnii <vlad.zahorodnii@kde.org>
|
From: Vlad Zahorodnii <vlad.zahorodnii@kde.org>
|
||||||
Date: Wed, 5 May 2021 20:49:26 +0300
|
Date: Wed, 5 May 2021 20:49:26 +0300
|
||||||
Subject: [PATCH 20/30] Client: Announce an output after receiving more
|
Subject: [PATCH 01/51] Client: Announce an output after receiving more
|
||||||
complete state
|
complete state
|
||||||
|
|
||||||
Output initialization is not atomic, meaning that the compositor may
|
Output initialization is not atomic, meaning that the compositor may
|
||||||
@ -142,5 +142,5 @@ index df1c94f2..050cfdc0 100644
|
|||||||
|
|
||||||
#if QT_CONFIG(cursor)
|
#if QT_CONFIG(cursor)
|
||||||
--
|
--
|
||||||
2.31.1
|
2.40.1
|
||||||
|
|
||||||
@ -1,7 +1,7 @@
|
|||||||
From 62494312db0f58053d1342bfacc7984186fdf3a6 Mon Sep 17 00:00:00 2001
|
From e08bb6ed336b4bd2f3e85b0d2f43f1b49cdaf7b0 Mon Sep 17 00:00:00 2001
|
||||||
From: Jaeyoon Jung <jaeyoon.jung@lge.com>
|
From: Jaeyoon Jung <jaeyoon.jung@lge.com>
|
||||||
Date: Mon, 15 Feb 2021 08:31:06 +0900
|
Date: Mon, 15 Feb 2021 08:31:06 +0900
|
||||||
Subject: [PATCH 21/30] Fix issue with repeated window size changes
|
Subject: [PATCH 02/51] Fix issue with repeated window size changes
|
||||||
|
|
||||||
Check if the new window size is different from the size requested
|
Check if the new window size is different from the size requested
|
||||||
previously before calling wl_egl_window_resize. It addresses the issue
|
previously before calling wl_egl_window_resize. It addresses the issue
|
||||||
@ -20,10 +20,10 @@ Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io>
|
|||||||
2 files changed, 4 insertions(+), 1 deletion(-)
|
2 files changed, 4 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
diff --git a/src/hardwareintegration/client/wayland-egl/qwaylandeglwindow.cpp b/src/hardwareintegration/client/wayland-egl/qwaylandeglwindow.cpp
|
diff --git a/src/hardwareintegration/client/wayland-egl/qwaylandeglwindow.cpp b/src/hardwareintegration/client/wayland-egl/qwaylandeglwindow.cpp
|
||||||
index 7889f575..201b583b 100644
|
index 57d4eb6b..13dd747a 100644
|
||||||
--- a/src/hardwareintegration/client/wayland-egl/qwaylandeglwindow.cpp
|
--- a/src/hardwareintegration/client/wayland-egl/qwaylandeglwindow.cpp
|
||||||
+++ b/src/hardwareintegration/client/wayland-egl/qwaylandeglwindow.cpp
|
+++ b/src/hardwareintegration/client/wayland-egl/qwaylandeglwindow.cpp
|
||||||
@@ -131,14 +131,16 @@ void QWaylandEglWindow::updateSurface(bool create)
|
@@ -122,14 +122,16 @@ void QWaylandEglWindow::updateSurface(bool create)
|
||||||
if (!disableResizeCheck) {
|
if (!disableResizeCheck) {
|
||||||
wl_egl_window_get_attached_size(m_waylandEglWindow, ¤t_width, ¤t_height);
|
wl_egl_window_get_attached_size(m_waylandEglWindow, ¤t_width, ¤t_height);
|
||||||
}
|
}
|
||||||
@ -42,10 +42,10 @@ index 7889f575..201b583b 100644
|
|||||||
|
|
||||||
if (!m_eglSurface && m_waylandEglWindow && create) {
|
if (!m_eglSurface && m_waylandEglWindow && create) {
|
||||||
diff --git a/src/hardwareintegration/client/wayland-egl/qwaylandeglwindow.h b/src/hardwareintegration/client/wayland-egl/qwaylandeglwindow.h
|
diff --git a/src/hardwareintegration/client/wayland-egl/qwaylandeglwindow.h b/src/hardwareintegration/client/wayland-egl/qwaylandeglwindow.h
|
||||||
index 5b1f4d56..0079dfef 100644
|
index 6c8f04ec..94c56325 100644
|
||||||
--- a/src/hardwareintegration/client/wayland-egl/qwaylandeglwindow.h
|
--- a/src/hardwareintegration/client/wayland-egl/qwaylandeglwindow.h
|
||||||
+++ b/src/hardwareintegration/client/wayland-egl/qwaylandeglwindow.h
|
+++ b/src/hardwareintegration/client/wayland-egl/qwaylandeglwindow.h
|
||||||
@@ -88,6 +88,7 @@ private:
|
@@ -87,6 +87,7 @@ private:
|
||||||
mutable QOpenGLFramebufferObject *m_contentFBO = nullptr;
|
mutable QOpenGLFramebufferObject *m_contentFBO = nullptr;
|
||||||
|
|
||||||
QSurfaceFormat m_format;
|
QSurfaceFormat m_format;
|
||||||
@ -54,5 +54,5 @@ index 5b1f4d56..0079dfef 100644
|
|||||||
|
|
||||||
}
|
}
|
||||||
--
|
--
|
||||||
2.31.1
|
2.40.1
|
||||||
|
|
||||||
@ -1,7 +1,7 @@
|
|||||||
From fcc2f57cefa66339c8cb6632f45a47fbb99bb60d Mon Sep 17 00:00:00 2001
|
From 40965d23e170cb02b184cda5962352acd415542e Mon Sep 17 00:00:00 2001
|
||||||
From: David Edmundson <davidedmundson@kde.org>
|
From: David Edmundson <davidedmundson@kde.org>
|
||||||
Date: Tue, 9 Feb 2021 16:09:21 +0000
|
Date: Tue, 9 Feb 2021 16:09:21 +0000
|
||||||
Subject: [PATCH 23/30] Client: Connect drags being accepted to updating the
|
Subject: [PATCH 03/51] Client: Connect drags being accepted to updating the
|
||||||
source drag icon
|
source drag icon
|
||||||
|
|
||||||
Currently in a multi-process drag and drop when the other client accepts
|
Currently in a multi-process drag and drop when the other client accepts
|
||||||
@ -23,7 +23,7 @@ Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io>
|
|||||||
1 file changed, 1 insertion(+)
|
1 file changed, 1 insertion(+)
|
||||||
|
|
||||||
diff --git a/src/client/qwaylanddatadevice.cpp b/src/client/qwaylanddatadevice.cpp
|
diff --git a/src/client/qwaylanddatadevice.cpp b/src/client/qwaylanddatadevice.cpp
|
||||||
index 19944a34..54a69c3c 100644
|
index 7e2e3308..bbd2d568 100644
|
||||||
--- a/src/client/qwaylanddatadevice.cpp
|
--- a/src/client/qwaylanddatadevice.cpp
|
||||||
+++ b/src/client/qwaylanddatadevice.cpp
|
+++ b/src/client/qwaylanddatadevice.cpp
|
||||||
@@ -124,6 +124,7 @@ bool QWaylandDataDevice::startDrag(QMimeData *mimeData, QWaylandWindow *icon)
|
@@ -124,6 +124,7 @@ bool QWaylandDataDevice::startDrag(QMimeData *mimeData, QWaylandWindow *icon)
|
||||||
@ -35,5 +35,5 @@ index 19944a34..54a69c3c 100644
|
|||||||
start_drag(m_dragSource->object(), origin->wlSurface(), icon->wlSurface(), m_display->currentInputDevice()->serial());
|
start_drag(m_dragSource->object(), origin->wlSurface(), icon->wlSurface(), m_display->currentInputDevice()->serial());
|
||||||
return true;
|
return true;
|
||||||
--
|
--
|
||||||
2.31.1
|
2.40.1
|
||||||
|
|
||||||
@ -1,7 +1,7 @@
|
|||||||
From 1b5e43a593e917610e6245f7a272ac081c508ba4 Mon Sep 17 00:00:00 2001
|
From 1474fd12afbc6c9850872801c70252c425d4280b Mon Sep 17 00:00:00 2001
|
||||||
From: David Edmundson <davidedmundson@kde.org>
|
From: David Edmundson <davidedmundson@kde.org>
|
||||||
Date: Fri, 14 May 2021 13:23:24 +0100
|
Date: Fri, 14 May 2021 13:23:24 +0100
|
||||||
Subject: [PATCH 24/30] Client: Disconnect registry listener on destruction
|
Subject: [PATCH 04/51] Client: Disconnect registry listener on destruction
|
||||||
|
|
||||||
If a display outlives a QWaylandClientExtension and a new global is
|
If a display outlives a QWaylandClientExtension and a new global is
|
||||||
announced we end up delivering an event to a now deleted extension which
|
announced we end up delivering an event to a now deleted extension which
|
||||||
@ -45,5 +45,5 @@ index 98272e57..5bd28398 100644
|
|||||||
QtWaylandClient::QWaylandIntegration *integration() const;
|
QtWaylandClient::QWaylandIntegration *integration() const;
|
||||||
int version() const;
|
int version() const;
|
||||||
--
|
--
|
||||||
2.31.1
|
2.40.1
|
||||||
|
|
||||||
@ -1,7 +1,7 @@
|
|||||||
From 36a552fa530be57091e986ebd1468d75d3061743 Mon Sep 17 00:00:00 2001
|
From f5e0a5773064636b6802a4f8f7fb0cb3cec46a68 Mon Sep 17 00:00:00 2001
|
||||||
From: David Edmundson <davidedmundson@kde.org>
|
From: David Edmundson <davidedmundson@kde.org>
|
||||||
Date: Mon, 3 May 2021 23:01:53 +0100
|
Date: Mon, 3 May 2021 23:01:53 +0100
|
||||||
Subject: [PATCH 25/30] Client: Set XdgShell size hints before the first commit
|
Subject: [PATCH 05/51] Client: Set XdgShell size hints before the first commit
|
||||||
|
|
||||||
propagateSizeHints is only called in QWindow we have platform window and
|
propagateSizeHints is only called in QWindow we have platform window and
|
||||||
minimumSizeHint is then sent. We also need to send existing hints when
|
minimumSizeHint is then sent. We also need to send existing hints when
|
||||||
@ -20,7 +20,7 @@ Reviewed-by: Aleix Pol Gonzalez <aleixpol@kde.org>
|
|||||||
2 files changed, 2 insertions(+), 3 deletions(-)
|
2 files changed, 2 insertions(+), 3 deletions(-)
|
||||||
|
|
||||||
diff --git a/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp b/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp
|
diff --git a/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp b/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp
|
||||||
index 3a1569f7..7d33dabd 100644
|
index fa9c01aa..c3d2d3ea 100644
|
||||||
--- a/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp
|
--- a/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp
|
||||||
+++ b/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp
|
+++ b/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp
|
||||||
@@ -105,8 +105,6 @@ void QWaylandXdgSurface::Toplevel::applyConfigure()
|
@@ -105,8 +105,6 @@ void QWaylandXdgSurface::Toplevel::applyConfigure()
|
||||||
@ -32,7 +32,7 @@ index 3a1569f7..7d33dabd 100644
|
|||||||
m_applied = m_pending;
|
m_applied = m_pending;
|
||||||
qCDebug(lcQpaWayland) << "Applied pending xdg_toplevel configure event:" << m_applied.size << m_applied.states;
|
qCDebug(lcQpaWayland) << "Applied pending xdg_toplevel configure event:" << m_applied.size << m_applied.states;
|
||||||
}
|
}
|
||||||
@@ -257,6 +255,7 @@ QWaylandXdgSurface::QWaylandXdgSurface(QWaylandXdgShell *shell, ::xdg_surface *s
|
@@ -267,6 +265,7 @@ QWaylandXdgSurface::QWaylandXdgSurface(QWaylandXdgShell *shell, ::xdg_surface *s
|
||||||
m_toplevel->set_parent(parentXdgSurface->m_toplevel->object());
|
m_toplevel->set_parent(parentXdgSurface->m_toplevel->object());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -54,5 +54,5 @@ index 2277bbb8..2fdd0a7c 100644
|
|||||||
QCOMPOSITOR_TRY_COMPARE(xdgToplevel()->m_committed.minSize, QSize(100, 100));
|
QCOMPOSITOR_TRY_COMPARE(xdgToplevel()->m_committed.minSize, QSize(100, 100));
|
||||||
QCOMPOSITOR_TRY_COMPARE(xdgToplevel()->m_committed.maxSize, QSize(1000, 1000));
|
QCOMPOSITOR_TRY_COMPARE(xdgToplevel()->m_committed.maxSize, QSize(1000, 1000));
|
||||||
--
|
--
|
||||||
2.31.1
|
2.40.1
|
||||||
|
|
||||||
@ -1,38 +0,0 @@
|
|||||||
From e5c272423d1bba2825086b82fd97499237a6fa4b Mon Sep 17 00:00:00 2001
|
|
||||||
From: Vlad Zahorodnii <vlad.zahorodnii@kde.org>
|
|
||||||
Date: Fri, 30 Oct 2020 16:55:30 +0200
|
|
||||||
Subject: [PATCH 05/19] Scanner: Avoid accessing dangling pointers in
|
|
||||||
destroy_func()
|
|
||||||
|
|
||||||
Usually, the object associated with the resource gets destroyed in the
|
|
||||||
destroy_resource() function.
|
|
||||||
|
|
||||||
Therefore, we need to double-check that the object is still alive before
|
|
||||||
trying to reset its m_resource.
|
|
||||||
|
|
||||||
Change-Id: I26408228f58919db17eb29584a1cbd4a9427d25c
|
|
||||||
Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io>
|
|
||||||
(cherry picked from commit 735164b5c2a2637a8d53a8803a2401e4ef477ff0)
|
|
||||||
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
|
|
||||||
---
|
|
||||||
src/qtwaylandscanner/qtwaylandscanner.cpp | 4 +++-
|
|
||||||
1 file changed, 3 insertions(+), 1 deletion(-)
|
|
||||||
|
|
||||||
diff --git a/src/qtwaylandscanner/qtwaylandscanner.cpp b/src/qtwaylandscanner/qtwaylandscanner.cpp
|
|
||||||
index 1d635f06..e2f87bbd 100644
|
|
||||||
--- a/src/qtwaylandscanner/qtwaylandscanner.cpp
|
|
||||||
+++ b/src/qtwaylandscanner/qtwaylandscanner.cpp
|
|
||||||
@@ -814,7 +814,9 @@ bool Scanner::process()
|
|
||||||
printf(" if (Q_LIKELY(that)) {\n");
|
|
||||||
printf(" that->m_resource_map.remove(resource->client(), resource);\n");
|
|
||||||
printf(" that->%s_destroy_resource(resource);\n", interfaceNameStripped);
|
|
||||||
- printf(" if (that->m_resource == resource)\n");
|
|
||||||
+ printf("\n");
|
|
||||||
+ printf(" that = resource->%s_object;\n", interfaceNameStripped);
|
|
||||||
+ printf(" if (that && that->m_resource == resource)\n");
|
|
||||||
printf(" that->m_resource = nullptr;\n");
|
|
||||||
printf(" }\n");
|
|
||||||
printf(" delete resource;\n");
|
|
||||||
--
|
|
||||||
2.31.1
|
|
||||||
|
|
||||||
@ -1,7 +1,7 @@
|
|||||||
From a8ddf1a7296e2d28b36231a391807226a7329ae4 Mon Sep 17 00:00:00 2001
|
From 27108c290bf0f12bb032827e5c01cc94e330d547 Mon Sep 17 00:00:00 2001
|
||||||
From: David Edmundson <davidedmundson@kde.org>
|
From: David Edmundson <davidedmundson@kde.org>
|
||||||
Date: Mon, 14 Jun 2021 12:45:37 +0100
|
Date: Mon, 14 Jun 2021 12:45:37 +0100
|
||||||
Subject: [PATCH 26/30] Fix build
|
Subject: [PATCH 06/51] Fix build
|
||||||
|
|
||||||
1b5e43a593e917610e6245f7a272ac081c508ba4 relied on a patch that we can't
|
1b5e43a593e917610e6245f7a272ac081c508ba4 relied on a patch that we can't
|
||||||
backport.
|
backport.
|
||||||
@ -42,5 +42,5 @@ index 69cc46a0..9091efbe 100644
|
|||||||
|
|
||||||
class Q_WAYLAND_CLIENT_EXPORT QWaylandClientExtensionTemplatePrivate : public QWaylandClientExtensionPrivate
|
class Q_WAYLAND_CLIENT_EXPORT QWaylandClientExtensionTemplatePrivate : public QWaylandClientExtensionPrivate
|
||||||
--
|
--
|
||||||
2.31.1
|
2.40.1
|
||||||
|
|
||||||
@ -1,38 +0,0 @@
|
|||||||
From a825fb5f714fd79d16cc3ebbdd327e7961b07d0a Mon Sep 17 00:00:00 2001
|
|
||||||
From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= <morten.sorvig@qt.io>
|
|
||||||
Date: Mon, 16 Nov 2020 19:37:33 +0100
|
|
||||||
Subject: [PATCH 06/19] Make setting QT_SCALE_FACTOR work on Wayland
|
|
||||||
|
|
||||||
Follow-up to 8cb1b07aea12d50b4fecc45c903705dfd368022a,
|
|
||||||
fixes one additional case (Use of minimum/maximum size).
|
|
||||||
|
|
||||||
Fixes: QTBUG-87762
|
|
||||||
Change-Id: I73e0df2529b0cadf25ad50ea7459cdbb92caf424
|
|
||||||
Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io>
|
|
||||||
(cherry picked from commit 6ed363e3665f17d935f8636d9c958154c898f5c5)
|
|
||||||
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
|
|
||||||
---
|
|
||||||
src/client/qwaylandwindow.cpp | 6 ++++--
|
|
||||||
1 file changed, 4 insertions(+), 2 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/src/client/qwaylandwindow.cpp b/src/client/qwaylandwindow.cpp
|
|
||||||
index bc031ed5..eb053406 100644
|
|
||||||
--- a/src/client/qwaylandwindow.cpp
|
|
||||||
+++ b/src/client/qwaylandwindow.cpp
|
|
||||||
@@ -332,9 +332,11 @@ void QWaylandWindow::setWindowIcon(const QIcon &icon)
|
|
||||||
|
|
||||||
void QWaylandWindow::setGeometry_helper(const QRect &rect)
|
|
||||||
{
|
|
||||||
+ QSize minimum = windowMinimumSize();
|
|
||||||
+ QSize maximum = windowMaximumSize();
|
|
||||||
QPlatformWindow::setGeometry(QRect(rect.x(), rect.y(),
|
|
||||||
- qBound(window()->minimumWidth(), rect.width(), window()->maximumWidth()),
|
|
||||||
- qBound(window()->minimumHeight(), rect.height(), window()->maximumHeight())));
|
|
||||||
+ qBound(minimum.width(), rect.width(), maximum.width()),
|
|
||||||
+ qBound(minimum.height(), rect.height(), maximum.height())));
|
|
||||||
|
|
||||||
if (mSubSurfaceWindow) {
|
|
||||||
QMargins m = QPlatformWindow::parent()->frameMargins();
|
|
||||||
--
|
|
||||||
2.31.1
|
|
||||||
|
|
||||||
@ -1,62 +0,0 @@
|
|||||||
From 2c0a03e9aea13831d05ac03996949f888afd5085 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Jaehak Lee <jaehak.lee@mobis.co.kr>
|
|
||||||
Date: Sun, 8 Nov 2020 11:40:06 +0900
|
|
||||||
Subject: [PATCH 07/19] Do not try to eglMakeCurrent for unintended case
|
|
||||||
|
|
||||||
The QSGThreadedRenderLoop::hide can be called at twice,
|
|
||||||
when the QWindowPrivate::setVisible(false) is called.
|
|
||||||
|
|
||||||
The eglSurface is EGL_NO_SURFACE when the second QSGThreadedRenderLoop::hide is
|
|
||||||
called. And if EGL_KHR_surfaceless_context is supported, the eglMakeCurrent
|
|
||||||
don't return the false.
|
|
||||||
|
|
||||||
But this case is not intended. So, add the defence code for above case.
|
|
||||||
|
|
||||||
Fixes: QTBUG-88277
|
|
||||||
Change-Id: Ia9e5990303e98f0eedc48531e5af62ff9961f419
|
|
||||||
Reviewed-by: Laszlo Agocs <laszlo.agocs@qt.io>
|
|
||||||
Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io>
|
|
||||||
---
|
|
||||||
.../client/wayland-egl/qwaylandglcontext.cpp | 6 ++++++
|
|
||||||
.../client/wayland-egl/qwaylandglcontext.h | 1 +
|
|
||||||
2 files changed, 7 insertions(+)
|
|
||||||
|
|
||||||
diff --git a/src/hardwareintegration/client/wayland-egl/qwaylandglcontext.cpp b/src/hardwareintegration/client/wayland-egl/qwaylandglcontext.cpp
|
|
||||||
index ccebf43d..681f82f4 100644
|
|
||||||
--- a/src/hardwareintegration/client/wayland-egl/qwaylandglcontext.cpp
|
|
||||||
+++ b/src/hardwareintegration/client/wayland-egl/qwaylandglcontext.cpp
|
|
||||||
@@ -336,6 +336,8 @@ QWaylandGLContext::QWaylandGLContext(EGLDisplay eglDisplay, QWaylandDisplay *dis
|
|
||||||
<< "It may also cause the event loop to freeze in some situations";
|
|
||||||
}
|
|
||||||
|
|
||||||
+ m_supportSurfaceLessContext = q_hasEglExtension(m_eglDisplay, "EGL_KHR_surfaceless_context");
|
|
||||||
+
|
|
||||||
updateGLFormat();
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -439,6 +441,10 @@ bool QWaylandGLContext::makeCurrent(QPlatformSurface *surface)
|
|
||||||
eglSurface = window->eglSurface();
|
|
||||||
}
|
|
||||||
|
|
||||||
+ if (eglSurface == EGL_NO_SURFACE && m_supportSurfaceLessContext) {
|
|
||||||
+ return false;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
if (!eglMakeCurrent(m_eglDisplay, eglSurface, eglSurface, m_context)) {
|
|
||||||
qWarning("QWaylandGLContext::makeCurrent: eglError: %x, this: %p \n", eglGetError(), this);
|
|
||||||
window->setCanResize(true);
|
|
||||||
diff --git a/src/hardwareintegration/client/wayland-egl/qwaylandglcontext.h b/src/hardwareintegration/client/wayland-egl/qwaylandglcontext.h
|
|
||||||
index 46c7bb76..93edaec0 100644
|
|
||||||
--- a/src/hardwareintegration/client/wayland-egl/qwaylandglcontext.h
|
|
||||||
+++ b/src/hardwareintegration/client/wayland-egl/qwaylandglcontext.h
|
|
||||||
@@ -93,6 +93,7 @@ private:
|
|
||||||
DecorationsBlitter *m_blitter = nullptr;
|
|
||||||
uint m_api;
|
|
||||||
bool m_supportNonBlockingSwap = true;
|
|
||||||
+ bool m_supportSurfaceLessContext = false;
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
--
|
|
||||||
2.31.1
|
|
||||||
|
|
||||||
@ -1,7 +1,7 @@
|
|||||||
From d1c4a459faa1d514026c4834828cb33024ac2ceb Mon Sep 17 00:00:00 2001
|
From 07a83b80d7c1b90146d9c6b6339bf4e730ca50b9 Mon Sep 17 00:00:00 2001
|
||||||
From: Zhang Liang <zhanglianga@uniontech.com>
|
From: Zhang Liang <zhanglianga@uniontech.com>
|
||||||
Date: Mon, 1 Feb 2021 19:29:43 +0800
|
Date: Mon, 1 Feb 2021 19:29:43 +0800
|
||||||
Subject: [PATCH 27/30] Fix: remove listener
|
Subject: [PATCH 07/51] Fix: remove listener
|
||||||
|
|
||||||
Add the operation for removing the listener form listener list
|
Add the operation for removing the listener form listener list
|
||||||
|
|
||||||
@ -13,10 +13,10 @@ Reviewed-by: David Edmundson <davidedmundson@kde.org>
|
|||||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
diff --git a/src/client/qwaylanddisplay.cpp b/src/client/qwaylanddisplay.cpp
|
diff --git a/src/client/qwaylanddisplay.cpp b/src/client/qwaylanddisplay.cpp
|
||||||
index f10c1f79..e0dfe8b2 100644
|
index 78e387bc..280e63bd 100644
|
||||||
--- a/src/client/qwaylanddisplay.cpp
|
--- a/src/client/qwaylanddisplay.cpp
|
||||||
+++ b/src/client/qwaylanddisplay.cpp
|
+++ b/src/client/qwaylanddisplay.cpp
|
||||||
@@ -452,9 +452,10 @@ void QWaylandDisplay::addRegistryListener(RegistryListener listener, void *data)
|
@@ -456,9 +456,10 @@ void QWaylandDisplay::addRegistryListener(RegistryListener listener, void *data)
|
||||||
|
|
||||||
void QWaylandDisplay::removeListener(RegistryListener listener, void *data)
|
void QWaylandDisplay::removeListener(RegistryListener listener, void *data)
|
||||||
{
|
{
|
||||||
@ -29,5 +29,5 @@ index f10c1f79..e0dfe8b2 100644
|
|||||||
|
|
||||||
uint32_t QWaylandDisplay::currentTimeMillisec()
|
uint32_t QWaylandDisplay::currentTimeMillisec()
|
||||||
--
|
--
|
||||||
2.31.1
|
2.40.1
|
||||||
|
|
||||||
@ -1,7 +1,7 @@
|
|||||||
From a6476d1a1c78eb7f17408241b268404e27b3e161 Mon Sep 17 00:00:00 2001
|
From 218aa4f1fb91a1dfe892111a45376091dd34ec06 Mon Sep 17 00:00:00 2001
|
||||||
From: David Redondo <qt@david-redondo.de>
|
From: David Redondo <qt@david-redondo.de>
|
||||||
Date: Wed, 26 May 2021 14:49:40 +0200
|
Date: Wed, 26 May 2021 14:49:40 +0200
|
||||||
Subject: [PATCH 28/30] Hook up queryKeyboardModifers
|
Subject: [PATCH 08/51] Hook up queryKeyboardModifers
|
||||||
|
|
||||||
Can be useful when upon enter a modifiers event is received but no key
|
Can be useful when upon enter a modifiers event is received but no key
|
||||||
event so no QKeyEvent is generated.
|
event so no QKeyEvent is generated.
|
||||||
@ -19,7 +19,7 @@ Reviewed-by: David Edmundson <davidedmundson@kde.org>
|
|||||||
2 files changed, 10 insertions(+)
|
2 files changed, 10 insertions(+)
|
||||||
|
|
||||||
diff --git a/src/client/qwaylandintegration.cpp b/src/client/qwaylandintegration.cpp
|
diff --git a/src/client/qwaylandintegration.cpp b/src/client/qwaylandintegration.cpp
|
||||||
index c53ccb78..e5e7dd42 100644
|
index d257e2e3..cd8569b1 100644
|
||||||
--- a/src/client/qwaylandintegration.cpp
|
--- a/src/client/qwaylandintegration.cpp
|
||||||
+++ b/src/client/qwaylandintegration.cpp
|
+++ b/src/client/qwaylandintegration.cpp
|
||||||
@@ -262,6 +262,14 @@ QWaylandDisplay *QWaylandIntegration::display() const
|
@@ -262,6 +262,14 @@ QWaylandDisplay *QWaylandIntegration::display() const
|
||||||
@ -51,5 +51,5 @@ index ff70ae25..73b80658 100644
|
|||||||
|
|
||||||
QStringList themeNames() const override;
|
QStringList themeNames() const override;
|
||||||
--
|
--
|
||||||
2.31.1
|
2.40.1
|
||||||
|
|
||||||
@ -1,112 +0,0 @@
|
|||||||
From 10005185e06857ce119c50fe710f9eedde06ec5e Mon Sep 17 00:00:00 2001
|
|
||||||
From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= <morten.sorvig@qt.io>
|
|
||||||
Date: Fri, 13 Nov 2020 11:21:50 +0100
|
|
||||||
Subject: [PATCH 08/19] Make setting QT_SCALE_FACTOR work on Wayland
|
|
||||||
|
|
||||||
QWindow geometry accessors return geometry in device
|
|
||||||
independent pixels. Normally this coordinate system
|
|
||||||
is equivalent to the Wayland native coordinate system,
|
|
||||||
but this is not the case when QT_SCALE_FACTOR is set.
|
|
||||||
|
|
||||||
Replace QWindow geometry calls with the helpers from
|
|
||||||
QPlatformWindow which return geometry in the native
|
|
||||||
coordinate system:
|
|
||||||
|
|
||||||
QWindow::geometry() -> QPlatformWindow::windowGeometry()
|
|
||||||
QWindow::frameGeometry() -> QPlatformWindow::windowFrameGeometry()
|
|
||||||
|
|
||||||
Task-number: QTBUG-87762
|
|
||||||
Fixes: QTBUG-88064
|
|
||||||
(cherry-picked from commit 8cb1b07aea12d50b4fecc45c903705dfd368022a)
|
|
||||||
Change-Id: I6e2029bc6210f12441ae7c9d8b678271e9922dde
|
|
||||||
Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io>
|
|
||||||
---
|
|
||||||
src/client/qwaylandwindow.cpp | 7 ++++---
|
|
||||||
.../shellintegration/wl-shell/qwaylandwlshellsurface.cpp | 2 +-
|
|
||||||
.../shellintegration/xdg-shell-v5/qwaylandxdgsurfacev5.cpp | 2 +-
|
|
||||||
.../shellintegration/xdg-shell-v6/qwaylandxdgshellv6.cpp | 2 +-
|
|
||||||
.../shellintegration/xdg-shell/qwaylandxdgshell.cpp | 2 +-
|
|
||||||
5 files changed, 8 insertions(+), 7 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/src/client/qwaylandwindow.cpp b/src/client/qwaylandwindow.cpp
|
|
||||||
index eb053406..9b343702 100644
|
|
||||||
--- a/src/client/qwaylandwindow.cpp
|
|
||||||
+++ b/src/client/qwaylandwindow.cpp
|
|
||||||
@@ -194,10 +194,11 @@ void QWaylandWindow::initWindow()
|
|
||||||
if (QScreen *s = window()->screen())
|
|
||||||
setOrientationMask(s->orientationUpdateMask());
|
|
||||||
setWindowFlags(window()->flags());
|
|
||||||
- if (window()->geometry().isEmpty())
|
|
||||||
+ QRect geometry = windowGeometry();
|
|
||||||
+ if (geometry.isEmpty())
|
|
||||||
setGeometry_helper(QRect(QPoint(), QSize(500,500)));
|
|
||||||
else
|
|
||||||
- setGeometry_helper(window()->geometry());
|
|
||||||
+ setGeometry_helper(geometry);
|
|
||||||
setMask(window()->mask());
|
|
||||||
if (mShellSurface)
|
|
||||||
mShellSurface->requestWindowStates(window()->windowStates());
|
|
||||||
@@ -431,7 +432,7 @@ void QWaylandWindow::setVisible(bool visible)
|
|
||||||
initWindow();
|
|
||||||
mDisplay->flushRequests();
|
|
||||||
|
|
||||||
- setGeometry(window()->geometry());
|
|
||||||
+ setGeometry(windowGeometry());
|
|
||||||
// Don't flush the events here, or else the newly visible window may start drawing, but since
|
|
||||||
// there was no frame before it will be stuck at the waitForFrameSync() in
|
|
||||||
// QWaylandShmBackingStore::beginPaint().
|
|
||||||
diff --git a/src/plugins/shellintegration/wl-shell/qwaylandwlshellsurface.cpp b/src/plugins/shellintegration/wl-shell/qwaylandwlshellsurface.cpp
|
|
||||||
index 245fec19..8f41118d 100644
|
|
||||||
--- a/src/plugins/shellintegration/wl-shell/qwaylandwlshellsurface.cpp
|
|
||||||
+++ b/src/plugins/shellintegration/wl-shell/qwaylandwlshellsurface.cpp
|
|
||||||
@@ -134,7 +134,7 @@ void QWaylandWlShellSurface::applyConfigure()
|
|
||||||
{
|
|
||||||
if ((m_pending.states & (Qt::WindowMaximized|Qt::WindowFullScreen))
|
|
||||||
&& !(m_applied.states & (Qt::WindowMaximized|Qt::WindowFullScreen))) {
|
|
||||||
- m_normalSize = m_window->window()->frameGeometry().size();
|
|
||||||
+ m_normalSize = m_window->windowFrameGeometry().size();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_pending.states != m_applied.states)
|
|
||||||
diff --git a/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgsurfacev5.cpp b/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgsurfacev5.cpp
|
|
||||||
index 770fad7e..73aba1ee 100644
|
|
||||||
--- a/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgsurfacev5.cpp
|
|
||||||
+++ b/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgsurfacev5.cpp
|
|
||||||
@@ -157,7 +157,7 @@ void QWaylandXdgSurfaceV5::applyConfigure()
|
|
||||||
if (m_pending.isResizing)
|
|
||||||
m_normalSize = m_pending.size;
|
|
||||||
else if (!(m_acked.states & (Qt::WindowMaximized|Qt::WindowFullScreen)))
|
|
||||||
- m_normalSize = m_window->window()->frameGeometry().size();
|
|
||||||
+ m_normalSize = m_window->windowFrameGeometry().size();
|
|
||||||
|
|
||||||
if ((m_pending.states & Qt::WindowActive) && !(m_acked.states & Qt::WindowActive))
|
|
||||||
m_window->display()->handleWindowActivated(m_window);
|
|
||||||
diff --git a/src/plugins/shellintegration/xdg-shell-v6/qwaylandxdgshellv6.cpp b/src/plugins/shellintegration/xdg-shell-v6/qwaylandxdgshellv6.cpp
|
|
||||||
index c137b308..8c371661 100644
|
|
||||||
--- a/src/plugins/shellintegration/xdg-shell-v6/qwaylandxdgshellv6.cpp
|
|
||||||
+++ b/src/plugins/shellintegration/xdg-shell-v6/qwaylandxdgshellv6.cpp
|
|
||||||
@@ -72,7 +72,7 @@ QWaylandXdgSurfaceV6::Toplevel::~Toplevel()
|
|
||||||
void QWaylandXdgSurfaceV6::Toplevel::applyConfigure()
|
|
||||||
{
|
|
||||||
if (!(m_applied.states & (Qt::WindowMaximized|Qt::WindowFullScreen)))
|
|
||||||
- m_normalSize = m_xdgSurface->m_window->window()->frameGeometry().size();
|
|
||||||
+ m_normalSize = m_xdgSurface->m_window->windowFrameGeometry().size();
|
|
||||||
|
|
||||||
if ((m_pending.states & Qt::WindowActive) && !(m_applied.states & Qt::WindowActive))
|
|
||||||
m_xdgSurface->m_window->display()->handleWindowActivated(m_xdgSurface->m_window);
|
|
||||||
diff --git a/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp b/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp
|
|
||||||
index b6d23ac1..1c762944 100644
|
|
||||||
--- a/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp
|
|
||||||
+++ b/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp
|
|
||||||
@@ -83,7 +83,7 @@ QWaylandXdgSurface::Toplevel::~Toplevel()
|
|
||||||
void QWaylandXdgSurface::Toplevel::applyConfigure()
|
|
||||||
{
|
|
||||||
if (!(m_applied.states & (Qt::WindowMaximized|Qt::WindowFullScreen)))
|
|
||||||
- m_normalSize = m_xdgSurface->m_window->window()->frameGeometry().size();
|
|
||||||
+ m_normalSize = m_xdgSurface->m_window->windowFrameGeometry().size();
|
|
||||||
|
|
||||||
if ((m_pending.states & Qt::WindowActive) && !(m_applied.states & Qt::WindowActive))
|
|
||||||
m_xdgSurface->m_window->display()->handleWindowActivated(m_xdgSurface->m_window);
|
|
||||||
--
|
|
||||||
2.31.1
|
|
||||||
|
|
||||||
@ -1,7 +1,7 @@
|
|||||||
From 3c420cd180397e3f42c8a436a7f1b11465925bdd Mon Sep 17 00:00:00 2001
|
From cedb1d0987486f0162d8a10defb3705f5e3b3a45 Mon Sep 17 00:00:00 2001
|
||||||
From: Jan Blackquill <uhhadd@gmail.com>
|
From: Jan Blackquill <uhhadd@gmail.com>
|
||||||
Date: Tue, 24 Aug 2021 14:36:34 -0400
|
Date: Tue, 24 Aug 2021 14:36:34 -0400
|
||||||
Subject: [PATCH 30/30] Correctly detect if image format is supported by
|
Subject: [PATCH 09/51] Correctly detect if image format is supported by
|
||||||
QImageWriter
|
QImageWriter
|
||||||
|
|
||||||
The code queries potential image formats by stripping a mimetype of its
|
The code queries potential image formats by stripping a mimetype of its
|
||||||
@ -64,5 +64,5 @@ index a5fdd34d..051a91dc 100644
|
|||||||
fmt = imgFmt;
|
fmt = imgFmt;
|
||||||
}
|
}
|
||||||
--
|
--
|
||||||
2.31.1
|
2.40.1
|
||||||
|
|
||||||
@ -1,35 +0,0 @@
|
|||||||
From dba4bc4f1d6dfee9fe9433c55b15653d703bed4f Mon Sep 17 00:00:00 2001
|
|
||||||
From: Andreas Cord-Landwehr <cordlandwehr@kde.org>
|
|
||||||
Date: Wed, 2 Dec 2020 20:55:52 +0100
|
|
||||||
Subject: [PATCH 09/19] Ensure that grabbing is performed in correct context
|
|
||||||
|
|
||||||
For multi-display rendering on EGL, it is mandatory that the grabbing of
|
|
||||||
the surface happens in the same EGL context as the surface belongs to.
|
|
||||||
By adding the grabbing to the rendering stage of the image, this
|
|
||||||
relation is forced.
|
|
||||||
|
|
||||||
Task-number: QTBUG-87597
|
|
||||||
Change-Id: I50f40df1215aa771d714065e942c5a738ba6269f
|
|
||||||
Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io>
|
|
||||||
(cherry picked from commit ab3a1a07f3d1e0d5a9e9d97b6b3b587180e2f4c8)
|
|
||||||
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
|
|
||||||
---
|
|
||||||
src/compositor/compositor_api/qwaylandquickcompositor.cpp | 2 +-
|
|
||||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
|
||||||
|
|
||||||
diff --git a/src/compositor/compositor_api/qwaylandquickcompositor.cpp b/src/compositor/compositor_api/qwaylandquickcompositor.cpp
|
|
||||||
index 49f0860e..db1cf00f 100644
|
|
||||||
--- a/src/compositor/compositor_api/qwaylandquickcompositor.cpp
|
|
||||||
+++ b/src/compositor/compositor_api/qwaylandquickcompositor.cpp
|
|
||||||
@@ -161,7 +161,7 @@ void QWaylandQuickCompositor::grabSurface(QWaylandSurfaceGrabber *grabber, const
|
|
||||||
GrabState *state = new GrabState;
|
|
||||||
state->grabber = grabber;
|
|
||||||
state->buffer = buffer;
|
|
||||||
- static_cast<QQuickWindow *>(output->window())->scheduleRenderJob(state, QQuickWindow::NoStage);
|
|
||||||
+ static_cast<QQuickWindow *>(output->window())->scheduleRenderJob(state, QQuickWindow::AfterRenderingStage);
|
|
||||||
#else
|
|
||||||
emit grabber->failed(QWaylandSurfaceGrabber::UnknownBufferType);
|
|
||||||
#endif
|
|
||||||
--
|
|
||||||
2.31.1
|
|
||||||
|
|
||||||
77
0010-Client-Don-t-always-recreate-frame-callbacks.patch
Normal file
77
0010-Client-Don-t-always-recreate-frame-callbacks.patch
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
From 39f76fba46ff2a6bd4aca6c2abea501d56bed62e Mon Sep 17 00:00:00 2001
|
||||||
|
From: Georges Basile Stavracas Neto <gbsneto@gnome.org>
|
||||||
|
Date: Thu, 27 May 2021 19:55:04 -0300
|
||||||
|
Subject: [PATCH 10/51] Client: Don't always recreate frame callbacks
|
||||||
|
|
||||||
|
The main QWaylandWindow method that is executed when handling updates is
|
||||||
|
QWaylandWindow::handleUpdate(). This method always, unconditionally queues
|
||||||
|
a frame callback, regardless of whether any other one is already queued.
|
||||||
|
|
||||||
|
On some circumstances, e.g. when a window is hidden or completely obscured
|
||||||
|
by other windows, it stops receiving frame callbacks from the compositor.
|
||||||
|
However, QWaylandWindow would continue to request for them, which eventually
|
||||||
|
fills up the Wayland socket, and causes the application to crash.
|
||||||
|
|
||||||
|
This can be avoided by checking if the platform window is already waiting
|
||||||
|
for a frame callback, before queueing another one.
|
||||||
|
|
||||||
|
In QWaylandWindow::handleUpdate(), check if mWaitingForFrameCallback is true
|
||||||
|
before queueing frame callbacks, and early return if that's the case.
|
||||||
|
|
||||||
|
The XDG-shell test needed to be updated for this: The mock compositor is
|
||||||
|
not responding to any frame callbacks, so the window will be unexposed,
|
||||||
|
no longer get paint events and therefore not trigger any commit. This
|
||||||
|
worked by accident before because we were issuing updates quickly enough
|
||||||
|
to reset the timer before it had a chance to unexpose the window. The
|
||||||
|
easiest fix is just to disable the dependency on frame callbacks in
|
||||||
|
this test, since that is clearly not what it's testing.
|
||||||
|
|
||||||
|
Task-number: QTBUG-81504
|
||||||
|
Change-Id: Ieacb05c7d5a5fcf662243d9177ebcc308cb9ca84
|
||||||
|
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
|
||||||
|
Reviewed-by: Georges Basile Stavracas Neto <gbsneto@gnome.org>
|
||||||
|
Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io>
|
||||||
|
(cherry picked from commit cbc74ba6d7186457d8d07183272e952dee5f34f9)
|
||||||
|
---
|
||||||
|
src/client/qwaylandwindow.cpp | 4 ++++
|
||||||
|
tests/auto/client/xdgshell/tst_xdgshell.cpp | 2 ++
|
||||||
|
2 files changed, 6 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/src/client/qwaylandwindow.cpp b/src/client/qwaylandwindow.cpp
|
||||||
|
index df2dcdaa..23816895 100644
|
||||||
|
--- a/src/client/qwaylandwindow.cpp
|
||||||
|
+++ b/src/client/qwaylandwindow.cpp
|
||||||
|
@@ -1192,6 +1192,10 @@ void QWaylandWindow::requestUpdate()
|
||||||
|
void QWaylandWindow::handleUpdate()
|
||||||
|
{
|
||||||
|
qCDebug(lcWaylandBackingstore) << "handleUpdate" << QThread::currentThread();
|
||||||
|
+
|
||||||
|
+ if (mWaitingForFrameCallback)
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
// TODO: Should sync subsurfaces avoid requesting frame callbacks?
|
||||||
|
QReadLocker lock(&mSurfaceLock);
|
||||||
|
if (!mSurface)
|
||||||
|
diff --git a/tests/auto/client/xdgshell/tst_xdgshell.cpp b/tests/auto/client/xdgshell/tst_xdgshell.cpp
|
||||||
|
index 2fdd0a7c..e2593314 100644
|
||||||
|
--- a/tests/auto/client/xdgshell/tst_xdgshell.cpp
|
||||||
|
+++ b/tests/auto/client/xdgshell/tst_xdgshell.cpp
|
||||||
|
@@ -138,6 +138,7 @@ void tst_xdgshell::configureSize()
|
||||||
|
|
||||||
|
void tst_xdgshell::configureStates()
|
||||||
|
{
|
||||||
|
+ QVERIFY(qputenv("QT_WAYLAND_FRAME_CALLBACK_TIMEOUT", "0"));
|
||||||
|
QRasterWindow window;
|
||||||
|
window.resize(64, 48);
|
||||||
|
window.show();
|
||||||
|
@@ -186,6 +187,7 @@ void tst_xdgshell::configureStates()
|
||||||
|
QCOMPARE(window.windowStates(), Qt::WindowNoState);
|
||||||
|
QCOMPARE(window.frameGeometry().size(), windowedSize);
|
||||||
|
// QCOMPARE(window.frameGeometry().topLeft(), QPoint()); // TODO: this doesn't currently work when window decorations are enabled
|
||||||
|
+ QVERIFY(qunsetenv("QT_WAYLAND_FRAME_CALLBACK_TIMEOUT"));
|
||||||
|
}
|
||||||
|
|
||||||
|
void tst_xdgshell::popup()
|
||||||
|
--
|
||||||
|
2.40.1
|
||||||
|
|
||||||
@ -1,36 +0,0 @@
|
|||||||
From a8d35b3c18bdb05a0da3ed50a554a7b7bd4ebed3 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io>
|
|
||||||
Date: Mon, 30 Nov 2020 13:13:18 +0100
|
|
||||||
Subject: [PATCH 10/19] Fix leaked subsurface wayland items
|
|
||||||
|
|
||||||
Whenever a subsurface was added we would create a QWaylandQuickItem,
|
|
||||||
but this was never deleted. It is one-to-one with the surface, so it
|
|
||||||
should be deleted at the same time.
|
|
||||||
|
|
||||||
[ChangeLog][QtWaylandCompositor] Fixed a memory leak when creating
|
|
||||||
subsurfaces.
|
|
||||||
|
|
||||||
Task-number: QTBUG-88782
|
|
||||||
Change-Id: If4b3f15200ce3bd123ff73847d3593d174a39229
|
|
||||||
Reviewed-by: Paul Olav Tvete <paul.tvete@qt.io>
|
|
||||||
(cherry picked from commit 38fc568b30bf916165324c2cd2db127d2a9aa68c)
|
|
||||||
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
|
|
||||||
---
|
|
||||||
src/compositor/compositor_api/qwaylandquickitem.cpp | 1 +
|
|
||||||
1 file changed, 1 insertion(+)
|
|
||||||
|
|
||||||
diff --git a/src/compositor/compositor_api/qwaylandquickitem.cpp b/src/compositor/compositor_api/qwaylandquickitem.cpp
|
|
||||||
index 15f0195c..2218f43a 100644
|
|
||||||
--- a/src/compositor/compositor_api/qwaylandquickitem.cpp
|
|
||||||
+++ b/src/compositor/compositor_api/qwaylandquickitem.cpp
|
|
||||||
@@ -737,6 +737,7 @@ void QWaylandQuickItem::handleSubsurfaceAdded(QWaylandSurface *childSurface)
|
|
||||||
childItem->setVisible(true);
|
|
||||||
childItem->setParentItem(this);
|
|
||||||
connect(childSurface, &QWaylandSurface::subsurfacePositionChanged, childItem, &QWaylandQuickItem::handleSubsurfacePosition);
|
|
||||||
+ connect(childSurface, &QWaylandSurface::destroyed, childItem, &QObject::deleteLater);
|
|
||||||
} else {
|
|
||||||
bool success = QMetaObject::invokeMethod(d->subsurfaceHandler, "handleSubsurfaceAdded", Q_ARG(QWaylandSurface *, childSurface));
|
|
||||||
if (!success)
|
|
||||||
--
|
|
||||||
2.31.1
|
|
||||||
|
|
||||||
@ -0,0 +1,58 @@
|
|||||||
|
From c9cd53f50c71af26278589b1477c8d800c776ac1 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Georges Basile Stavracas Neto <gbsneto@gnome.org>
|
||||||
|
Date: Thu, 27 May 2021 20:02:53 -0300
|
||||||
|
Subject: [PATCH 11/51] Client: Always destroy frame callback in the actual
|
||||||
|
callback
|
||||||
|
|
||||||
|
It's good hygiene to destroy all frame callbacks. Destroy the
|
||||||
|
frame callback and cleanup the mFrameCallback class member in
|
||||||
|
the callback itself. The callback destruction happens before
|
||||||
|
calling handleFrameCallback() to avoid the theoretical case
|
||||||
|
where another frame callback is queued by handleFrameCallback(),
|
||||||
|
and then immediately destroyed in the callback handler.
|
||||||
|
|
||||||
|
* asturmlechner 2021-09-27:
|
||||||
|
Conflict resolved from non-backported commit in dev branch:
|
||||||
|
93058de8d7e7c2f320c22b3bd898aa06cf5babcd
|
||||||
|
|
||||||
|
Change-Id: Ide6dc95e3402932c58bfc088a9d471fda821e9a1
|
||||||
|
Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io>
|
||||||
|
(cherry picked from commit 42cdc61a93cf2acb09936aebb5e431fdbc0a26c6)
|
||||||
|
---
|
||||||
|
src/client/qwaylandwindow.cpp | 11 +++++------
|
||||||
|
1 file changed, 5 insertions(+), 6 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/client/qwaylandwindow.cpp b/src/client/qwaylandwindow.cpp
|
||||||
|
index 23816895..d3f28d68 100644
|
||||||
|
--- a/src/client/qwaylandwindow.cpp
|
||||||
|
+++ b/src/client/qwaylandwindow.cpp
|
||||||
|
@@ -635,9 +635,13 @@ void QWaylandWindow::commit()
|
||||||
|
|
||||||
|
const wl_callback_listener QWaylandWindow::callbackListener = {
|
||||||
|
[](void *data, wl_callback *callback, uint32_t time) {
|
||||||
|
- Q_UNUSED(callback);
|
||||||
|
Q_UNUSED(time);
|
||||||
|
auto *window = static_cast<QWaylandWindow*>(data);
|
||||||
|
+
|
||||||
|
+ Q_ASSERT(callback == window->mFrameCallback);
|
||||||
|
+ wl_callback_destroy(callback);
|
||||||
|
+ window->mFrameCallback = nullptr;
|
||||||
|
+
|
||||||
|
window->handleFrameCallback();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
@@ -1201,11 +1205,6 @@ void QWaylandWindow::handleUpdate()
|
||||||
|
if (!mSurface)
|
||||||
|
return;
|
||||||
|
|
||||||
|
- if (mFrameCallback) {
|
||||||
|
- wl_callback_destroy(mFrameCallback);
|
||||||
|
- mFrameCallback = nullptr;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
QMutexLocker locker(mFrameQueue.mutex);
|
||||||
|
struct ::wl_surface *wrappedSurface = reinterpret_cast<struct ::wl_surface *>(wl_proxy_create_wrapper(mSurface->object()));
|
||||||
|
wl_proxy_set_queue(reinterpret_cast<wl_proxy *>(wrappedSurface), mFrameQueue.queue);
|
||||||
|
--
|
||||||
|
2.40.1
|
||||||
|
|
||||||
@ -1,38 +0,0 @@
|
|||||||
From 9ee2ea141adc7765f6c212e63839ef23a4494b30 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Weng Xuetian <wengxt@gmail.com>
|
|
||||||
Date: Tue, 9 Mar 2021 10:43:59 -0800
|
|
||||||
Subject: [PATCH 11/19] 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.31.1
|
|
||||||
|
|
||||||
@ -1,38 +0,0 @@
|
|||||||
From 9df11e79b46c77d8c83f765b2a8e85b639fd55a2 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io>
|
|
||||||
Date: Tue, 5 Jan 2021 09:08:50 +0100
|
|
||||||
Subject: [PATCH 12/19] Fix memory leak in QWaylandGLContext
|
|
||||||
|
|
||||||
We were leaking an EGL context with every GL context created,
|
|
||||||
which lead to rapid OOM errors in stress tests.
|
|
||||||
|
|
||||||
[ChangeLog][Qt Wayland Client] Fixed a memory leak when creating
|
|
||||||
QOpenGLContexts on Wayland and using the wayland-egl backend.
|
|
||||||
|
|
||||||
Fixes: QTBUG-85608
|
|
||||||
Pick-to: 5.15
|
|
||||||
Pick-to: 6.0
|
|
||||||
Change-Id: I8426b5df36ec7ab9e66ce15f9e02edad3aca60b9
|
|
||||||
Reviewed-by: David Edmundson <davidedmundson@kde.org>
|
|
||||||
---
|
|
||||||
.../client/wayland-egl/qwaylandglcontext.cpp | 4 +++-
|
|
||||||
1 file changed, 3 insertions(+), 1 deletion(-)
|
|
||||||
|
|
||||||
diff --git a/src/hardwareintegration/client/wayland-egl/qwaylandglcontext.cpp b/src/hardwareintegration/client/wayland-egl/qwaylandglcontext.cpp
|
|
||||||
index 681f82f4..befadedc 100644
|
|
||||||
--- a/src/hardwareintegration/client/wayland-egl/qwaylandglcontext.cpp
|
|
||||||
+++ b/src/hardwareintegration/client/wayland-egl/qwaylandglcontext.cpp
|
|
||||||
@@ -406,7 +406,9 @@ void QWaylandGLContext::updateGLFormat()
|
|
||||||
QWaylandGLContext::~QWaylandGLContext()
|
|
||||||
{
|
|
||||||
delete m_blitter;
|
|
||||||
- eglDestroyContext(m_eglDisplay, m_context);
|
|
||||||
+ m_blitter = nullptr;
|
|
||||||
+ if (m_decorationsContext != EGL_NO_CONTEXT)
|
|
||||||
+ eglDestroyContext(eglDisplay(), m_decorationsContext);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool QWaylandGLContext::makeCurrent(QPlatformSurface *surface)
|
|
||||||
--
|
|
||||||
2.31.1
|
|
||||||
|
|
||||||
@ -1,7 +1,8 @@
|
|||||||
From cc54267e93851f067aba51cae015ca8fc3147c11 Mon Sep 17 00:00:00 2001
|
From 398c131a02d48fc9f538951f08caa93dccd03a1a Mon Sep 17 00:00:00 2001
|
||||||
From: Méven Car <meven.car@enioka.com>
|
From: =?UTF-8?q?M=C3=A9ven=20Car?= <meven.car@enioka.com>
|
||||||
Date: Wed, 18 Aug 2021 18:28:20 +0200
|
Date: Wed, 18 Aug 2021 18:28:20 +0200
|
||||||
Subject: [PATCH] Wayland client: use wl_keyboard to determine active state
|
Subject: [PATCH 12/51] Wayland client: use wl_keyboard to determine active
|
||||||
|
state
|
||||||
|
|
||||||
Commit f497a5bb87270174b8e0106b7eca1992d44ff15d made QWaylandDisplay
|
Commit f497a5bb87270174b8e0106b7eca1992d44ff15d made QWaylandDisplay
|
||||||
use the xdgshell's active state for QWindow::isActive(), instead of
|
use the xdgshell's active state for QWindow::isActive(), instead of
|
||||||
@ -24,17 +25,34 @@ We are still exposing it for decorations, which is the only reason to
|
|||||||
use the Xdghint over keyboard focus - so you can keep the toplevel
|
use the Xdghint over keyboard focus - so you can keep the toplevel
|
||||||
active whilst you show a popup.
|
active whilst you show a popup.
|
||||||
|
|
||||||
|
cherry-pick 40036a1b80e5234e6db7d5cbeff122aa7ee13e20
|
||||||
|
|
||||||
Change-Id: I4343d2ed9fb5b066cde95628ed0b4ccc84a424db
|
Change-Id: I4343d2ed9fb5b066cde95628ed0b4ccc84a424db
|
||||||
|
Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io>
|
||||||
---
|
---
|
||||||
|
src/client/qwaylanddisplay.cpp | 19 +++++++++++--------
|
||||||
|
src/client/qwaylanddisplay_p.h | 1 +
|
||||||
|
src/client/qwaylandwindow.cpp | 13 +++++++++++--
|
||||||
|
src/client/qwaylandwindow_p.h | 1 +
|
||||||
|
.../qwaylandshellintegration_p.h | 7 +++----
|
||||||
|
.../qwaylandxdgshellv5integration.cpp | 7 -------
|
||||||
|
.../qwaylandxdgshellv5integration_p.h | 1 -
|
||||||
|
.../qwaylandxdgshellv6integration.cpp | 14 --------------
|
||||||
|
.../qwaylandxdgshellv6integration_p.h | 1 -
|
||||||
|
.../xdg-shell/qwaylandxdgshell.cpp | 16 +++++-----------
|
||||||
|
.../xdg-shell/qwaylandxdgshellintegration.cpp | 14 --------------
|
||||||
|
.../xdg-shell/qwaylandxdgshellintegration_p.h | 1 -
|
||||||
|
tests/auto/client/xdgshell/tst_xdgshell.cpp | 10 +++++++---
|
||||||
|
13 files changed, 39 insertions(+), 66 deletions(-)
|
||||||
|
|
||||||
diff --git a/src/client/qwaylanddisplay.cpp b/src/client/qwaylanddisplay.cpp
|
diff --git a/src/client/qwaylanddisplay.cpp b/src/client/qwaylanddisplay.cpp
|
||||||
index e0dfe8b..2730311 100644
|
index 280e63bd..1568052e 100644
|
||||||
--- a/src/client/qwaylanddisplay.cpp
|
--- a/src/client/qwaylanddisplay.cpp
|
||||||
+++ b/src/client/qwaylanddisplay.cpp
|
+++ b/src/client/qwaylanddisplay.cpp
|
||||||
@@ -575,14 +575,10 @@ void QWaylandDisplay::handleKeyboardFocusChanged(QWaylandInputDevice *inputDevic
|
@@ -579,14 +579,10 @@ void QWaylandDisplay::handleKeyboardFocusChanged(QWaylandInputDevice *inputDevic
|
||||||
if (mLastKeyboardFocus == keyboardFocus)
|
if (mLastKeyboardFocus == keyboardFocus)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
- if (mWaylandIntegration->mShellIntegration) {
|
- if (mWaylandIntegration->mShellIntegration) {
|
||||||
- mWaylandIntegration->mShellIntegration->handleKeyboardFocusChanged(keyboardFocus, mLastKeyboardFocus);
|
- mWaylandIntegration->mShellIntegration->handleKeyboardFocusChanged(keyboardFocus, mLastKeyboardFocus);
|
||||||
- } else {
|
- } else {
|
||||||
@ -47,13 +65,13 @@ index e0dfe8b..2730311 100644
|
|||||||
+ handleWindowActivated(keyboardFocus);
|
+ handleWindowActivated(keyboardFocus);
|
||||||
+ if (mLastKeyboardFocus)
|
+ if (mLastKeyboardFocus)
|
||||||
+ handleWindowDeactivated(mLastKeyboardFocus);
|
+ handleWindowDeactivated(mLastKeyboardFocus);
|
||||||
|
|
||||||
mLastKeyboardFocus = keyboardFocus;
|
mLastKeyboardFocus = keyboardFocus;
|
||||||
}
|
}
|
||||||
@@ -627,6 +623,13 @@ QWaylandInputDevice *QWaylandDisplay::defaultInputDevice() const
|
@@ -631,6 +627,13 @@ QWaylandInputDevice *QWaylandDisplay::defaultInputDevice() const
|
||||||
return mInputDevices.isEmpty() ? 0 : mInputDevices.first();
|
return mInputDevices.isEmpty() ? 0 : mInputDevices.first();
|
||||||
}
|
}
|
||||||
|
|
||||||
+bool QWaylandDisplay::isKeyboardAvailable() const
|
+bool QWaylandDisplay::isKeyboardAvailable() const
|
||||||
+{
|
+{
|
||||||
+ return std::any_of(
|
+ return std::any_of(
|
||||||
@ -62,22 +80,22 @@ index e0dfe8b..2730311 100644
|
|||||||
+}
|
+}
|
||||||
+
|
+
|
||||||
#if QT_CONFIG(cursor)
|
#if QT_CONFIG(cursor)
|
||||||
|
|
||||||
QWaylandCursor *QWaylandDisplay::waylandCursor()
|
QWaylandCursor *QWaylandDisplay::waylandCursor()
|
||||||
diff --git a/src/client/qwaylanddisplay_p.h b/src/client/qwaylanddisplay_p.h
|
diff --git a/src/client/qwaylanddisplay_p.h b/src/client/qwaylanddisplay_p.h
|
||||||
index 3b092bc..09a1736 100644
|
index 1bad8b67..15104d65 100644
|
||||||
--- a/src/client/qwaylanddisplay_p.h
|
--- a/src/client/qwaylanddisplay_p.h
|
||||||
+++ b/src/client/qwaylanddisplay_p.h
|
+++ b/src/client/qwaylanddisplay_p.h
|
||||||
@@ -215,6 +215,7 @@ public:
|
@@ -219,6 +219,7 @@ public:
|
||||||
void destroyFrameQueue(const FrameQueue &q);
|
void destroyFrameQueue(const FrameQueue &q);
|
||||||
void dispatchQueueWhile(wl_event_queue *queue, std::function<bool()> condition, int timeout = -1);
|
void dispatchQueueWhile(wl_event_queue *queue, std::function<bool()> condition, int timeout = -1);
|
||||||
|
|
||||||
+ bool isKeyboardAvailable() const;
|
+ bool isKeyboardAvailable() const;
|
||||||
public slots:
|
public slots:
|
||||||
void blockingReadEvents();
|
void blockingReadEvents();
|
||||||
void flushRequests();
|
void flushRequests();
|
||||||
diff --git a/src/client/qwaylandwindow.cpp b/src/client/qwaylandwindow.cpp
|
diff --git a/src/client/qwaylandwindow.cpp b/src/client/qwaylandwindow.cpp
|
||||||
index e0b91dd..8d56be1 100644
|
index d3f28d68..b363c352 100644
|
||||||
--- a/src/client/qwaylandwindow.cpp
|
--- a/src/client/qwaylandwindow.cpp
|
||||||
+++ b/src/client/qwaylandwindow.cpp
|
+++ b/src/client/qwaylandwindow.cpp
|
||||||
@@ -96,7 +96,6 @@ QWaylandWindow::QWaylandWindow(QWindow *window, QWaylandDisplay *display)
|
@@ -96,7 +96,6 @@ QWaylandWindow::QWaylandWindow(QWindow *window, QWaylandDisplay *display)
|
||||||
@ -85,19 +103,27 @@ index e0b91dd..8d56be1 100644
|
|||||||
{
|
{
|
||||||
mDisplay->destroyFrameQueue(mFrameQueue);
|
mDisplay->destroyFrameQueue(mFrameQueue);
|
||||||
- mDisplay->handleWindowDestroyed(this);
|
- mDisplay->handleWindowDestroyed(this);
|
||||||
|
|
||||||
delete mWindowDecoration;
|
delete mWindowDecoration;
|
||||||
|
|
||||||
@@ -266,6 +265,8 @@ void QWaylandWindow::reset()
|
@@ -266,6 +265,8 @@ void QWaylandWindow::reset()
|
||||||
|
|
||||||
mMask = QRegion();
|
mMask = QRegion();
|
||||||
mQueuedBuffer = nullptr;
|
mQueuedBuffer = nullptr;
|
||||||
+
|
+
|
||||||
+ mDisplay->handleWindowDestroyed(this);
|
+ mDisplay->handleWindowDestroyed(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
QWaylandWindow *QWaylandWindow::fromWlSurface(::wl_surface *surface)
|
QWaylandWindow *QWaylandWindow::fromWlSurface(::wl_surface *surface)
|
||||||
@@ -1097,7 +1098,10 @@ Qt::WindowStates QWaylandWindow::windowStates() const
|
@@ -1105,10 +1106,18 @@ bool QWaylandWindow::setMouseGrabEnabled(bool grab)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
+Qt::WindowStates QWaylandWindow::windowStates() const
|
||||||
|
+{
|
||||||
|
+ return mLastReportedWindowStates;
|
||||||
|
+}
|
||||||
|
+
|
||||||
void QWaylandWindow::handleWindowStatesChanged(Qt::WindowStates states)
|
void QWaylandWindow::handleWindowStatesChanged(Qt::WindowStates states)
|
||||||
{
|
{
|
||||||
createDecoration();
|
createDecoration();
|
||||||
@ -108,32 +134,46 @@ index e0b91dd..8d56be1 100644
|
|||||||
+ lastStatesWithoutActive);
|
+ lastStatesWithoutActive);
|
||||||
mLastReportedWindowStates = states;
|
mLastReportedWindowStates = states;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
diff --git a/src/client/qwaylandwindow_p.h b/src/client/qwaylandwindow_p.h
|
||||||
|
index 01337cff..fb3ed606 100644
|
||||||
|
--- a/src/client/qwaylandwindow_p.h
|
||||||
|
+++ b/src/client/qwaylandwindow_p.h
|
||||||
|
@@ -148,6 +148,7 @@ public:
|
||||||
|
void setWindowState(Qt::WindowStates states) override;
|
||||||
|
void setWindowFlags(Qt::WindowFlags flags) override;
|
||||||
|
void handleWindowStatesChanged(Qt::WindowStates states);
|
||||||
|
+ Qt::WindowStates windowStates() const;
|
||||||
|
|
||||||
|
void raise() override;
|
||||||
|
void lower() override;
|
||||||
diff --git a/src/client/shellintegration/qwaylandshellintegration_p.h b/src/client/shellintegration/qwaylandshellintegration_p.h
|
diff --git a/src/client/shellintegration/qwaylandshellintegration_p.h b/src/client/shellintegration/qwaylandshellintegration_p.h
|
||||||
index ccad004..b308ffe 100644
|
index ccad0048..4cc9b3b8 100644
|
||||||
--- a/src/client/shellintegration/qwaylandshellintegration_p.h
|
--- a/src/client/shellintegration/qwaylandshellintegration_p.h
|
||||||
+++ b/src/client/shellintegration/qwaylandshellintegration_p.h
|
+++ b/src/client/shellintegration/qwaylandshellintegration_p.h
|
||||||
@@ -73,12 +73,6 @@ public:
|
@@ -73,11 +73,10 @@ public:
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
virtual QWaylandShellSurface *createShellSurface(QWaylandWindow *window) = 0;
|
virtual QWaylandShellSurface *createShellSurface(QWaylandWindow *window) = 0;
|
||||||
- virtual void handleKeyboardFocusChanged(QWaylandWindow *newFocus, QWaylandWindow *oldFocus) {
|
+ // kept for binary compat with layer-shell-qt
|
||||||
|
virtual void handleKeyboardFocusChanged(QWaylandWindow *newFocus, QWaylandWindow *oldFocus) {
|
||||||
- if (newFocus)
|
- if (newFocus)
|
||||||
- m_display->handleWindowActivated(newFocus);
|
- m_display->handleWindowActivated(newFocus);
|
||||||
- if (oldFocus)
|
- if (oldFocus)
|
||||||
- m_display->handleWindowDeactivated(oldFocus);
|
- m_display->handleWindowDeactivated(oldFocus);
|
||||||
- }
|
+ Q_UNUSED(newFocus);
|
||||||
|
+ Q_UNUSED(oldFocus);
|
||||||
|
}
|
||||||
virtual void *nativeResourceForWindow(const QByteArray &resource, QWindow *window) {
|
virtual void *nativeResourceForWindow(const QByteArray &resource, QWindow *window) {
|
||||||
Q_UNUSED(resource);
|
Q_UNUSED(resource);
|
||||||
Q_UNUSED(window);
|
|
||||||
diff --git a/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgshellv5integration.cpp b/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgshellv5integration.cpp
|
diff --git a/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgshellv5integration.cpp b/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgshellv5integration.cpp
|
||||||
index 4e25949..cfc6093 100644
|
index 4e25949f..cfc60939 100644
|
||||||
--- a/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgshellv5integration.cpp
|
--- a/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgshellv5integration.cpp
|
||||||
+++ b/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgshellv5integration.cpp
|
+++ b/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgshellv5integration.cpp
|
||||||
@@ -85,13 +85,6 @@ QWaylandShellSurface *QWaylandXdgShellV5Integration::createShellSurface(QWayland
|
@@ -85,13 +85,6 @@ QWaylandShellSurface *QWaylandXdgShellV5Integration::createShellSurface(QWayland
|
||||||
return m_xdgShell->createXdgSurface(window);
|
return m_xdgShell->createXdgSurface(window);
|
||||||
}
|
}
|
||||||
|
|
||||||
-void QWaylandXdgShellV5Integration::handleKeyboardFocusChanged(QWaylandWindow *newFocus, QWaylandWindow *oldFocus) {
|
-void QWaylandXdgShellV5Integration::handleKeyboardFocusChanged(QWaylandWindow *newFocus, QWaylandWindow *oldFocus) {
|
||||||
- if (newFocus && qobject_cast<QWaylandXdgPopupV5 *>(newFocus->shellSurface()))
|
- if (newFocus && qobject_cast<QWaylandXdgPopupV5 *>(newFocus->shellSurface()))
|
||||||
- m_display->handleWindowActivated(newFocus);
|
- m_display->handleWindowActivated(newFocus);
|
||||||
@ -142,10 +182,10 @@ index 4e25949..cfc6093 100644
|
|||||||
-}
|
-}
|
||||||
-
|
-
|
||||||
}
|
}
|
||||||
|
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
diff --git a/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgshellv5integration_p.h b/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgshellv5integration_p.h
|
diff --git a/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgshellv5integration_p.h b/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgshellv5integration_p.h
|
||||||
index ce6bdb9..aed8867 100644
|
index ce6bdb9e..aed88670 100644
|
||||||
--- a/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgshellv5integration_p.h
|
--- a/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgshellv5integration_p.h
|
||||||
+++ b/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgshellv5integration_p.h
|
+++ b/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgshellv5integration_p.h
|
||||||
@@ -67,7 +67,6 @@ public:
|
@@ -67,7 +67,6 @@ public:
|
||||||
@ -153,17 +193,17 @@ index ce6bdb9..aed8867 100644
|
|||||||
bool initialize(QWaylandDisplay *display) override;
|
bool initialize(QWaylandDisplay *display) override;
|
||||||
QWaylandShellSurface *createShellSurface(QWaylandWindow *window) override;
|
QWaylandShellSurface *createShellSurface(QWaylandWindow *window) override;
|
||||||
- void handleKeyboardFocusChanged(QWaylandWindow *newFocus, QWaylandWindow *oldFocus) override;
|
- void handleKeyboardFocusChanged(QWaylandWindow *newFocus, QWaylandWindow *oldFocus) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QScopedPointer<QWaylandXdgShellV5> m_xdgShell;
|
QScopedPointer<QWaylandXdgShellV5> m_xdgShell;
|
||||||
diff --git a/src/plugins/shellintegration/xdg-shell-v6/qwaylandxdgshellv6integration.cpp b/src/plugins/shellintegration/xdg-shell-v6/qwaylandxdgshellv6integration.cpp
|
diff --git a/src/plugins/shellintegration/xdg-shell-v6/qwaylandxdgshellv6integration.cpp b/src/plugins/shellintegration/xdg-shell-v6/qwaylandxdgshellv6integration.cpp
|
||||||
index 0316431..e8da8ba 100644
|
index 03164316..e8da8ba1 100644
|
||||||
--- a/src/plugins/shellintegration/xdg-shell-v6/qwaylandxdgshellv6integration.cpp
|
--- a/src/plugins/shellintegration/xdg-shell-v6/qwaylandxdgshellv6integration.cpp
|
||||||
+++ b/src/plugins/shellintegration/xdg-shell-v6/qwaylandxdgshellv6integration.cpp
|
+++ b/src/plugins/shellintegration/xdg-shell-v6/qwaylandxdgshellv6integration.cpp
|
||||||
@@ -68,20 +68,6 @@ QWaylandShellSurface *QWaylandXdgShellV6Integration::createShellSurface(QWayland
|
@@ -68,20 +68,6 @@ QWaylandShellSurface *QWaylandXdgShellV6Integration::createShellSurface(QWayland
|
||||||
return m_xdgShell->getXdgSurface(window);
|
return m_xdgShell->getXdgSurface(window);
|
||||||
}
|
}
|
||||||
|
|
||||||
-void QWaylandXdgShellV6Integration::handleKeyboardFocusChanged(QWaylandWindow *newFocus, QWaylandWindow *oldFocus)
|
-void QWaylandXdgShellV6Integration::handleKeyboardFocusChanged(QWaylandWindow *newFocus, QWaylandWindow *oldFocus)
|
||||||
-{
|
-{
|
||||||
- if (newFocus) {
|
- if (newFocus) {
|
||||||
@ -179,10 +219,10 @@ index 0316431..e8da8ba 100644
|
|||||||
-}
|
-}
|
||||||
-
|
-
|
||||||
}
|
}
|
||||||
|
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
diff --git a/src/plugins/shellintegration/xdg-shell-v6/qwaylandxdgshellv6integration_p.h b/src/plugins/shellintegration/xdg-shell-v6/qwaylandxdgshellv6integration_p.h
|
diff --git a/src/plugins/shellintegration/xdg-shell-v6/qwaylandxdgshellv6integration_p.h b/src/plugins/shellintegration/xdg-shell-v6/qwaylandxdgshellv6integration_p.h
|
||||||
index 261f8cb..c1bcd5c 100644
|
index 261f8cbb..c1bcd5c6 100644
|
||||||
--- a/src/plugins/shellintegration/xdg-shell-v6/qwaylandxdgshellv6integration_p.h
|
--- a/src/plugins/shellintegration/xdg-shell-v6/qwaylandxdgshellv6integration_p.h
|
||||||
+++ b/src/plugins/shellintegration/xdg-shell-v6/qwaylandxdgshellv6integration_p.h
|
+++ b/src/plugins/shellintegration/xdg-shell-v6/qwaylandxdgshellv6integration_p.h
|
||||||
@@ -65,7 +65,6 @@ public:
|
@@ -65,7 +65,6 @@ public:
|
||||||
@ -190,15 +230,15 @@ index 261f8cb..c1bcd5c 100644
|
|||||||
bool initialize(QWaylandDisplay *display) override;
|
bool initialize(QWaylandDisplay *display) override;
|
||||||
QWaylandShellSurface *createShellSurface(QWaylandWindow *window) override;
|
QWaylandShellSurface *createShellSurface(QWaylandWindow *window) override;
|
||||||
- void handleKeyboardFocusChanged(QWaylandWindow *newFocus, QWaylandWindow *oldFocus) override;
|
- void handleKeyboardFocusChanged(QWaylandWindow *newFocus, QWaylandWindow *oldFocus) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QScopedPointer<QWaylandXdgShellV6> m_xdgShell;
|
QScopedPointer<QWaylandXdgShellV6> m_xdgShell;
|
||||||
diff --git a/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp b/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp
|
diff --git a/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp b/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp
|
||||||
index cf7eb4e..2c6e84b 100644
|
index c3d2d3ea..9a362b74 100644
|
||||||
--- a/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp
|
--- a/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp
|
||||||
+++ b/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp
|
+++ b/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp
|
||||||
@@ -67,11 +67,6 @@ QWaylandXdgSurface::Toplevel::Toplevel(QWaylandXdgSurface *xdgSurface)
|
@@ -67,11 +67,6 @@ QWaylandXdgSurface::Toplevel::Toplevel(QWaylandXdgSurface *xdgSurface)
|
||||||
|
|
||||||
QWaylandXdgSurface::Toplevel::~Toplevel()
|
QWaylandXdgSurface::Toplevel::~Toplevel()
|
||||||
{
|
{
|
||||||
- if (m_applied.states & Qt::WindowActive) {
|
- if (m_applied.states & Qt::WindowActive) {
|
||||||
@ -209,37 +249,36 @@ index cf7eb4e..2c6e84b 100644
|
|||||||
// The protocol spec requires that the decoration object is deleted before xdg_toplevel.
|
// The protocol spec requires that the decoration object is deleted before xdg_toplevel.
|
||||||
delete m_decoration;
|
delete m_decoration;
|
||||||
m_decoration = nullptr;
|
m_decoration = nullptr;
|
||||||
@@ -85,17 +80,16 @@ void QWaylandXdgSurface::Toplevel::applyConfigure()
|
@@ -85,16 +80,15 @@ void QWaylandXdgSurface::Toplevel::applyConfigure()
|
||||||
if (!(m_applied.states & (Qt::WindowMaximized|Qt::WindowFullScreen)))
|
if (!(m_applied.states & (Qt::WindowMaximized|Qt::WindowFullScreen)))
|
||||||
m_normalSize = m_xdgSurface->m_window->windowFrameGeometry().size();
|
m_normalSize = m_xdgSurface->m_window->windowFrameGeometry().size();
|
||||||
|
|
||||||
- if ((m_pending.states & Qt::WindowActive) && !(m_applied.states & Qt::WindowActive))
|
- if ((m_pending.states & Qt::WindowActive) && !(m_applied.states & Qt::WindowActive))
|
||||||
+ if ((m_pending.states & Qt::WindowActive) && !(m_applied.states & Qt::WindowActive)
|
+ if ((m_pending.states & Qt::WindowActive) && !(m_applied.states & Qt::WindowActive)
|
||||||
+ && !m_xdgSurface->m_window->display()->isKeyboardAvailable())
|
+ && !m_xdgSurface->m_window->display()->isKeyboardAvailable())
|
||||||
m_xdgSurface->m_window->display()->handleWindowActivated(m_xdgSurface->m_window);
|
m_xdgSurface->m_window->display()->handleWindowActivated(m_xdgSurface->m_window);
|
||||||
|
|
||||||
- if (!(m_pending.states & Qt::WindowActive) && (m_applied.states & Qt::WindowActive))
|
- if (!(m_pending.states & Qt::WindowActive) && (m_applied.states & Qt::WindowActive))
|
||||||
+ if (!(m_pending.states & Qt::WindowActive) && (m_applied.states & Qt::WindowActive)
|
+ if (!(m_pending.states & Qt::WindowActive) && (m_applied.states & Qt::WindowActive)
|
||||||
+ && !m_xdgSurface->m_window->display()->isKeyboardAvailable())
|
+ && !m_xdgSurface->m_window->display()->isKeyboardAvailable())
|
||||||
m_xdgSurface->m_window->display()->handleWindowDeactivated(m_xdgSurface->m_window);
|
m_xdgSurface->m_window->display()->handleWindowDeactivated(m_xdgSurface->m_window);
|
||||||
|
|
||||||
- // TODO: none of the other plugins send WindowActive either, but is it on purpose?
|
- // TODO: none of the other plugins send WindowActive either, but is it on purpose?
|
||||||
- Qt::WindowStates statesWithoutActive = m_pending.states & ~Qt::WindowActive;
|
- Qt::WindowStates statesWithoutActive = m_pending.states & ~Qt::WindowActive;
|
||||||
-
|
-
|
||||||
m_xdgSurface->m_window->handleToplevelWindowTilingStatesChanged(m_toplevelStates);
|
|
||||||
- m_xdgSurface->m_window->handleWindowStatesChanged(statesWithoutActive);
|
- m_xdgSurface->m_window->handleWindowStatesChanged(statesWithoutActive);
|
||||||
+ m_xdgSurface->m_window->handleWindowStatesChanged(m_pending.states);
|
+ m_xdgSurface->m_window->handleWindowStatesChanged(m_pending.states);
|
||||||
|
|
||||||
if (m_pending.size.isEmpty()) {
|
if (m_pending.size.isEmpty()) {
|
||||||
// An empty size in the configure means it's up to the client to choose the size
|
// An empty size in the configure means it's up to the client to choose the size
|
||||||
diff --git a/src/plugins/shellintegration/xdg-shell/qwaylandxdgshellintegration.cpp b/src/plugins/shellintegration/xdg-shell/qwaylandxdgshellintegration.cpp
|
diff --git a/src/plugins/shellintegration/xdg-shell/qwaylandxdgshellintegration.cpp b/src/plugins/shellintegration/xdg-shell/qwaylandxdgshellintegration.cpp
|
||||||
index 8769d97..da0dd6a 100644
|
index 8769d971..da0dd6a7 100644
|
||||||
--- a/src/plugins/shellintegration/xdg-shell/qwaylandxdgshellintegration.cpp
|
--- a/src/plugins/shellintegration/xdg-shell/qwaylandxdgshellintegration.cpp
|
||||||
+++ b/src/plugins/shellintegration/xdg-shell/qwaylandxdgshellintegration.cpp
|
+++ b/src/plugins/shellintegration/xdg-shell/qwaylandxdgshellintegration.cpp
|
||||||
@@ -69,20 +69,6 @@ QWaylandShellSurface *QWaylandXdgShellIntegration::createShellSurface(QWaylandWi
|
@@ -69,20 +69,6 @@ QWaylandShellSurface *QWaylandXdgShellIntegration::createShellSurface(QWaylandWi
|
||||||
return m_xdgShell->getXdgSurface(window);
|
return m_xdgShell->getXdgSurface(window);
|
||||||
}
|
}
|
||||||
|
|
||||||
-void QWaylandXdgShellIntegration::handleKeyboardFocusChanged(QWaylandWindow *newFocus, QWaylandWindow *oldFocus)
|
-void QWaylandXdgShellIntegration::handleKeyboardFocusChanged(QWaylandWindow *newFocus, QWaylandWindow *oldFocus)
|
||||||
-{
|
-{
|
||||||
- if (newFocus) {
|
- if (newFocus) {
|
||||||
@ -255,10 +294,10 @@ index 8769d97..da0dd6a 100644
|
|||||||
-}
|
-}
|
||||||
-
|
-
|
||||||
}
|
}
|
||||||
|
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
diff --git a/src/plugins/shellintegration/xdg-shell/qwaylandxdgshellintegration_p.h b/src/plugins/shellintegration/xdg-shell/qwaylandxdgshellintegration_p.h
|
diff --git a/src/plugins/shellintegration/xdg-shell/qwaylandxdgshellintegration_p.h b/src/plugins/shellintegration/xdg-shell/qwaylandxdgshellintegration_p.h
|
||||||
index b6caa6c..2f929f9 100644
|
index b6caa6c9..2f929f98 100644
|
||||||
--- a/src/plugins/shellintegration/xdg-shell/qwaylandxdgshellintegration_p.h
|
--- a/src/plugins/shellintegration/xdg-shell/qwaylandxdgshellintegration_p.h
|
||||||
+++ b/src/plugins/shellintegration/xdg-shell/qwaylandxdgshellintegration_p.h
|
+++ b/src/plugins/shellintegration/xdg-shell/qwaylandxdgshellintegration_p.h
|
||||||
@@ -65,7 +65,6 @@ public:
|
@@ -65,7 +65,6 @@ public:
|
||||||
@ -266,11 +305,11 @@ index b6caa6c..2f929f9 100644
|
|||||||
bool initialize(QWaylandDisplay *display) override;
|
bool initialize(QWaylandDisplay *display) override;
|
||||||
QWaylandShellSurface *createShellSurface(QWaylandWindow *window) override;
|
QWaylandShellSurface *createShellSurface(QWaylandWindow *window) override;
|
||||||
- void handleKeyboardFocusChanged(QWaylandWindow *newFocus, QWaylandWindow *oldFocus) override;
|
- void handleKeyboardFocusChanged(QWaylandWindow *newFocus, QWaylandWindow *oldFocus) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QScopedPointer<QWaylandXdgShell> m_xdgShell;
|
QScopedPointer<QWaylandXdgShell> m_xdgShell;
|
||||||
diff --git a/tests/auto/client/xdgshell/tst_xdgshell.cpp b/tests/auto/client/xdgshell/tst_xdgshell.cpp
|
diff --git a/tests/auto/client/xdgshell/tst_xdgshell.cpp b/tests/auto/client/xdgshell/tst_xdgshell.cpp
|
||||||
index 2fdd0a7..5346b6e 100644
|
index e2593314..73d1eb9c 100644
|
||||||
--- a/tests/auto/client/xdgshell/tst_xdgshell.cpp
|
--- a/tests/auto/client/xdgshell/tst_xdgshell.cpp
|
||||||
+++ b/tests/auto/client/xdgshell/tst_xdgshell.cpp
|
+++ b/tests/auto/client/xdgshell/tst_xdgshell.cpp
|
||||||
@@ -31,6 +31,7 @@
|
@@ -31,6 +31,7 @@
|
||||||
@ -278,13 +317,13 @@ index 2fdd0a7..5346b6e 100644
|
|||||||
#include <QtGui/qpa/qplatformnativeinterface.h>
|
#include <QtGui/qpa/qplatformnativeinterface.h>
|
||||||
#include <QtWaylandClient/private/wayland-wayland-client-protocol.h>
|
#include <QtWaylandClient/private/wayland-wayland-client-protocol.h>
|
||||||
+#include <QtWaylandClient/private/qwaylandwindow_p.h>
|
+#include <QtWaylandClient/private/qwaylandwindow_p.h>
|
||||||
|
|
||||||
using namespace MockCompositor;
|
using namespace MockCompositor;
|
||||||
|
|
||||||
@@ -154,9 +155,12 @@ void tst_xdgshell::configureStates()
|
@@ -155,9 +156,12 @@ void tst_xdgshell::configureStates()
|
||||||
// Toplevel windows don't know their position on xdg-shell
|
// Toplevel windows don't know their position on xdg-shell
|
||||||
// QCOMPARE(window.frameGeometry().topLeft(), QPoint()); // TODO: this doesn't currently work when window decorations are enabled
|
// QCOMPARE(window.frameGeometry().topLeft(), QPoint()); // TODO: this doesn't currently work when window decorations are enabled
|
||||||
|
|
||||||
-// QEXPECT_FAIL("", "configure has already been acked, we shouldn't have to wait for isActive", Continue);
|
-// QEXPECT_FAIL("", "configure has already been acked, we shouldn't have to wait for isActive", Continue);
|
||||||
-// QVERIFY(window.isActive());
|
-// QVERIFY(window.isActive());
|
||||||
- QTRY_VERIFY(window.isActive()); // Just make sure it eventually get's set correctly
|
- QTRY_VERIFY(window.isActive()); // Just make sure it eventually get's set correctly
|
||||||
@ -294,6 +333,9 @@ index 2fdd0a7..5346b6e 100644
|
|||||||
+ Q_ASSERT(waylandWindow);
|
+ Q_ASSERT(waylandWindow);
|
||||||
+ QTRY_VERIFY(waylandWindow->windowStates().testFlag(
|
+ QTRY_VERIFY(waylandWindow->windowStates().testFlag(
|
||||||
+ Qt::WindowActive)); // Just make sure it eventually get's set correctly
|
+ Qt::WindowActive)); // Just make sure it eventually get's set correctly
|
||||||
|
|
||||||
const QSize screenSize(640, 480);
|
const QSize screenSize(640, 480);
|
||||||
const uint maximizedSerial = exec([=] {
|
const uint maximizedSerial = exec([=] {
|
||||||
|
--
|
||||||
|
2.40.1
|
||||||
|
|
||||||
@ -1,41 +0,0 @@
|
|||||||
From 7db4f83c39d2a0c709bc0b9c0de3946d3b4ebfd5 Mon Sep 17 00:00:00 2001
|
|
||||||
From: David Edmundson <davidedmundson@kde.org>
|
|
||||||
Date: Mon, 16 Nov 2020 14:57:36 +0000
|
|
||||||
Subject: [PATCH 13/19] Client: Send set_window_geometry only once configured
|
|
||||||
|
|
||||||
The geometry only makes sense when a buffer exists, our currently send
|
|
||||||
value is somewhat meaningless, but till now harmless.
|
|
||||||
|
|
||||||
A specification clarification implies that it is an error if the
|
|
||||||
calculated effective window geometry is null, rather than just checking
|
|
||||||
the sent value. This is the case if set_window_geometry is sent before a
|
|
||||||
buffer is attached.
|
|
||||||
|
|
||||||
On our first configure call we enter resizeFromApplyConfigure which will
|
|
||||||
hit this path and send the initial state.
|
|
||||||
|
|
||||||
Pick-to: 5.15
|
|
||||||
Pick-to: 6.1
|
|
||||||
Pick-to: 6.0
|
|
||||||
Change-Id: Ib57ebe8b64210eae86e79dfdd6b5cb8a986b020b
|
|
||||||
Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io>
|
|
||||||
---
|
|
||||||
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 9b343702..e875af3a 100644
|
|
||||||
--- a/src/client/qwaylandwindow.cpp
|
|
||||||
+++ b/src/client/qwaylandwindow.cpp
|
|
||||||
@@ -365,7 +365,7 @@ void QWaylandWindow::setGeometry(const QRect &rect)
|
|
||||||
if (isExposed() && !mInResizeFromApplyConfigure && exposeGeometry != mLastExposeGeometry)
|
|
||||||
sendExposeEvent(exposeGeometry);
|
|
||||||
|
|
||||||
- if (mShellSurface)
|
|
||||||
+ if (mShellSurface && isExposed())
|
|
||||||
mShellSurface->setWindowGeometry(windowContentGeometry());
|
|
||||||
|
|
||||||
if (isOpaque() && mMask.isEmpty())
|
|
||||||
--
|
|
||||||
2.31.1
|
|
||||||
|
|
||||||
@ -1,7 +1,8 @@
|
|||||||
From 5ac39d2d76735c5d1d28a16f7fbc8b28e39886dd Mon Sep 17 00:00:00 2001
|
From 4cbf15b311fd9b00b28205e474c4b31a92ab819d Mon Sep 17 00:00:00 2001
|
||||||
From: Jan Grulich <jgrulich@redhat.com>
|
From: Jan Grulich <jgrulich@redhat.com>
|
||||||
Date: Fri, 16 Jul 2021 13:00:03 +0200
|
Date: Fri, 16 Jul 2021 13:00:03 +0200
|
||||||
Subject: [PATCH] Client: do not empty clipboard when a new popup/window is opened
|
Subject: [PATCH 13/51] Client: do not empty clipboard when a new popup/window
|
||||||
|
is opened
|
||||||
|
|
||||||
If we open a new popup or a window within the same app we have to avoid
|
If we open a new popup or a window within the same app we have to avoid
|
||||||
invalidating selection offer when losing focus, because it's still the
|
invalidating selection offer when losing focus, because it's still the
|
||||||
@ -9,15 +10,21 @@ same client who has the focus and we might not get a new selection offer
|
|||||||
by the compositor and therefore we would lose clipboard content.
|
by the compositor and therefore we would lose clipboard content.
|
||||||
|
|
||||||
Fixes: QTBUG-93474
|
Fixes: QTBUG-93474
|
||||||
Pick-to: 6.2 5.15
|
|
||||||
Change-Id: Ia2ef826c2967b1daf1cdeb085e8dae66d090dbcf
|
Change-Id: Ia2ef826c2967b1daf1cdeb085e8dae66d090dbcf
|
||||||
|
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
|
||||||
|
Reviewed-by: David Edmundson <davidedmundson@kde.org>
|
||||||
|
|
||||||
|
Cherry-pick: 1e57ebd501cfc2255300392cd4565cd034efeed8
|
||||||
---
|
---
|
||||||
|
src/client/qwaylanddisplay.cpp | 13 +++++++++++++
|
||||||
|
src/client/qwaylandinputdevice.cpp | 8 --------
|
||||||
|
2 files changed, 13 insertions(+), 8 deletions(-)
|
||||||
|
|
||||||
diff --git a/src/client/qwaylanddisplay.cpp b/src/client/qwaylanddisplay.cpp
|
diff --git a/src/client/qwaylanddisplay.cpp b/src/client/qwaylanddisplay.cpp
|
||||||
index 2730311..9f595af 100644
|
index 1568052e..aa8808e9 100644
|
||||||
--- a/src/client/qwaylanddisplay.cpp
|
--- a/src/client/qwaylanddisplay.cpp
|
||||||
+++ b/src/client/qwaylanddisplay.cpp
|
+++ b/src/client/qwaylanddisplay.cpp
|
||||||
@@ -597,6 +597,19 @@ void QWaylandDisplay::handleWaylandSync()
|
@@ -601,6 +601,19 @@ void QWaylandDisplay::handleWaylandSync()
|
||||||
QWindow *activeWindow = mActiveWindows.empty() ? nullptr : mActiveWindows.last()->window();
|
QWindow *activeWindow = mActiveWindows.empty() ? nullptr : mActiveWindows.last()->window();
|
||||||
if (activeWindow != QGuiApplication::focusWindow())
|
if (activeWindow != QGuiApplication::focusWindow())
|
||||||
QWindowSystemInterface::handleWindowActivated(activeWindow);
|
QWindowSystemInterface::handleWindowActivated(activeWindow);
|
||||||
@ -35,13 +42,13 @@ index 2730311..9f595af 100644
|
|||||||
+ }
|
+ }
|
||||||
+ }
|
+ }
|
||||||
}
|
}
|
||||||
|
|
||||||
const wl_callback_listener QWaylandDisplay::syncCallbackListener = {
|
const wl_callback_listener QWaylandDisplay::syncCallbackListener = {
|
||||||
diff --git a/src/client/qwaylandinputdevice.cpp b/src/client/qwaylandinputdevice.cpp
|
diff --git a/src/client/qwaylandinputdevice.cpp b/src/client/qwaylandinputdevice.cpp
|
||||||
index ae045f4..514457e 100644
|
index e931d1f5..5d704795 100644
|
||||||
--- a/src/client/qwaylandinputdevice.cpp
|
--- a/src/client/qwaylandinputdevice.cpp
|
||||||
+++ b/src/client/qwaylandinputdevice.cpp
|
+++ b/src/client/qwaylandinputdevice.cpp
|
||||||
@@ -1300,14 +1300,6 @@ void QWaylandInputDevice::Keyboard::handleFocusDestroyed()
|
@@ -1304,14 +1304,6 @@ void QWaylandInputDevice::Keyboard::handleFocusDestroyed()
|
||||||
void QWaylandInputDevice::Keyboard::handleFocusLost()
|
void QWaylandInputDevice::Keyboard::handleFocusLost()
|
||||||
{
|
{
|
||||||
mFocus = nullptr;
|
mFocus = nullptr;
|
||||||
@ -56,3 +63,6 @@ index ae045f4..514457e 100644
|
|||||||
mParent->mQDisplay->handleKeyboardFocusChanged(mParent);
|
mParent->mQDisplay->handleKeyboardFocusChanged(mParent);
|
||||||
mRepeatTimer.stop();
|
mRepeatTimer.stop();
|
||||||
}
|
}
|
||||||
|
--
|
||||||
|
2.40.1
|
||||||
|
|
||||||
513
0014-Client-Implement-DataDeviceV3.patch
Normal file
513
0014-Client-Implement-DataDeviceV3.patch
Normal file
@ -0,0 +1,513 @@
|
|||||||
|
From 52f362f8dfd27a65cdee945ba923ae30521ab922 Mon Sep 17 00:00:00 2001
|
||||||
|
From: David Edmundson <davidedmundson@kde.org>
|
||||||
|
Date: Tue, 16 Feb 2021 09:51:47 +0000
|
||||||
|
Subject: [PATCH 14/51] Client: Implement DataDeviceV3
|
||||||
|
|
||||||
|
DataDeviceV2 fixes a leak of DataDevice resources.
|
||||||
|
|
||||||
|
DataDeviceV3 brings multiple improvements:
|
||||||
|
|
||||||
|
Action negotiation. The source announces which actions are supported,
|
||||||
|
the target then announces which subset of those action the target
|
||||||
|
supports and a preferred action. After negotiation both the source and
|
||||||
|
target are notified of which action is to be performed.
|
||||||
|
|
||||||
|
Drag sources are now notified when contents are dropped and when a
|
||||||
|
client has finished with the drag and drop operation.
|
||||||
|
|
||||||
|
A good test is the draggableicons example in QtBase.
|
||||||
|
|
||||||
|
Change-Id: I55e9759ca5a2e4218d02d863144a64ade53ef764
|
||||||
|
Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io>
|
||||||
|
(cherry picked from commit 283a2d61d03315495a52d82f356e7cb5292f4bb4)
|
||||||
|
---
|
||||||
|
src/client/qwaylanddatadevice.cpp | 84 ++++++++++++++-----
|
||||||
|
src/client/qwaylanddatadevice_p.h | 8 +-
|
||||||
|
src/client/qwaylanddatadevicemanager.cpp | 4 +-
|
||||||
|
src/client/qwaylanddatadevicemanager_p.h | 2 +-
|
||||||
|
src/client/qwaylanddataoffer.cpp | 25 ++++++
|
||||||
|
src/client/qwaylanddataoffer_p.h | 4 +
|
||||||
|
src/client/qwaylanddatasource.cpp | 27 +++++-
|
||||||
|
src/client/qwaylanddatasource_p.h | 10 ++-
|
||||||
|
src/client/qwaylanddisplay.cpp | 2 +-
|
||||||
|
src/client/qwaylanddnd.cpp | 24 +++---
|
||||||
|
src/client/qwaylanddnd_p.h | 7 +-
|
||||||
|
.../client/datadevicev1/tst_datadevicev1.cpp | 2 +-
|
||||||
|
12 files changed, 153 insertions(+), 46 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/client/qwaylanddatadevice.cpp b/src/client/qwaylanddatadevice.cpp
|
||||||
|
index bbd2d568..fbb5aa91 100644
|
||||||
|
--- a/src/client/qwaylanddatadevice.cpp
|
||||||
|
+++ b/src/client/qwaylanddatadevice.cpp
|
||||||
|
@@ -72,6 +72,8 @@ QWaylandDataDevice::QWaylandDataDevice(QWaylandDataDeviceManager *manager, QWayl
|
||||||
|
|
||||||
|
QWaylandDataDevice::~QWaylandDataDevice()
|
||||||
|
{
|
||||||
|
+ if (wl_data_device_get_version(object()) >= WL_DATA_DEVICE_RELEASE_SINCE_VERSION)
|
||||||
|
+ release();
|
||||||
|
}
|
||||||
|
|
||||||
|
QWaylandDataOffer *QWaylandDataDevice::selectionOffer() const
|
||||||
|
@@ -110,7 +112,7 @@ QWaylandDataOffer *QWaylandDataDevice::dragOffer() const
|
||||||
|
return m_dragOffer.data();
|
||||||
|
}
|
||||||
|
|
||||||
|
-bool QWaylandDataDevice::startDrag(QMimeData *mimeData, QWaylandWindow *icon)
|
||||||
|
+bool QWaylandDataDevice::startDrag(QMimeData *mimeData, Qt::DropActions supportedActions, QWaylandWindow *icon)
|
||||||
|
{
|
||||||
|
auto *seat = m_display->currentInputDevice();
|
||||||
|
auto *origin = seat->pointerFocus();
|
||||||
|
@@ -123,8 +125,28 @@ bool QWaylandDataDevice::startDrag(QMimeData *mimeData, QWaylandWindow *icon)
|
||||||
|
}
|
||||||
|
|
||||||
|
m_dragSource.reset(new QWaylandDataSource(m_display->dndSelectionHandler(), mimeData));
|
||||||
|
+
|
||||||
|
+ if (wl_data_device_get_version(object()) >= 3)
|
||||||
|
+ m_dragSource->set_actions(dropActionsToWl(supportedActions));
|
||||||
|
+
|
||||||
|
connect(m_dragSource.data(), &QWaylandDataSource::cancelled, this, &QWaylandDataDevice::dragSourceCancelled);
|
||||||
|
- connect(m_dragSource.data(), &QWaylandDataSource::targetChanged, this, &QWaylandDataDevice::dragSourceTargetChanged);
|
||||||
|
+ connect(m_dragSource.data(), &QWaylandDataSource::dndResponseUpdated, this, [this](bool accepted, Qt::DropAction action) {
|
||||||
|
+ auto drag = static_cast<QWaylandDrag *>(QGuiApplicationPrivate::platformIntegration()->drag());
|
||||||
|
+ // in old versions drop action is not set, so we guess
|
||||||
|
+ if (wl_data_source_get_version(m_dragSource->object()) < 3) {
|
||||||
|
+ drag->setResponse(accepted);
|
||||||
|
+ } else {
|
||||||
|
+ QPlatformDropQtResponse response(accepted, action);
|
||||||
|
+ drag->setResponse(response);
|
||||||
|
+ }
|
||||||
|
+ });
|
||||||
|
+ connect(m_dragSource.data(), &QWaylandDataSource::dndDropped, this, [](bool accepted, Qt::DropAction action) {
|
||||||
|
+ QPlatformDropQtResponse response(accepted, action);
|
||||||
|
+ static_cast<QWaylandDrag *>(QGuiApplicationPrivate::platformIntegration()->drag())->setDropResponse(response);
|
||||||
|
+ });
|
||||||
|
+ connect(m_dragSource.data(), &QWaylandDataSource::finished, this, []() {
|
||||||
|
+ static_cast<QWaylandDrag *>(QGuiApplicationPrivate::platformIntegration()->drag())->finishDrag();
|
||||||
|
+ });
|
||||||
|
|
||||||
|
start_drag(m_dragSource->object(), origin->wlSurface(), icon->wlSurface(), m_display->currentInputDevice()->serial());
|
||||||
|
return true;
|
||||||
|
@@ -153,7 +175,7 @@ void QWaylandDataDevice::data_device_drop()
|
||||||
|
supportedActions = drag->supportedActions();
|
||||||
|
} else if (m_dragOffer) {
|
||||||
|
dragData = m_dragOffer->mimeData();
|
||||||
|
- supportedActions = Qt::CopyAction | Qt::MoveAction | Qt::LinkAction;
|
||||||
|
+ supportedActions = m_dragOffer->supportedActions();
|
||||||
|
} else {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
@@ -163,7 +185,11 @@ void QWaylandDataDevice::data_device_drop()
|
||||||
|
QGuiApplication::keyboardModifiers());
|
||||||
|
|
||||||
|
if (drag) {
|
||||||
|
- static_cast<QWaylandDrag *>(QGuiApplicationPrivate::platformIntegration()->drag())->finishDrag(response);
|
||||||
|
+ auto drag = static_cast<QWaylandDrag *>(QGuiApplicationPrivate::platformIntegration()->drag());
|
||||||
|
+ drag->setDropResponse(response);
|
||||||
|
+ drag->finishDrag();
|
||||||
|
+ } else if (m_dragOffer) {
|
||||||
|
+ m_dragOffer->finish();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -187,7 +213,7 @@ void QWaylandDataDevice::data_device_enter(uint32_t serial, wl_surface *surface,
|
||||||
|
supportedActions = drag->supportedActions();
|
||||||
|
} else if (m_dragOffer) {
|
||||||
|
dragData = m_dragOffer->mimeData();
|
||||||
|
- supportedActions = Qt::CopyAction | Qt::MoveAction | Qt::LinkAction;
|
||||||
|
+ supportedActions = m_dragOffer->supportedActions();
|
||||||
|
}
|
||||||
|
|
||||||
|
const QPlatformDragQtResponse &response = QWindowSystemInterface::handleDrag(m_dragWindow, dragData, m_dragPoint, supportedActions,
|
||||||
|
@@ -198,11 +224,7 @@ void QWaylandDataDevice::data_device_enter(uint32_t serial, wl_surface *surface,
|
||||||
|
static_cast<QWaylandDrag *>(QGuiApplicationPrivate::platformIntegration()->drag())->setResponse(response);
|
||||||
|
}
|
||||||
|
|
||||||
|
- if (response.isAccepted()) {
|
||||||
|
- wl_data_offer_accept(m_dragOffer->object(), m_enterSerial, m_dragOffer->firstFormat().toUtf8().constData());
|
||||||
|
- } else {
|
||||||
|
- wl_data_offer_accept(m_dragOffer->object(), m_enterSerial, nullptr);
|
||||||
|
- }
|
||||||
|
+ sendResponse(supportedActions, response);
|
||||||
|
}
|
||||||
|
|
||||||
|
void QWaylandDataDevice::data_device_leave()
|
||||||
|
@@ -236,10 +258,10 @@ void QWaylandDataDevice::data_device_motion(uint32_t time, wl_fixed_t x, wl_fixe
|
||||||
|
supportedActions = drag->supportedActions();
|
||||||
|
} else {
|
||||||
|
dragData = m_dragOffer->mimeData();
|
||||||
|
- supportedActions = Qt::CopyAction | Qt::MoveAction | Qt::LinkAction;
|
||||||
|
+ supportedActions = m_dragOffer->supportedActions();
|
||||||
|
}
|
||||||
|
|
||||||
|
- QPlatformDragQtResponse response = QWindowSystemInterface::handleDrag(m_dragWindow, dragData, m_dragPoint, supportedActions,
|
||||||
|
+ const QPlatformDragQtResponse response = QWindowSystemInterface::handleDrag(m_dragWindow, dragData, m_dragPoint, supportedActions,
|
||||||
|
QGuiApplication::mouseButtons(),
|
||||||
|
QGuiApplication::keyboardModifiers());
|
||||||
|
|
||||||
|
@@ -247,11 +269,7 @@ void QWaylandDataDevice::data_device_motion(uint32_t time, wl_fixed_t x, wl_fixe
|
||||||
|
static_cast<QWaylandDrag *>(QGuiApplicationPrivate::platformIntegration()->drag())->setResponse(response);
|
||||||
|
}
|
||||||
|
|
||||||
|
- if (response.isAccepted()) {
|
||||||
|
- wl_data_offer_accept(m_dragOffer->object(), m_enterSerial, m_dragOffer->firstFormat().toUtf8().constData());
|
||||||
|
- } else {
|
||||||
|
- wl_data_offer_accept(m_dragOffer->object(), m_enterSerial, nullptr);
|
||||||
|
- }
|
||||||
|
+ sendResponse(supportedActions, response);
|
||||||
|
}
|
||||||
|
#endif // QT_CONFIG(draganddrop)
|
||||||
|
|
||||||
|
@@ -281,11 +299,6 @@ void QWaylandDataDevice::dragSourceCancelled()
|
||||||
|
m_dragSource.reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
-void QWaylandDataDevice::dragSourceTargetChanged(const QString &mimeType)
|
||||||
|
-{
|
||||||
|
- static_cast<QWaylandDrag *>(QGuiApplicationPrivate::platformIntegration()->drag())->updateTarget(mimeType);
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
QPoint QWaylandDataDevice::calculateDragPosition(int x, int y, QWindow *wnd) const
|
||||||
|
{
|
||||||
|
QPoint pnt(wl_fixed_to_int(x), wl_fixed_to_int(y));
|
||||||
|
@@ -298,6 +311,33 @@ QPoint QWaylandDataDevice::calculateDragPosition(int x, int y, QWindow *wnd) con
|
||||||
|
}
|
||||||
|
return pnt;
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+void QWaylandDataDevice::sendResponse(Qt::DropActions supportedActions, const QPlatformDragQtResponse &response)
|
||||||
|
+{
|
||||||
|
+ if (response.isAccepted()) {
|
||||||
|
+ if (wl_data_device_get_version(object()) >= 3)
|
||||||
|
+ m_dragOffer->set_actions(dropActionsToWl(supportedActions), dropActionsToWl(response.acceptedAction()));
|
||||||
|
+
|
||||||
|
+ m_dragOffer->accept(m_enterSerial, m_dragOffer->firstFormat());
|
||||||
|
+ } else {
|
||||||
|
+ m_dragOffer->accept(m_enterSerial, QString());
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+int QWaylandDataDevice::dropActionsToWl(Qt::DropActions actions)
|
||||||
|
+{
|
||||||
|
+
|
||||||
|
+ int wlActions = WL_DATA_DEVICE_MANAGER_DND_ACTION_NONE;
|
||||||
|
+ if (actions & Qt::CopyAction)
|
||||||
|
+ wlActions |= WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY;
|
||||||
|
+ if (actions & (Qt::MoveAction | Qt::TargetMoveAction))
|
||||||
|
+ wlActions |= WL_DATA_DEVICE_MANAGER_DND_ACTION_MOVE;
|
||||||
|
+
|
||||||
|
+ // wayland does not support LinkAction at the time of writing
|
||||||
|
+ return wlActions;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+
|
||||||
|
#endif // QT_CONFIG(draganddrop)
|
||||||
|
|
||||||
|
}
|
||||||
|
diff --git a/src/client/qwaylanddatadevice_p.h b/src/client/qwaylanddatadevice_p.h
|
||||||
|
index 16c3ad28..801dcc2c 100644
|
||||||
|
--- a/src/client/qwaylanddatadevice_p.h
|
||||||
|
+++ b/src/client/qwaylanddatadevice_p.h
|
||||||
|
@@ -64,6 +64,7 @@ QT_REQUIRE_CONFIG(wayland_datadevice);
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
class QMimeData;
|
||||||
|
+class QPlatformDragQtResponse;
|
||||||
|
class QWindow;
|
||||||
|
|
||||||
|
namespace QtWaylandClient {
|
||||||
|
@@ -89,7 +90,7 @@ public:
|
||||||
|
|
||||||
|
#if QT_CONFIG(draganddrop)
|
||||||
|
QWaylandDataOffer *dragOffer() const;
|
||||||
|
- bool startDrag(QMimeData *mimeData, QWaylandWindow *icon);
|
||||||
|
+ bool startDrag(QMimeData *mimeData, Qt::DropActions supportedActions, QWaylandWindow *icon);
|
||||||
|
void cancelDrag();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
@@ -109,13 +110,16 @@ private Q_SLOTS:
|
||||||
|
|
||||||
|
#if QT_CONFIG(draganddrop)
|
||||||
|
void dragSourceCancelled();
|
||||||
|
- void dragSourceTargetChanged(const QString &mimeType);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
private:
|
||||||
|
#if QT_CONFIG(draganddrop)
|
||||||
|
QPoint calculateDragPosition(int x, int y, QWindow *wnd) const;
|
||||||
|
#endif
|
||||||
|
+ void sendResponse(Qt::DropActions supportedActions, const QPlatformDragQtResponse &response);
|
||||||
|
+
|
||||||
|
+ static int dropActionsToWl(Qt::DropActions dropActions);
|
||||||
|
+
|
||||||
|
|
||||||
|
QWaylandDisplay *m_display = nullptr;
|
||||||
|
QWaylandInputDevice *m_inputDevice = nullptr;
|
||||||
|
diff --git a/src/client/qwaylanddatadevicemanager.cpp b/src/client/qwaylanddatadevicemanager.cpp
|
||||||
|
index 35d67307..6dc4f77f 100644
|
||||||
|
--- a/src/client/qwaylanddatadevicemanager.cpp
|
||||||
|
+++ b/src/client/qwaylanddatadevicemanager.cpp
|
||||||
|
@@ -50,8 +50,8 @@ QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
namespace QtWaylandClient {
|
||||||
|
|
||||||
|
-QWaylandDataDeviceManager::QWaylandDataDeviceManager(QWaylandDisplay *display, uint32_t id)
|
||||||
|
- : wl_data_device_manager(display->wl_registry(), id, 1)
|
||||||
|
+QWaylandDataDeviceManager::QWaylandDataDeviceManager(QWaylandDisplay *display, int version, uint32_t id)
|
||||||
|
+ : wl_data_device_manager(display->wl_registry(), id, qMin(version, 3))
|
||||||
|
, m_display(display)
|
||||||
|
{
|
||||||
|
// Create transfer devices for all input devices.
|
||||||
|
diff --git a/src/client/qwaylanddatadevicemanager_p.h b/src/client/qwaylanddatadevicemanager_p.h
|
||||||
|
index bd05c0fb..510d9be4 100644
|
||||||
|
--- a/src/client/qwaylanddatadevicemanager_p.h
|
||||||
|
+++ b/src/client/qwaylanddatadevicemanager_p.h
|
||||||
|
@@ -68,7 +68,7 @@ class QWaylandInputDevice;
|
||||||
|
class Q_WAYLAND_CLIENT_EXPORT QWaylandDataDeviceManager : public QtWayland::wl_data_device_manager
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
- QWaylandDataDeviceManager(QWaylandDisplay *display, uint32_t id);
|
||||||
|
+ QWaylandDataDeviceManager(QWaylandDisplay *display, int version, uint32_t id);
|
||||||
|
~QWaylandDataDeviceManager() override;
|
||||||
|
|
||||||
|
QWaylandDataDevice *getDataDevice(QWaylandInputDevice *inputDevice);
|
||||||
|
diff --git a/src/client/qwaylanddataoffer.cpp b/src/client/qwaylanddataoffer.cpp
|
||||||
|
index 2297e8a1..c9e158cc 100644
|
||||||
|
--- a/src/client/qwaylanddataoffer.cpp
|
||||||
|
+++ b/src/client/qwaylanddataoffer.cpp
|
||||||
|
@@ -82,6 +82,15 @@ QMimeData *QWaylandDataOffer::mimeData()
|
||||||
|
return m_mimeData.data();
|
||||||
|
}
|
||||||
|
|
||||||
|
+Qt::DropActions QWaylandDataOffer::supportedActions() const
|
||||||
|
+{
|
||||||
|
+ if (wl_data_offer_get_version(const_cast<::wl_data_offer*>(object())) < 3) {
|
||||||
|
+ return Qt::MoveAction | Qt::CopyAction;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return m_supportedActions;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
void QWaylandDataOffer::startReceiving(const QString &mimeType, int fd)
|
||||||
|
{
|
||||||
|
receive(mimeType, fd);
|
||||||
|
@@ -93,6 +102,22 @@ void QWaylandDataOffer::data_offer_offer(const QString &mime_type)
|
||||||
|
m_mimeData->appendFormat(mime_type);
|
||||||
|
}
|
||||||
|
|
||||||
|
+void QWaylandDataOffer::data_offer_action(uint32_t dnd_action)
|
||||||
|
+{
|
||||||
|
+ Q_UNUSED(dnd_action);
|
||||||
|
+ // This is the compositor telling the drag target what action it should perform
|
||||||
|
+ // It does not map nicely into Qt final drop semantics, other than pretending there is only one supported action?
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+void QWaylandDataOffer::data_offer_source_actions(uint32_t source_actions)
|
||||||
|
+{
|
||||||
|
+ m_supportedActions = Qt::DropActions();
|
||||||
|
+ if (source_actions & WL_DATA_DEVICE_MANAGER_DND_ACTION_MOVE)
|
||||||
|
+ m_supportedActions |= Qt::MoveAction;
|
||||||
|
+ if (source_actions & WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY)
|
||||||
|
+ m_supportedActions |= Qt::CopyAction;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
QWaylandMimeData::QWaylandMimeData(QWaylandAbstractDataOffer *dataOffer)
|
||||||
|
: m_dataOffer(dataOffer)
|
||||||
|
{
|
||||||
|
diff --git a/src/client/qwaylanddataoffer_p.h b/src/client/qwaylanddataoffer_p.h
|
||||||
|
index 9cf1483c..6f667398 100644
|
||||||
|
--- a/src/client/qwaylanddataoffer_p.h
|
||||||
|
+++ b/src/client/qwaylanddataoffer_p.h
|
||||||
|
@@ -82,6 +82,7 @@ public:
|
||||||
|
explicit QWaylandDataOffer(QWaylandDisplay *display, struct ::wl_data_offer *offer);
|
||||||
|
~QWaylandDataOffer() override;
|
||||||
|
QMimeData *mimeData() override;
|
||||||
|
+ Qt::DropActions supportedActions() const;
|
||||||
|
|
||||||
|
QString firstFormat() const;
|
||||||
|
|
||||||
|
@@ -89,10 +90,13 @@ public:
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void data_offer_offer(const QString &mime_type) override;
|
||||||
|
+ void data_offer_source_actions(uint32_t source_actions) override;
|
||||||
|
+ void data_offer_action(uint32_t dnd_action) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
QWaylandDisplay *m_display = nullptr;
|
||||||
|
QScopedPointer<QWaylandMimeData> m_mimeData;
|
||||||
|
+ Qt::DropActions m_supportedActions;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
diff --git a/src/client/qwaylanddatasource.cpp b/src/client/qwaylanddatasource.cpp
|
||||||
|
index f45122fb..5599cbd4 100644
|
||||||
|
--- a/src/client/qwaylanddatasource.cpp
|
||||||
|
+++ b/src/client/qwaylanddatasource.cpp
|
||||||
|
@@ -101,7 +101,32 @@ void QWaylandDataSource::data_source_send(const QString &mime_type, int32_t fd)
|
||||||
|
|
||||||
|
void QWaylandDataSource::data_source_target(const QString &mime_type)
|
||||||
|
{
|
||||||
|
- Q_EMIT targetChanged(mime_type);
|
||||||
|
+ m_accepted = !mime_type.isEmpty();
|
||||||
|
+ Q_EMIT dndResponseUpdated(m_accepted, m_dropAction);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+void QWaylandDataSource::data_source_action(uint32_t action)
|
||||||
|
+{
|
||||||
|
+ Qt::DropAction qtAction = Qt::IgnoreAction;
|
||||||
|
+
|
||||||
|
+ if (action == WL_DATA_DEVICE_MANAGER_DND_ACTION_MOVE)
|
||||||
|
+ qtAction = Qt::MoveAction;
|
||||||
|
+ else if (action == WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY)
|
||||||
|
+ qtAction = Qt::CopyAction;
|
||||||
|
+
|
||||||
|
+ m_dropAction = qtAction;
|
||||||
|
+ Q_EMIT dndResponseUpdated(m_accepted, m_dropAction);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+void QWaylandDataSource::data_source_dnd_finished()
|
||||||
|
+{
|
||||||
|
+ Q_EMIT finished();
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+void QWaylandDataSource::data_source_dnd_drop_performed()
|
||||||
|
+{
|
||||||
|
+
|
||||||
|
+ Q_EMIT dndDropped(m_accepted, m_dropAction);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
diff --git a/src/client/qwaylanddatasource_p.h b/src/client/qwaylanddatasource_p.h
|
||||||
|
index 25afff79..96f07bc3 100644
|
||||||
|
--- a/src/client/qwaylanddatasource_p.h
|
||||||
|
+++ b/src/client/qwaylanddatasource_p.h
|
||||||
|
@@ -77,17 +77,25 @@ public:
|
||||||
|
QMimeData *mimeData() const;
|
||||||
|
|
||||||
|
Q_SIGNALS:
|
||||||
|
- void targetChanged(const QString &mime_type);
|
||||||
|
void cancelled();
|
||||||
|
+ void finished();
|
||||||
|
+
|
||||||
|
+ void dndResponseUpdated(bool accepted, Qt::DropAction action);
|
||||||
|
+ void dndDropped(bool accepted, Qt::DropAction action);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void data_source_cancelled() override;
|
||||||
|
void data_source_send(const QString &mime_type, int32_t fd) override;
|
||||||
|
void data_source_target(const QString &mime_type) override;
|
||||||
|
+ void data_source_dnd_drop_performed() override;
|
||||||
|
+ void data_source_dnd_finished() override;
|
||||||
|
+ void data_source_action(uint32_t action) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
QWaylandDisplay *m_display = nullptr;
|
||||||
|
QMimeData *m_mime_data = nullptr;
|
||||||
|
+ bool m_accepted = false;
|
||||||
|
+ Qt::DropAction m_dropAction = Qt::IgnoreAction;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
diff --git a/src/client/qwaylanddisplay.cpp b/src/client/qwaylanddisplay.cpp
|
||||||
|
index aa8808e9..2d298532 100644
|
||||||
|
--- a/src/client/qwaylanddisplay.cpp
|
||||||
|
+++ b/src/client/qwaylanddisplay.cpp
|
||||||
|
@@ -356,7 +356,7 @@ void QWaylandDisplay::registry_global(uint32_t id, const QString &interface, uin
|
||||||
|
mInputDevices.append(inputDevice);
|
||||||
|
#if QT_CONFIG(wayland_datadevice)
|
||||||
|
} else if (interface == QStringLiteral("wl_data_device_manager")) {
|
||||||
|
- mDndSelectionHandler.reset(new QWaylandDataDeviceManager(this, id));
|
||||||
|
+ mDndSelectionHandler.reset(new QWaylandDataDeviceManager(this, version, id));
|
||||||
|
#endif
|
||||||
|
} else if (interface == QStringLiteral("qt_surface_extension")) {
|
||||||
|
mWindowExtension.reset(new QtWayland::qt_surface_extension(registry, id, 1));
|
||||||
|
diff --git a/src/client/qwaylanddnd.cpp b/src/client/qwaylanddnd.cpp
|
||||||
|
index 6535aa16..97ee5b2e 100644
|
||||||
|
--- a/src/client/qwaylanddnd.cpp
|
||||||
|
+++ b/src/client/qwaylanddnd.cpp
|
||||||
|
@@ -66,7 +66,7 @@ void QWaylandDrag::startDrag()
|
||||||
|
{
|
||||||
|
QBasicDrag::startDrag();
|
||||||
|
QWaylandWindow *icon = static_cast<QWaylandWindow *>(shapedPixmapWindow()->handle());
|
||||||
|
- if (m_display->currentInputDevice()->dataDevice()->startDrag(drag()->mimeData(), icon)) {
|
||||||
|
+ if (m_display->currentInputDevice()->dataDevice()->startDrag(drag()->mimeData(), drag()->supportedActions(), icon)) {
|
||||||
|
icon->addAttachOffset(-drag()->hotSpot());
|
||||||
|
} else {
|
||||||
|
// Cancelling immediately does not work, since the event loop for QDrag::exec is started
|
||||||
|
@@ -103,31 +103,31 @@ void QWaylandDrag::endDrag()
|
||||||
|
m_display->currentInputDevice()->handleEndDrag();
|
||||||
|
}
|
||||||
|
|
||||||
|
-void QWaylandDrag::updateTarget(const QString &mimeType)
|
||||||
|
+void QWaylandDrag::setResponse(bool accepted)
|
||||||
|
{
|
||||||
|
- setCanDrop(!mimeType.isEmpty());
|
||||||
|
-
|
||||||
|
- if (canDrop()) {
|
||||||
|
- updateCursor(defaultAction(drag()->supportedActions(), m_display->currentInputDevice()->modifiers()));
|
||||||
|
- } else {
|
||||||
|
- updateCursor(Qt::IgnoreAction);
|
||||||
|
- }
|
||||||
|
+ // This method is used for old DataDevices where the drag action is not communicated
|
||||||
|
+ Qt::DropAction action = defaultAction(drag()->supportedActions(), m_display->currentInputDevice()->modifiers());
|
||||||
|
+ setResponse(QPlatformDropQtResponse(accepted, action));
|
||||||
|
}
|
||||||
|
|
||||||
|
-void QWaylandDrag::setResponse(const QPlatformDragQtResponse &response)
|
||||||
|
+void QWaylandDrag::setResponse(const QPlatformDropQtResponse &response)
|
||||||
|
{
|
||||||
|
setCanDrop(response.isAccepted());
|
||||||
|
|
||||||
|
if (canDrop()) {
|
||||||
|
- updateCursor(defaultAction(drag()->supportedActions(), m_display->currentInputDevice()->modifiers()));
|
||||||
|
+ updateCursor(response.acceptedAction());
|
||||||
|
} else {
|
||||||
|
updateCursor(Qt::IgnoreAction);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
-void QWaylandDrag::finishDrag(const QPlatformDropQtResponse &response)
|
||||||
|
+void QWaylandDrag::setDropResponse(const QPlatformDropQtResponse &response)
|
||||||
|
{
|
||||||
|
setExecutedDropAction(response.acceptedAction());
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+void QWaylandDrag::finishDrag()
|
||||||
|
+{
|
||||||
|
QKeyEvent event(QEvent::KeyPress, Qt::Key_Escape, Qt::NoModifier);
|
||||||
|
eventFilter(shapedPixmapWindow(), &event);
|
||||||
|
}
|
||||||
|
diff --git a/src/client/qwaylanddnd_p.h b/src/client/qwaylanddnd_p.h
|
||||||
|
index 474fe2ab..747f0190 100644
|
||||||
|
--- a/src/client/qwaylanddnd_p.h
|
||||||
|
+++ b/src/client/qwaylanddnd_p.h
|
||||||
|
@@ -71,9 +71,10 @@ public:
|
||||||
|
QWaylandDrag(QWaylandDisplay *display);
|
||||||
|
~QWaylandDrag() override;
|
||||||
|
|
||||||
|
- void updateTarget(const QString &mimeType);
|
||||||
|
- void setResponse(const QPlatformDragQtResponse &response);
|
||||||
|
- void finishDrag(const QPlatformDropQtResponse &response);
|
||||||
|
+ void setResponse(bool accepted);
|
||||||
|
+ void setResponse(const QPlatformDropQtResponse &response);
|
||||||
|
+ void setDropResponse(const QPlatformDropQtResponse &response);
|
||||||
|
+ void finishDrag();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void startDrag() override;
|
||||||
|
diff --git a/tests/auto/client/datadevicev1/tst_datadevicev1.cpp b/tests/auto/client/datadevicev1/tst_datadevicev1.cpp
|
||||||
|
index 1568b3b9..067410d0 100644
|
||||||
|
--- a/tests/auto/client/datadevicev1/tst_datadevicev1.cpp
|
||||||
|
+++ b/tests/auto/client/datadevicev1/tst_datadevicev1.cpp
|
||||||
|
@@ -35,7 +35,7 @@
|
||||||
|
|
||||||
|
using namespace MockCompositor;
|
||||||
|
|
||||||
|
-constexpr int dataDeviceVersion = 1;
|
||||||
|
+constexpr int dataDeviceVersion = 3;
|
||||||
|
|
||||||
|
class DataDeviceCompositor : public DefaultCompositor {
|
||||||
|
public:
|
||||||
|
--
|
||||||
|
2.40.1
|
||||||
|
|
||||||
@ -1,40 +0,0 @@
|
|||||||
From a3e3ac1c86a956b25b1dc24f14518b6e6c96bcfc Mon Sep 17 00:00:00 2001
|
|
||||||
From: Jan Grulich <jgrulich@redhat.com>
|
|
||||||
Date: Wed, 10 Feb 2021 17:11:27 +0100
|
|
||||||
Subject: [PATCH 14/19] 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.31.1
|
|
||||||
|
|
||||||
@ -0,0 +1,67 @@
|
|||||||
|
From b29079669153d7b1894fc13b2cd8c6de1ad5471a Mon Sep 17 00:00:00 2001
|
||||||
|
From: Arjen Hiemstra <ahiemstra@heimr.nl>
|
||||||
|
Date: Thu, 18 Nov 2021 13:05:30 +0100
|
||||||
|
Subject: [PATCH 15/51] Client: Delay deletion of QDrag object until after
|
||||||
|
we're done with it
|
||||||
|
|
||||||
|
In certain cases, most notably when performing drag and drop operations
|
||||||
|
with touch, the QDrag object gets deleted before data_source_send is
|
||||||
|
executed. This then tries to access a deleted data_source, crashing the
|
||||||
|
client.
|
||||||
|
|
||||||
|
To avoid this, we indicate we want the QDrag object to stay around and
|
||||||
|
then delete it in QWaylandDrag::finishDrag, which with data_device v3 is
|
||||||
|
guaranteed to be called after everyone is done with the data source.
|
||||||
|
|
||||||
|
Change-Id: I6a2f5a219f58d1b721a9fec33c57d26d2c522ec9
|
||||||
|
Reviewed-by: David Edmundson <davidedmundson@kde.org>
|
||||||
|
(cherry picked from commit 39e3290efa2dd40722fa3322284cae3b01ccedf4)
|
||||||
|
---
|
||||||
|
src/client/qwaylanddnd.cpp | 11 +++++++++++
|
||||||
|
src/client/qwaylanddnd_p.h | 1 +
|
||||||
|
2 files changed, 12 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/src/client/qwaylanddnd.cpp b/src/client/qwaylanddnd.cpp
|
||||||
|
index 97ee5b2e..7c53f5fa 100644
|
||||||
|
--- a/src/client/qwaylanddnd.cpp
|
||||||
|
+++ b/src/client/qwaylanddnd.cpp
|
||||||
|
@@ -80,6 +80,9 @@ void QWaylandDrag::cancel()
|
||||||
|
QBasicDrag::cancel();
|
||||||
|
|
||||||
|
m_display->currentInputDevice()->dataDevice()->cancelDrag();
|
||||||
|
+
|
||||||
|
+ if (drag())
|
||||||
|
+ drag()->deleteLater();
|
||||||
|
}
|
||||||
|
|
||||||
|
void QWaylandDrag::move(const QPoint &globalPos, Qt::MouseButtons b, Qt::KeyboardModifiers mods)
|
||||||
|
@@ -130,6 +133,14 @@ void QWaylandDrag::finishDrag()
|
||||||
|
{
|
||||||
|
QKeyEvent event(QEvent::KeyPress, Qt::Key_Escape, Qt::NoModifier);
|
||||||
|
eventFilter(shapedPixmapWindow(), &event);
|
||||||
|
+
|
||||||
|
+ if (drag())
|
||||||
|
+ drag()->deleteLater();
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+bool QWaylandDrag::ownsDragObject() const
|
||||||
|
+{
|
||||||
|
+ return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
diff --git a/src/client/qwaylanddnd_p.h b/src/client/qwaylanddnd_p.h
|
||||||
|
index 747f0190..46f629ac 100644
|
||||||
|
--- a/src/client/qwaylanddnd_p.h
|
||||||
|
+++ b/src/client/qwaylanddnd_p.h
|
||||||
|
@@ -83,6 +83,7 @@ protected:
|
||||||
|
void drop(const QPoint &globalPos, Qt::MouseButtons b, Qt::KeyboardModifiers mods) override;
|
||||||
|
void endDrag() override;
|
||||||
|
|
||||||
|
+ bool ownsDragObject() const override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
QWaylandDisplay *m_display = nullptr;
|
||||||
|
--
|
||||||
|
2.40.1
|
||||||
|
|
||||||
@ -1,97 +0,0 @@
|
|||||||
From 2073ff99e62d4f99ed3f1f45559c5b68a61c5f66 Mon Sep 17 00:00:00 2001
|
|
||||||
From: David Edmundson <davidedmundson@kde.org>
|
|
||||||
Date: Mon, 14 Sep 2020 17:08:39 +0100
|
|
||||||
Subject: [PATCH 15/19] 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.31.1
|
|
||||||
|
|
||||||
@ -0,0 +1,38 @@
|
|||||||
|
From fde475c6e235429e7af64a54b9d81e893c618af7 Mon Sep 17 00:00:00 2001
|
||||||
|
From: David Edmundson <davidedmundson@kde.org>
|
||||||
|
Date: Sun, 14 Nov 2021 13:54:19 +0000
|
||||||
|
Subject: [PATCH 16/51] Client: Avoid processing of events when showing windows
|
||||||
|
|
||||||
|
The only time we want to dispatch events from the wayland socket is when
|
||||||
|
the application is waiting for external events. Doing so at any other
|
||||||
|
time will cause unpredictable behavior in client code.
|
||||||
|
|
||||||
|
This caused a crash downstream where we had outputs get altered whilst
|
||||||
|
itterating through outputs, which shouldn't happen.
|
||||||
|
|
||||||
|
There is no benefit to flushing here, it won't make anything appear
|
||||||
|
faster as we haven't attached the buffer yet.
|
||||||
|
|
||||||
|
Change-Id: Ie13eae4012dab96a93d8810f468d1343402b8c28
|
||||||
|
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
|
||||||
|
Reviewed-by: Aleix Pol Gonzalez <aleixpol@kde.org>
|
||||||
|
(cherry picked from commit 46ed85a80b28d519cf5887bbdce55d1bf57886c3)
|
||||||
|
---
|
||||||
|
src/client/qwaylandwindow.cpp | 1 -
|
||||||
|
1 file changed, 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/src/client/qwaylandwindow.cpp b/src/client/qwaylandwindow.cpp
|
||||||
|
index b363c352..b98435ed 100644
|
||||||
|
--- a/src/client/qwaylandwindow.cpp
|
||||||
|
+++ b/src/client/qwaylandwindow.cpp
|
||||||
|
@@ -437,7 +437,6 @@ void QWaylandWindow::setVisible(bool visible)
|
||||||
|
if (window()->type() == Qt::Popup || window()->type() == Qt::ToolTip)
|
||||||
|
activePopups << this;
|
||||||
|
initWindow();
|
||||||
|
- mDisplay->flushRequests();
|
||||||
|
|
||||||
|
setGeometry(windowGeometry());
|
||||||
|
// Don't flush the events here, or else the newly visible window may start drawing, but since
|
||||||
|
--
|
||||||
|
2.40.1
|
||||||
|
|
||||||
@ -1,39 +0,0 @@
|
|||||||
From 6810b0f66a34056bfe0da7299d7a768e700e58f5 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Jan Grulich <jgrulich@redhat.com>
|
|
||||||
Date: Thu, 11 Feb 2021 15:12:32 +0100
|
|
||||||
Subject: [PATCH 16/19] 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.31.1
|
|
||||||
|
|
||||||
85
0017-Handle-registry_global-out-of-constructor.patch
Normal file
85
0017-Handle-registry_global-out-of-constructor.patch
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
From f22c2639663d9b9010fd79a5873e11a716106b65 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Elvis Lee <kwangwoong.lee@lge.com>
|
||||||
|
Date: Thu, 18 Feb 2021 15:45:49 +0900
|
||||||
|
Subject: [PATCH 17/51] Handle registry_global out of constructor
|
||||||
|
|
||||||
|
Factory functions in QWaylandDisplay::registry_global() can be overridden.
|
||||||
|
Later, other classes instantiated in the registry_global can support
|
||||||
|
platform specific implementation with inheritance and some factory function.
|
||||||
|
|
||||||
|
Change-Id: I92ce574e049b8c91587687cc7c30611f3dfdbe56
|
||||||
|
Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io>
|
||||||
|
(cherry picked from commit 3793a82038682db77966ea5daf8e75964e4250fe)
|
||||||
|
---
|
||||||
|
src/client/qwaylanddisplay.cpp | 19 ++++++++++++-------
|
||||||
|
src/client/qwaylanddisplay_p.h | 2 ++
|
||||||
|
src/client/qwaylandintegration.cpp | 3 +++
|
||||||
|
3 files changed, 17 insertions(+), 7 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/client/qwaylanddisplay.cpp b/src/client/qwaylanddisplay.cpp
|
||||||
|
index 2d298532..97fb8cbe 100644
|
||||||
|
--- a/src/client/qwaylanddisplay.cpp
|
||||||
|
+++ b/src/client/qwaylanddisplay.cpp
|
||||||
|
@@ -160,13 +160,6 @@ QWaylandDisplay::QWaylandDisplay(QWaylandIntegration *waylandIntegration)
|
||||||
|
if (!mXkbContext)
|
||||||
|
qCWarning(lcQpaWayland, "failed to create xkb context");
|
||||||
|
#endif
|
||||||
|
-
|
||||||
|
- forceRoundTrip();
|
||||||
|
-
|
||||||
|
- if (!mWaitingScreens.isEmpty()) {
|
||||||
|
- // Give wl_output.done and zxdg_output_v1.done events a chance to arrive
|
||||||
|
- forceRoundTrip();
|
||||||
|
- }
|
||||||
|
}
|
||||||
|
|
||||||
|
QWaylandDisplay::~QWaylandDisplay(void)
|
||||||
|
@@ -191,6 +184,18 @@ QWaylandDisplay::~QWaylandDisplay(void)
|
||||||
|
wl_display_disconnect(mDisplay);
|
||||||
|
}
|
||||||
|
|
||||||
|
+// Steps which is called just after constructor. This separates registry_global() out of the constructor
|
||||||
|
+// so that factory functions in integration can be overridden.
|
||||||
|
+void QWaylandDisplay::initialize()
|
||||||
|
+{
|
||||||
|
+ forceRoundTrip();
|
||||||
|
+
|
||||||
|
+ if (!mWaitingScreens.isEmpty()) {
|
||||||
|
+ // Give wl_output.done and zxdg_output_v1.done events a chance to arrive
|
||||||
|
+ forceRoundTrip();
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
void QWaylandDisplay::ensureScreen()
|
||||||
|
{
|
||||||
|
if (!mScreens.empty() || mPlaceholderScreen)
|
||||||
|
diff --git a/src/client/qwaylanddisplay_p.h b/src/client/qwaylanddisplay_p.h
|
||||||
|
index 15104d65..49820255 100644
|
||||||
|
--- a/src/client/qwaylanddisplay_p.h
|
||||||
|
+++ b/src/client/qwaylanddisplay_p.h
|
||||||
|
@@ -131,6 +131,8 @@ public:
|
||||||
|
QWaylandDisplay(QWaylandIntegration *waylandIntegration);
|
||||||
|
~QWaylandDisplay(void) override;
|
||||||
|
|
||||||
|
+ void initialize();
|
||||||
|
+
|
||||||
|
#if QT_CONFIG(xkbcommon)
|
||||||
|
struct xkb_context *xkbContext() const { return mXkbContext.get(); }
|
||||||
|
#endif
|
||||||
|
diff --git a/src/client/qwaylandintegration.cpp b/src/client/qwaylandintegration.cpp
|
||||||
|
index cd8569b1..8afecb31 100644
|
||||||
|
--- a/src/client/qwaylandintegration.cpp
|
||||||
|
+++ b/src/client/qwaylandintegration.cpp
|
||||||
|
@@ -200,6 +200,9 @@ void QWaylandIntegration::initialize()
|
||||||
|
QSocketNotifier *sn = new QSocketNotifier(fd, QSocketNotifier::Read, mDisplay.data());
|
||||||
|
QObject::connect(sn, SIGNAL(activated(QSocketDescriptor)), mDisplay.data(), SLOT(flushRequests()));
|
||||||
|
|
||||||
|
+ // Call after eventDispatcher is fully connected, for QWaylandDisplay::forceRoundTrip()
|
||||||
|
+ mDisplay->initialize();
|
||||||
|
+
|
||||||
|
// Qt does not support running with no screens
|
||||||
|
mDisplay->ensureScreen();
|
||||||
|
}
|
||||||
|
--
|
||||||
|
2.40.1
|
||||||
|
|
||||||
@ -1,41 +0,0 @@
|
|||||||
From cea69b8adec1e61adc1fa04cbf46b77c0d72c75e Mon Sep 17 00:00:00 2001
|
|
||||||
From: Aleix Pol <aleixpol@kde.org>
|
|
||||||
Date: Mon, 23 Nov 2020 20:07:02 +0100
|
|
||||||
Subject: [PATCH 17/19] 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.31.1
|
|
||||||
|
|
||||||
47
0018-Connect-flushRequest-after-forceRoundTrip.patch
Normal file
47
0018-Connect-flushRequest-after-forceRoundTrip.patch
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
From 192b3af086ecca973109be4e169a601af434239a Mon Sep 17 00:00:00 2001
|
||||||
|
From: Elvis Lee <kwangwoong.lee@lge.com>
|
||||||
|
Date: Wed, 17 Mar 2021 16:31:10 +0900
|
||||||
|
Subject: [PATCH 18/51] Connect flushRequest after forceRoundTrip
|
||||||
|
|
||||||
|
If flushRequest is connected with aboutToBlock, the flushRequest
|
||||||
|
may consumes all events so that processEvents might be blocked in forceRoundTrip.
|
||||||
|
|
||||||
|
Change-Id: I12b2c506e8442bf0e75f6ab6e418d3e1eea6d68c
|
||||||
|
Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io>
|
||||||
|
(cherry picked from commit 654a54755138c520c3a41210d8078196e9a2c1bf)
|
||||||
|
---
|
||||||
|
src/client/qwaylandintegration.cpp | 11 +++++++----
|
||||||
|
1 file changed, 7 insertions(+), 4 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/client/qwaylandintegration.cpp b/src/client/qwaylandintegration.cpp
|
||||||
|
index 8afecb31..661cea53 100644
|
||||||
|
--- a/src/client/qwaylandintegration.cpp
|
||||||
|
+++ b/src/client/qwaylandintegration.cpp
|
||||||
|
@@ -192,10 +192,6 @@ QAbstractEventDispatcher *QWaylandIntegration::createEventDispatcher() const
|
||||||
|
|
||||||
|
void QWaylandIntegration::initialize()
|
||||||
|
{
|
||||||
|
- QAbstractEventDispatcher *dispatcher = QGuiApplicationPrivate::eventDispatcher;
|
||||||
|
- QObject::connect(dispatcher, SIGNAL(aboutToBlock()), mDisplay.data(), SLOT(flushRequests()));
|
||||||
|
- QObject::connect(dispatcher, SIGNAL(awake()), mDisplay.data(), SLOT(flushRequests()));
|
||||||
|
-
|
||||||
|
int fd = wl_display_get_fd(mDisplay->wl_display());
|
||||||
|
QSocketNotifier *sn = new QSocketNotifier(fd, QSocketNotifier::Read, mDisplay.data());
|
||||||
|
QObject::connect(sn, SIGNAL(activated(QSocketDescriptor)), mDisplay.data(), SLOT(flushRequests()));
|
||||||
|
@@ -203,6 +199,13 @@ void QWaylandIntegration::initialize()
|
||||||
|
// Call after eventDispatcher is fully connected, for QWaylandDisplay::forceRoundTrip()
|
||||||
|
mDisplay->initialize();
|
||||||
|
|
||||||
|
+ // But the aboutToBlock() and awake() should be connected after initializePlatform().
|
||||||
|
+ // Otherwise the connected flushRequests() may consumes up all events before processEvents starts to wait,
|
||||||
|
+ // so that processEvents(QEventLoop::WaitForMoreEvents) may be blocked in the forceRoundTrip().
|
||||||
|
+ QAbstractEventDispatcher *dispatcher = QGuiApplicationPrivate::eventDispatcher;
|
||||||
|
+ QObject::connect(dispatcher, SIGNAL(aboutToBlock()), mDisplay.data(), SLOT(flushRequests()));
|
||||||
|
+ QObject::connect(dispatcher, SIGNAL(awake()), mDisplay.data(), SLOT(flushRequests()));
|
||||||
|
+
|
||||||
|
// Qt does not support running with no screens
|
||||||
|
mDisplay->ensureScreen();
|
||||||
|
}
|
||||||
|
--
|
||||||
|
2.40.1
|
||||||
|
|
||||||
@ -1,26 +0,0 @@
|
|||||||
From 2f84a874da064069461284db1da36dc818949ec1 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Albert Astals Cid <aacid@kde.org>
|
|
||||||
Date: Sat, 10 Apr 2021 12:10:16 +0200
|
|
||||||
Subject: [PATCH 18/19] Fix compilation
|
|
||||||
|
|
||||||
9df11e79b46c77d8c83f765b2a8e85b639fd55a2 can't be backported 1:1
|
|
||||||
---
|
|
||||||
.../client/wayland-egl/qwaylandglcontext.cpp | 2 +-
|
|
||||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
|
||||||
|
|
||||||
diff --git a/src/hardwareintegration/client/wayland-egl/qwaylandglcontext.cpp b/src/hardwareintegration/client/wayland-egl/qwaylandglcontext.cpp
|
|
||||||
index befadedc..95d1049c 100644
|
|
||||||
--- a/src/hardwareintegration/client/wayland-egl/qwaylandglcontext.cpp
|
|
||||||
+++ b/src/hardwareintegration/client/wayland-egl/qwaylandglcontext.cpp
|
|
||||||
@@ -408,7 +408,7 @@ QWaylandGLContext::~QWaylandGLContext()
|
|
||||||
delete m_blitter;
|
|
||||||
m_blitter = nullptr;
|
|
||||||
if (m_decorationsContext != EGL_NO_CONTEXT)
|
|
||||||
- eglDestroyContext(eglDisplay(), m_decorationsContext);
|
|
||||||
+ eglDestroyContext(m_eglDisplay, m_decorationsContext);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool QWaylandGLContext::makeCurrent(QPlatformSurface *surface)
|
|
||||||
--
|
|
||||||
2.31.1
|
|
||||||
|
|
||||||
574
0019-Move-the-wayland-socket-polling-to-a-separate-event-.patch
Normal file
574
0019-Move-the-wayland-socket-polling-to-a-separate-event-.patch
Normal file
@ -0,0 +1,574 @@
|
|||||||
|
From 965fc31b57176d7d913d90465a857c285abd0a59 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Adrien Faveraux <af@brain-networks.fr>
|
||||||
|
Date: Fri, 26 Nov 2021 09:18:58 +0100
|
||||||
|
Subject: [PATCH 19/51] Move the wayland socket polling to a separate event
|
||||||
|
thread
|
||||||
|
|
||||||
|
New event threads is introduced which calls poll() on the wayland fd,
|
||||||
|
instead of relying on the event dispatcher by using the QSocketNotifier.
|
||||||
|
This allows to call in the proper order the wl_display_prepare_read(),
|
||||||
|
poll() and wl_display_read_events() functions.
|
||||||
|
|
||||||
|
One thread is responsible for the default queue; when needed, it emit
|
||||||
|
a signal so that the main thread can dispatch the queue. Another thread
|
||||||
|
is responsible for the dedicated queue for frame callbacks; this thread
|
||||||
|
will dispatch events on the thread itself.
|
||||||
|
|
||||||
|
QWaylandWindow is updated to, instead of each window's dedicated event
|
||||||
|
queue, use this queue for frame callbacks.
|
||||||
|
|
||||||
|
Co-authored-by: Ratchanan Srirattanamet <ratchanan@ubports.com>
|
||||||
|
Task-number: QTBUG-66075
|
||||||
|
Change-Id: Ibb33ad7f4193b866d1b8d7a0405a94d59dcad5eb
|
||||||
|
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
|
||||||
|
Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io>
|
||||||
|
(cherry picked from commit 92a7904d9651348b0c307e84251c8440c6f75b22)
|
||||||
|
---
|
||||||
|
src/client/qwaylanddisplay.cpp | 302 +++++++++++++++++++++--------
|
||||||
|
src/client/qwaylanddisplay_p.h | 21 +-
|
||||||
|
src/client/qwaylandintegration.cpp | 4 +-
|
||||||
|
src/client/qwaylandwindow.cpp | 34 +++-
|
||||||
|
src/client/qwaylandwindow_p.h | 2 +-
|
||||||
|
5 files changed, 255 insertions(+), 108 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/client/qwaylanddisplay.cpp b/src/client/qwaylanddisplay.cpp
|
||||||
|
index 97fb8cbe..ebcdbd22 100644
|
||||||
|
--- a/src/client/qwaylanddisplay.cpp
|
||||||
|
+++ b/src/client/qwaylanddisplay.cpp
|
||||||
|
@@ -87,10 +87,203 @@
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
+#include <tuple> // for std::tie
|
||||||
|
+
|
||||||
|
+static void checkWaylandError(struct wl_display *display)
|
||||||
|
+{
|
||||||
|
+ int ecode = wl_display_get_error(display);
|
||||||
|
+ if ((ecode == EPIPE || ecode == ECONNRESET)) {
|
||||||
|
+ // special case this to provide a nicer error
|
||||||
|
+ qWarning("The Wayland connection broke. Did the Wayland compositor die?");
|
||||||
|
+ } else {
|
||||||
|
+ qWarning("The Wayland connection experienced a fatal error: %s", strerror(ecode));
|
||||||
|
+ }
|
||||||
|
+ _exit(1);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
namespace QtWaylandClient {
|
||||||
|
|
||||||
|
+class EventThread : public QThread
|
||||||
|
+{
|
||||||
|
+ Q_OBJECT
|
||||||
|
+public:
|
||||||
|
+ enum OperatingMode {
|
||||||
|
+ EmitToDispatch, // Emit the signal, allow dispatching in a differnt thread.
|
||||||
|
+ SelfDispatch, // Dispatch the events inside this thread.
|
||||||
|
+ };
|
||||||
|
+
|
||||||
|
+ EventThread(struct wl_display * wl, struct wl_event_queue * ev_queue,
|
||||||
|
+ OperatingMode mode)
|
||||||
|
+ : m_fd(wl_display_get_fd(wl))
|
||||||
|
+ , m_pipefd{ -1, -1 }
|
||||||
|
+ , m_wldisplay(wl)
|
||||||
|
+ , m_wlevqueue(ev_queue)
|
||||||
|
+ , m_mode(mode)
|
||||||
|
+ , m_reading(true)
|
||||||
|
+ , m_quitting(false)
|
||||||
|
+ {
|
||||||
|
+ setObjectName(QStringLiteral("WaylandEventThread"));
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ void readAndDispatchEvents()
|
||||||
|
+ {
|
||||||
|
+ /*
|
||||||
|
+ * Dispatch pending events and flush the requests at least once. If the event thread
|
||||||
|
+ * is not reading, try to call _prepare_read() to allow the event thread to poll().
|
||||||
|
+ * If that fails, re-try dispatch & flush again until _prepare_read() is successful.
|
||||||
|
+ *
|
||||||
|
+ * This allow any call to readAndDispatchEvents() to start event thread's polling,
|
||||||
|
+ * not only the one issued from event thread's waitForReading(), which means functions
|
||||||
|
+ * called from dispatch_pending() can safely spin an event loop.
|
||||||
|
+ */
|
||||||
|
+ for (;;) {
|
||||||
|
+ if (dispatchQueuePending() < 0) {
|
||||||
|
+ checkWaylandError(m_wldisplay);
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ wl_display_flush(m_wldisplay);
|
||||||
|
+
|
||||||
|
+ // We have to check if event thread is reading every time we dispatch
|
||||||
|
+ // something, as that may recursively call this function.
|
||||||
|
+ if (m_reading.loadAcquire())
|
||||||
|
+ break;
|
||||||
|
+
|
||||||
|
+ if (prepareReadQueue() == 0) {
|
||||||
|
+ QMutexLocker l(&m_mutex);
|
||||||
|
+ m_reading.storeRelease(true);
|
||||||
|
+ m_cond.wakeOne();
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ void stop()
|
||||||
|
+ {
|
||||||
|
+ // We have to both write to the pipe and set the flag, as the thread may be
|
||||||
|
+ // either in the poll() or waiting for _prepare_read().
|
||||||
|
+ if (m_pipefd[1] != -1 && write(m_pipefd[1], "\0", 1) == -1)
|
||||||
|
+ qWarning("Failed to write to the pipe: %s.", strerror(errno));
|
||||||
|
+
|
||||||
|
+ {
|
||||||
|
+ QMutexLocker l(&m_mutex);
|
||||||
|
+ m_quitting = true;
|
||||||
|
+ m_cond.wakeOne();
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ wait();
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+Q_SIGNALS:
|
||||||
|
+ void needReadAndDispatch();
|
||||||
|
+
|
||||||
|
+protected:
|
||||||
|
+ void run() override
|
||||||
|
+ {
|
||||||
|
+ // we use this pipe to make the loop exit otherwise if we simply used a flag on the loop condition, if stop() gets
|
||||||
|
+ // called while poll() is blocking the thread will never quit since there are no wayland messages coming anymore.
|
||||||
|
+ struct Pipe
|
||||||
|
+ {
|
||||||
|
+ Pipe(int *fds)
|
||||||
|
+ : fds(fds)
|
||||||
|
+ {
|
||||||
|
+ if (qt_safe_pipe(fds) != 0)
|
||||||
|
+ qWarning("Pipe creation failed. Quitting may hang.");
|
||||||
|
+ }
|
||||||
|
+ ~Pipe()
|
||||||
|
+ {
|
||||||
|
+ if (fds[0] != -1) {
|
||||||
|
+ close(fds[0]);
|
||||||
|
+ close(fds[1]);
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ int *fds;
|
||||||
|
+ } pipe(m_pipefd);
|
||||||
|
+
|
||||||
|
+ // Make the main thread call wl_prepare_read(), dispatch the pending messages and flush the
|
||||||
|
+ // outbound ones. Wait until it's done before proceeding, unless we're told to quit.
|
||||||
|
+ while (waitForReading()) {
|
||||||
|
+ pollfd fds[2] = { { m_fd, POLLIN, 0 }, { m_pipefd[0], POLLIN, 0 } };
|
||||||
|
+ poll(fds, 2, -1);
|
||||||
|
+
|
||||||
|
+ if (fds[1].revents & POLLIN) {
|
||||||
|
+ // we don't really care to read the byte that was written here since we're closing down
|
||||||
|
+ wl_display_cancel_read(m_wldisplay);
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (fds[0].revents & POLLIN)
|
||||||
|
+ wl_display_read_events(m_wldisplay);
|
||||||
|
+ // The polll was succesfull and the event thread did the wl_display_read_events(). On the next iteration of the loop
|
||||||
|
+ // the event sent to the main thread will cause it to dispatch the messages just read, unless the loop exits in which
|
||||||
|
+ // case we don't care anymore about them.
|
||||||
|
+ else
|
||||||
|
+ wl_display_cancel_read(m_wldisplay);
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+private:
|
||||||
|
+ bool waitForReading()
|
||||||
|
+ {
|
||||||
|
+ Q_ASSERT(QThread::currentThread() == this);
|
||||||
|
+
|
||||||
|
+ m_reading.storeRelease(false);
|
||||||
|
+
|
||||||
|
+ if (m_mode == SelfDispatch) {
|
||||||
|
+ readAndDispatchEvents();
|
||||||
|
+ } else {
|
||||||
|
+ Q_EMIT needReadAndDispatch();
|
||||||
|
+
|
||||||
|
+ QMutexLocker lock(&m_mutex);
|
||||||
|
+ // m_reading might be set from our emit or some other invocation of
|
||||||
|
+ // readAndDispatchEvents().
|
||||||
|
+ while (!m_reading.loadRelaxed() && !m_quitting)
|
||||||
|
+ m_cond.wait(&m_mutex);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return !m_quitting;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ int dispatchQueuePending()
|
||||||
|
+ {
|
||||||
|
+ if (m_wlevqueue)
|
||||||
|
+ return wl_display_dispatch_queue_pending(m_wldisplay, m_wlevqueue);
|
||||||
|
+ else
|
||||||
|
+ return wl_display_dispatch_pending(m_wldisplay);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ int prepareReadQueue()
|
||||||
|
+ {
|
||||||
|
+ if (m_wlevqueue)
|
||||||
|
+ return wl_display_prepare_read_queue(m_wldisplay, m_wlevqueue);
|
||||||
|
+ else
|
||||||
|
+ return wl_display_prepare_read(m_wldisplay);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ int m_fd;
|
||||||
|
+ int m_pipefd[2];
|
||||||
|
+ wl_display *m_wldisplay;
|
||||||
|
+ wl_event_queue *m_wlevqueue;
|
||||||
|
+ OperatingMode m_mode;
|
||||||
|
+
|
||||||
|
+ /* Concurrency note when operating in EmitToDispatch mode:
|
||||||
|
+ * m_reading is set to false inside event thread's waitForReading(), and is
|
||||||
|
+ * set to true inside main thread's readAndDispatchEvents().
|
||||||
|
+ * The lock is not taken when setting m_reading to false, as the main thread
|
||||||
|
+ * is not actively waiting for it to turn false. However, the lock is taken
|
||||||
|
+ * inside readAndDispatchEvents() before setting m_reading to true,
|
||||||
|
+ * as the event thread is actively waiting for it under the wait condition.
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+ QAtomicInteger<bool> m_reading;
|
||||||
|
+ bool m_quitting;
|
||||||
|
+ QMutex m_mutex;
|
||||||
|
+ QWaitCondition m_cond;
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
Q_LOGGING_CATEGORY(lcQpaWayland, "qt.qpa.wayland"); // for general (uncategorized) Wayland platform logging
|
||||||
|
|
||||||
|
struct wl_surface *QWaylandDisplay::createSurface(void *handle)
|
||||||
|
@@ -164,6 +357,12 @@ QWaylandDisplay::QWaylandDisplay(QWaylandIntegration *waylandIntegration)
|
||||||
|
|
||||||
|
QWaylandDisplay::~QWaylandDisplay(void)
|
||||||
|
{
|
||||||
|
+ if (m_eventThread)
|
||||||
|
+ m_eventThread->stop();
|
||||||
|
+
|
||||||
|
+ if (m_frameEventQueueThread)
|
||||||
|
+ m_frameEventQueueThread->stop();
|
||||||
|
+
|
||||||
|
if (mSyncCallback)
|
||||||
|
wl_callback_destroy(mSyncCallback);
|
||||||
|
|
||||||
|
@@ -210,98 +409,37 @@ void QWaylandDisplay::ensureScreen()
|
||||||
|
|
||||||
|
void QWaylandDisplay::checkError() const
|
||||||
|
{
|
||||||
|
- int ecode = wl_display_get_error(mDisplay);
|
||||||
|
- if ((ecode == EPIPE || ecode == ECONNRESET)) {
|
||||||
|
- // special case this to provide a nicer error
|
||||||
|
- qWarning("The Wayland connection broke. Did the Wayland compositor die?");
|
||||||
|
- } else {
|
||||||
|
- qWarning("The Wayland connection experienced a fatal error: %s", strerror(ecode));
|
||||||
|
- }
|
||||||
|
- _exit(1);
|
||||||
|
+ checkWaylandError(mDisplay);
|
||||||
|
}
|
||||||
|
|
||||||
|
+// Called in main thread, either from queued signal or directly.
|
||||||
|
void QWaylandDisplay::flushRequests()
|
||||||
|
{
|
||||||
|
- if (wl_display_prepare_read(mDisplay) == 0) {
|
||||||
|
- wl_display_read_events(mDisplay);
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- if (wl_display_dispatch_pending(mDisplay) < 0)
|
||||||
|
- checkError();
|
||||||
|
-
|
||||||
|
- {
|
||||||
|
- QReadLocker locker(&m_frameQueueLock);
|
||||||
|
- for (const FrameQueue &q : mExternalQueues) {
|
||||||
|
- QMutexLocker locker(q.mutex);
|
||||||
|
- while (wl_display_prepare_read_queue(mDisplay, q.queue) != 0)
|
||||||
|
- wl_display_dispatch_queue_pending(mDisplay, q.queue);
|
||||||
|
- wl_display_read_events(mDisplay);
|
||||||
|
- wl_display_dispatch_queue_pending(mDisplay, q.queue);
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- wl_display_flush(mDisplay);
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
-void QWaylandDisplay::blockingReadEvents()
|
||||||
|
-{
|
||||||
|
- if (wl_display_dispatch(mDisplay) < 0)
|
||||||
|
- checkError();
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
-void QWaylandDisplay::destroyFrameQueue(const QWaylandDisplay::FrameQueue &q)
|
||||||
|
-{
|
||||||
|
- QWriteLocker locker(&m_frameQueueLock);
|
||||||
|
- auto it = std::find_if(mExternalQueues.begin(),
|
||||||
|
- mExternalQueues.end(),
|
||||||
|
- [&q] (const QWaylandDisplay::FrameQueue &other){ return other.queue == q.queue; });
|
||||||
|
- Q_ASSERT(it != mExternalQueues.end());
|
||||||
|
- mExternalQueues.erase(it);
|
||||||
|
- if (q.queue != nullptr)
|
||||||
|
- wl_event_queue_destroy(q.queue);
|
||||||
|
- delete q.mutex;
|
||||||
|
+ m_eventThread->readAndDispatchEvents();
|
||||||
|
}
|
||||||
|
|
||||||
|
-QWaylandDisplay::FrameQueue QWaylandDisplay::createFrameQueue()
|
||||||
|
+// We have to wait until we have an eventDispatcher before creating the eventThread,
|
||||||
|
+// otherwise forceRoundTrip() may block inside _events_read() because eventThread is
|
||||||
|
+// polling.
|
||||||
|
+void QWaylandDisplay::initEventThread()
|
||||||
|
{
|
||||||
|
- QWriteLocker locker(&m_frameQueueLock);
|
||||||
|
- FrameQueue q{createEventQueue()};
|
||||||
|
- mExternalQueues.append(q);
|
||||||
|
- return q;
|
||||||
|
-}
|
||||||
|
+ m_eventThread.reset(
|
||||||
|
+ new EventThread(mDisplay, /* default queue */ nullptr, EventThread::EmitToDispatch));
|
||||||
|
+ connect(m_eventThread.get(), &EventThread::needReadAndDispatch, this,
|
||||||
|
+ &QWaylandDisplay::flushRequests, Qt::QueuedConnection);
|
||||||
|
+ m_eventThread->start();
|
||||||
|
|
||||||
|
-wl_event_queue *QWaylandDisplay::createEventQueue()
|
||||||
|
-{
|
||||||
|
- return wl_display_create_queue(mDisplay);
|
||||||
|
+ // wl_display_disconnect() free this.
|
||||||
|
+ m_frameEventQueue = wl_display_create_queue(mDisplay);
|
||||||
|
+ m_frameEventQueueThread.reset(
|
||||||
|
+ new EventThread(mDisplay, m_frameEventQueue, EventThread::SelfDispatch));
|
||||||
|
+ m_frameEventQueueThread->start();
|
||||||
|
}
|
||||||
|
|
||||||
|
-void QWaylandDisplay::dispatchQueueWhile(wl_event_queue *queue, std::function<bool ()> condition, int timeout)
|
||||||
|
+void QWaylandDisplay::blockingReadEvents()
|
||||||
|
{
|
||||||
|
- if (!condition())
|
||||||
|
- return;
|
||||||
|
-
|
||||||
|
- QElapsedTimer timer;
|
||||||
|
- timer.start();
|
||||||
|
- struct pollfd pFd = qt_make_pollfd(wl_display_get_fd(mDisplay), POLLIN);
|
||||||
|
- while (timeout == -1 || timer.elapsed() < timeout) {
|
||||||
|
- while (wl_display_prepare_read_queue(mDisplay, queue) != 0)
|
||||||
|
- wl_display_dispatch_queue_pending(mDisplay, queue);
|
||||||
|
-
|
||||||
|
- wl_display_flush(mDisplay);
|
||||||
|
-
|
||||||
|
- const int remaining = qMax(timeout - timer.elapsed(), 0ll);
|
||||||
|
- const int pollTimeout = timeout == -1 ? -1 : remaining;
|
||||||
|
- if (qt_poll_msecs(&pFd, 1, pollTimeout) > 0)
|
||||||
|
- wl_display_read_events(mDisplay);
|
||||||
|
- else
|
||||||
|
- wl_display_cancel_read(mDisplay);
|
||||||
|
-
|
||||||
|
- if (wl_display_dispatch_queue_pending(mDisplay, queue) < 0)
|
||||||
|
- checkError();
|
||||||
|
-
|
||||||
|
- if (!condition())
|
||||||
|
- break;
|
||||||
|
- }
|
||||||
|
+ if (wl_display_dispatch(mDisplay) < 0)
|
||||||
|
+ checkWaylandError(mDisplay);
|
||||||
|
}
|
||||||
|
|
||||||
|
QWaylandScreen *QWaylandDisplay::screenForOutput(struct wl_output *output) const
|
||||||
|
@@ -678,4 +816,6 @@ QWaylandCursorTheme *QWaylandDisplay::loadCursorTheme(const QString &name, int p
|
||||||
|
|
||||||
|
} // namespace QtWaylandClient
|
||||||
|
|
||||||
|
+#include "qwaylanddisplay.moc"
|
||||||
|
+
|
||||||
|
QT_END_NAMESPACE
|
||||||
|
diff --git a/src/client/qwaylanddisplay_p.h b/src/client/qwaylanddisplay_p.h
|
||||||
|
index 49820255..cf91b924 100644
|
||||||
|
--- a/src/client/qwaylanddisplay_p.h
|
||||||
|
+++ b/src/client/qwaylanddisplay_p.h
|
||||||
|
@@ -111,6 +111,7 @@ class QWaylandSurface;
|
||||||
|
class QWaylandShellIntegration;
|
||||||
|
class QWaylandCursor;
|
||||||
|
class QWaylandCursorTheme;
|
||||||
|
+class EventThread;
|
||||||
|
|
||||||
|
typedef void (*RegistryListener)(void *data,
|
||||||
|
struct wl_registry *registry,
|
||||||
|
@@ -122,12 +123,6 @@ class Q_WAYLAND_CLIENT_EXPORT QWaylandDisplay : public QObject, public QtWayland
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
- struct FrameQueue {
|
||||||
|
- FrameQueue(wl_event_queue *q = nullptr) : queue(q), mutex(new QMutex) {}
|
||||||
|
- wl_event_queue *queue;
|
||||||
|
- QMutex *mutex;
|
||||||
|
- };
|
||||||
|
-
|
||||||
|
QWaylandDisplay(QWaylandIntegration *waylandIntegration);
|
||||||
|
~QWaylandDisplay(void) override;
|
||||||
|
|
||||||
|
@@ -216,12 +211,11 @@ public:
|
||||||
|
void handleKeyboardFocusChanged(QWaylandInputDevice *inputDevice);
|
||||||
|
void handleWindowDestroyed(QWaylandWindow *window);
|
||||||
|
|
||||||
|
- wl_event_queue *createEventQueue();
|
||||||
|
- FrameQueue createFrameQueue();
|
||||||
|
- void destroyFrameQueue(const FrameQueue &q);
|
||||||
|
- void dispatchQueueWhile(wl_event_queue *queue, std::function<bool()> condition, int timeout = -1);
|
||||||
|
+ wl_event_queue *frameEventQueue() { return m_frameEventQueue; };
|
||||||
|
|
||||||
|
bool isKeyboardAvailable() const;
|
||||||
|
+
|
||||||
|
+ void initEventThread();
|
||||||
|
public slots:
|
||||||
|
void blockingReadEvents();
|
||||||
|
void flushRequests();
|
||||||
|
@@ -244,6 +238,9 @@ private:
|
||||||
|
};
|
||||||
|
|
||||||
|
struct wl_display *mDisplay = nullptr;
|
||||||
|
+ QScopedPointer<EventThread> m_eventThread;
|
||||||
|
+ wl_event_queue *m_frameEventQueue = nullptr;
|
||||||
|
+ QScopedPointer<EventThread> m_frameEventQueueThread;
|
||||||
|
QtWayland::wl_compositor mCompositor;
|
||||||
|
QScopedPointer<QWaylandShm> mShm;
|
||||||
|
QList<QWaylandScreen *> mWaitingScreens;
|
||||||
|
@@ -282,11 +279,9 @@ private:
|
||||||
|
QWaylandInputDevice *mLastInputDevice = nullptr;
|
||||||
|
QPointer<QWaylandWindow> mLastInputWindow;
|
||||||
|
QPointer<QWaylandWindow> mLastKeyboardFocus;
|
||||||
|
- QVector<QWaylandWindow *> mActiveWindows;
|
||||||
|
- QVector<FrameQueue> mExternalQueues;
|
||||||
|
+ QList<QWaylandWindow *> mActiveWindows;
|
||||||
|
struct wl_callback *mSyncCallback = nullptr;
|
||||||
|
static const wl_callback_listener syncCallbackListener;
|
||||||
|
- QReadWriteLock m_frameQueueLock;
|
||||||
|
|
||||||
|
bool mClientSideInputContextRequested = !QPlatformInputContextFactory::requested().isNull();
|
||||||
|
|
||||||
|
diff --git a/src/client/qwaylandintegration.cpp b/src/client/qwaylandintegration.cpp
|
||||||
|
index 661cea53..fbf00c6b 100644
|
||||||
|
--- a/src/client/qwaylandintegration.cpp
|
||||||
|
+++ b/src/client/qwaylandintegration.cpp
|
||||||
|
@@ -192,9 +192,7 @@ QAbstractEventDispatcher *QWaylandIntegration::createEventDispatcher() const
|
||||||
|
|
||||||
|
void QWaylandIntegration::initialize()
|
||||||
|
{
|
||||||
|
- int fd = wl_display_get_fd(mDisplay->wl_display());
|
||||||
|
- QSocketNotifier *sn = new QSocketNotifier(fd, QSocketNotifier::Read, mDisplay.data());
|
||||||
|
- QObject::connect(sn, SIGNAL(activated(QSocketDescriptor)), mDisplay.data(), SLOT(flushRequests()));
|
||||||
|
+ mDisplay->initEventThread();
|
||||||
|
|
||||||
|
// Call after eventDispatcher is fully connected, for QWaylandDisplay::forceRoundTrip()
|
||||||
|
mDisplay->initialize();
|
||||||
|
diff --git a/src/client/qwaylandwindow.cpp b/src/client/qwaylandwindow.cpp
|
||||||
|
index b98435ed..292dd023 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)
|
||||||
|
- , mFrameQueue(mDisplay->createFrameQueue())
|
||||||
|
, mResizeAfterSwap(qEnvironmentVariableIsSet("QT_WAYLAND_RESIZE_AFTER_SWAP"))
|
||||||
|
{
|
||||||
|
{
|
||||||
|
@@ -95,8 +94,6 @@ QWaylandWindow::QWaylandWindow(QWindow *window, QWaylandDisplay *display)
|
||||||
|
|
||||||
|
QWaylandWindow::~QWaylandWindow()
|
||||||
|
{
|
||||||
|
- mDisplay->destroyFrameQueue(mFrameQueue);
|
||||||
|
-
|
||||||
|
delete mWindowDecoration;
|
||||||
|
|
||||||
|
if (mSurface)
|
||||||
|
@@ -648,6 +645,8 @@ const wl_callback_listener QWaylandWindow::callbackListener = {
|
||||||
|
|
||||||
|
void QWaylandWindow::handleFrameCallback()
|
||||||
|
{
|
||||||
|
+ QMutexLocker locker(&mFrameSyncMutex);
|
||||||
|
+
|
||||||
|
mWaitingForFrameCallback = false;
|
||||||
|
mFrameCallbackElapsedTimer.invalidate();
|
||||||
|
|
||||||
|
@@ -669,12 +668,16 @@ void QWaylandWindow::handleFrameCallback()
|
||||||
|
mWaitingForUpdateDelivery = true;
|
||||||
|
QMetaObject::invokeMethod(this, doHandleExpose, Qt::QueuedConnection);
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+ mFrameSyncWait.notify_all();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool QWaylandWindow::waitForFrameSync(int timeout)
|
||||||
|
{
|
||||||
|
- QMutexLocker locker(mFrameQueue.mutex);
|
||||||
|
- mDisplay->dispatchQueueWhile(mFrameQueue.queue, [&]() { return mWaitingForFrameCallback; }, timeout);
|
||||||
|
+ QMutexLocker locker(&mFrameSyncMutex);
|
||||||
|
+
|
||||||
|
+ QDeadlineTimer deadline(timeout);
|
||||||
|
+ while (mWaitingForFrameCallback && mFrameSyncWait.wait(&mFrameSyncMutex, deadline)) { }
|
||||||
|
|
||||||
|
if (mWaitingForFrameCallback) {
|
||||||
|
qCDebug(lcWaylandBackingstore) << "Didn't receive frame callback in time, window should now be inexposed";
|
||||||
|
@@ -1179,8 +1182,11 @@ void QWaylandWindow::requestUpdate()
|
||||||
|
Q_ASSERT(hasPendingUpdateRequest()); // should be set by QPA
|
||||||
|
|
||||||
|
// If we have a frame callback all is good and will be taken care of there
|
||||||
|
- if (mWaitingForFrameCallback)
|
||||||
|
- return;
|
||||||
|
+ {
|
||||||
|
+ QMutexLocker locker(&mFrameSyncMutex);
|
||||||
|
+ if (mWaitingForFrameCallback)
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
// If we've already called deliverUpdateRequest(), but haven't seen any attach+commit/swap yet
|
||||||
|
// This is a somewhat redundant behavior and might indicate a bug in the calling code, so log
|
||||||
|
@@ -1193,7 +1199,12 @@ void QWaylandWindow::requestUpdate()
|
||||||
|
// so use invokeMethod to delay the delivery a bit.
|
||||||
|
QMetaObject::invokeMethod(this, [this] {
|
||||||
|
// Things might have changed in the meantime
|
||||||
|
- if (hasPendingUpdateRequest() && !mWaitingForFrameCallback)
|
||||||
|
+ {
|
||||||
|
+ QMutexLocker locker(&mFrameSyncMutex);
|
||||||
|
+ if (mWaitingForFrameCallback)
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+ if (hasPendingUpdateRequest())
|
||||||
|
deliverUpdateRequest();
|
||||||
|
}, Qt::QueuedConnection);
|
||||||
|
}
|
||||||
|
@@ -1213,9 +1224,10 @@ void QWaylandWindow::handleUpdate()
|
||||||
|
if (!mSurface)
|
||||||
|
return;
|
||||||
|
|
||||||
|
- QMutexLocker locker(mFrameQueue.mutex);
|
||||||
|
+ QMutexLocker locker(&mFrameSyncMutex);
|
||||||
|
+
|
||||||
|
struct ::wl_surface *wrappedSurface = reinterpret_cast<struct ::wl_surface *>(wl_proxy_create_wrapper(mSurface->object()));
|
||||||
|
- wl_proxy_set_queue(reinterpret_cast<wl_proxy *>(wrappedSurface), mFrameQueue.queue);
|
||||||
|
+ wl_proxy_set_queue(reinterpret_cast<wl_proxy *>(wrappedSurface), mDisplay->frameEventQueue());
|
||||||
|
mFrameCallback = wl_surface_frame(wrappedSurface);
|
||||||
|
wl_proxy_wrapper_destroy(wrappedSurface);
|
||||||
|
wl_callback_add_listener(mFrameCallback, &QWaylandWindow::callbackListener, this);
|
||||||
|
@@ -1225,6 +1237,8 @@ void QWaylandWindow::handleUpdate()
|
||||||
|
// Start a timer for handling the case when the compositor stops sending frame callbacks.
|
||||||
|
if (mFrameCallbackTimeout > 0) {
|
||||||
|
QMetaObject::invokeMethod(this, [this] {
|
||||||
|
+ QMutexLocker locker(&mFrameSyncMutex);
|
||||||
|
+
|
||||||
|
if (mWaitingForFrameCallback) {
|
||||||
|
if (mFrameCallbackCheckIntervalTimerId < 0)
|
||||||
|
mFrameCallbackCheckIntervalTimerId = startTimer(mFrameCallbackTimeout);
|
||||||
|
diff --git a/src/client/qwaylandwindow_p.h b/src/client/qwaylandwindow_p.h
|
||||||
|
index fb3ed606..54ac67a9 100644
|
||||||
|
--- a/src/client/qwaylandwindow_p.h
|
||||||
|
+++ b/src/client/qwaylandwindow_p.h
|
||||||
|
@@ -232,7 +232,7 @@ protected:
|
||||||
|
int mFrameCallbackCheckIntervalTimerId = -1;
|
||||||
|
QElapsedTimer mFrameCallbackElapsedTimer;
|
||||||
|
struct ::wl_callback *mFrameCallback = nullptr;
|
||||||
|
- QWaylandDisplay::FrameQueue mFrameQueue;
|
||||||
|
+ QMutex mFrameSyncMutex;
|
||||||
|
QWaitCondition mFrameSyncWait;
|
||||||
|
|
||||||
|
// True when we have called deliverRequestUpdate, but the client has not yet attached a new buffer
|
||||||
|
--
|
||||||
|
2.40.1
|
||||||
|
|
||||||
@ -1,257 +0,0 @@
|
|||||||
From 91c48320633e493b4cd519e5d73b836a878b2b77 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Aleix Pol <aleixpol@kde.org>
|
|
||||||
Date: Wed, 10 Mar 2021 01:09:13 +0100
|
|
||||||
Subject: [PATCH 19/19] 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.31.1
|
|
||||||
|
|
||||||
79
0020-Client-Remove-mWaitingForUpdateDelivery.patch
Normal file
79
0020-Client-Remove-mWaitingForUpdateDelivery.patch
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
From 39f6f824e660c36b2865bf55f9ea609aaa02697e Mon Sep 17 00:00:00 2001
|
||||||
|
From: Vlad Zahorodnii <vlad.zahorodnii@kde.org>
|
||||||
|
Date: Tue, 1 Feb 2022 13:05:36 +0200
|
||||||
|
Subject: [PATCH 20/51] Client: Remove mWaitingForUpdateDelivery
|
||||||
|
|
||||||
|
Currently, mWaitingForUpdateDelivery is shared between the main thread
|
||||||
|
(doHandleFrameCallback()) and the frame callback event thread
|
||||||
|
(handleFrameCallback()), however the access to it is not synchronized
|
||||||
|
between both threads. On the other hand, QWaylandWindow
|
||||||
|
already ensures not to create a frame callback if there's already one
|
||||||
|
pending.
|
||||||
|
|
||||||
|
This change removes mWaitingForUpdateDelivery flag because it should be
|
||||||
|
already covered by mWaitingForFrameCallback and to remove unsynchronized
|
||||||
|
shared state between threads.
|
||||||
|
|
||||||
|
Change-Id: I0e5a25d18d1e66c4d7683e7e972330c4d7cbbf38
|
||||||
|
Reviewed-by: David Edmundson <davidedmundson@kde.org>
|
||||||
|
(cherry picked from commit feb1a5c207c13d0bf87c0d8ad039279dbf8cee9e)
|
||||||
|
---
|
||||||
|
src/client/qwaylandwindow.cpp | 29 ++++++++++++-----------------
|
||||||
|
src/client/qwaylandwindow_p.h | 1 -
|
||||||
|
2 files changed, 12 insertions(+), 18 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/client/qwaylandwindow.cpp b/src/client/qwaylandwindow.cpp
|
||||||
|
index 292dd023..de5af1bd 100644
|
||||||
|
--- a/src/client/qwaylandwindow.cpp
|
||||||
|
+++ b/src/client/qwaylandwindow.cpp
|
||||||
|
@@ -651,23 +651,18 @@ void QWaylandWindow::handleFrameCallback()
|
||||||
|
mFrameCallbackElapsedTimer.invalidate();
|
||||||
|
|
||||||
|
// The rest can wait until we can run it on the correct thread
|
||||||
|
- if (!mWaitingForUpdateDelivery) {
|
||||||
|
- auto doHandleExpose = [this]() {
|
||||||
|
- 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;
|
||||||
|
- };
|
||||||
|
-
|
||||||
|
- // 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);
|
||||||
|
- }
|
||||||
|
+ auto doHandleExpose = [this]() {
|
||||||
|
+ bool wasExposed = isExposed();
|
||||||
|
+ mFrameCallbackTimedOut = false;
|
||||||
|
+ if (!wasExposed && isExposed()) // Did setting mFrameCallbackTimedOut make the window exposed?
|
||||||
|
+ sendExposeEvent(QRect(QPoint(), geometry().size()));
|
||||||
|
+ if (wasExposed && hasPendingUpdateRequest())
|
||||||
|
+ deliverUpdateRequest();
|
||||||
|
+ };
|
||||||
|
+
|
||||||
|
+ // Queued connection, to make sure we don't call handleUpdate() from inside waitForFrameSync()
|
||||||
|
+ // in the single-threaded case.
|
||||||
|
+ 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..cf7ce879 100644
|
||||||
|
--- a/src/client/qwaylandwindow_p.h
|
||||||
|
+++ b/src/client/qwaylandwindow_p.h
|
||||||
|
@@ -228,7 +228,6 @@ 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.1
|
||||||
|
|
||||||
82
0021-client-Simplify-round-trip-behavior.patch
Normal file
82
0021-client-Simplify-round-trip-behavior.patch
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
From 89b396cbef7c8fb7041d3a13d952d468c5c57e56 Mon Sep 17 00:00:00 2001
|
||||||
|
From: David Edmundson <davidedmundson@kde.org>
|
||||||
|
Date: Wed, 9 Feb 2022 17:20:48 +0000
|
||||||
|
Subject: [PATCH 21/51] client: Simplify round trip behavior
|
||||||
|
|
||||||
|
The custom event queue was removed in
|
||||||
|
302d4ffb8549214eb4028dc3e47ec4ee4e12ffbd (2015) so the comment about not
|
||||||
|
being able to use the inbuilt round trip method no longer applies.
|
||||||
|
|
||||||
|
This fixes a real world problem. Use of a blocking round trip should not
|
||||||
|
process non wayland events. Doing so can lead to misbehaviour client
|
||||||
|
side as things happen out of order. The move to the event thread created
|
||||||
|
several regressions as we now get events before the QGuiApplication is
|
||||||
|
fully constructed.
|
||||||
|
|
||||||
|
Change-Id: I650481f49a47ed1a9778c7e1bc3c48db6e8f0031
|
||||||
|
Reviewed-by: Vlad Zahorodnii <vlad.zahorodnii@kde.org>
|
||||||
|
Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io>
|
||||||
|
(cherry picked from commit 62646d9122845d7bd9104b610478cebde3e769c7)
|
||||||
|
---
|
||||||
|
src/client/qwaylanddisplay.cpp | 43 +---------------------------------
|
||||||
|
1 file changed, 1 insertion(+), 42 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/client/qwaylanddisplay.cpp b/src/client/qwaylanddisplay.cpp
|
||||||
|
index ebcdbd22..d371ffec 100644
|
||||||
|
--- a/src/client/qwaylanddisplay.cpp
|
||||||
|
+++ b/src/client/qwaylanddisplay.cpp
|
||||||
|
@@ -615,50 +615,9 @@ uint32_t QWaylandDisplay::currentTimeMillisec()
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
-static void
|
||||||
|
-sync_callback(void *data, struct wl_callback *callback, uint32_t serial)
|
||||||
|
-{
|
||||||
|
- Q_UNUSED(serial)
|
||||||
|
- bool *done = static_cast<bool *>(data);
|
||||||
|
-
|
||||||
|
- *done = true;
|
||||||
|
-
|
||||||
|
- // If the wl_callback done event is received after the condition check in the while loop in
|
||||||
|
- // forceRoundTrip(), but before the call to processEvents, the call to processEvents may block
|
||||||
|
- // forever if no more events are posted (eventhough the callback is handled in response to the
|
||||||
|
- // aboutToBlock signal). Hence, we wake up the event dispatcher so forceRoundTrip may return.
|
||||||
|
- // (QTBUG-64696)
|
||||||
|
- if (auto *dispatcher = QThread::currentThread()->eventDispatcher())
|
||||||
|
- dispatcher->wakeUp();
|
||||||
|
-
|
||||||
|
- wl_callback_destroy(callback);
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
-static const struct wl_callback_listener sync_listener = {
|
||||||
|
- sync_callback
|
||||||
|
-};
|
||||||
|
-
|
||||||
|
void QWaylandDisplay::forceRoundTrip()
|
||||||
|
{
|
||||||
|
- // wl_display_roundtrip() works on the main queue only,
|
||||||
|
- // but we use a separate one, so basically reimplement it here
|
||||||
|
- int ret = 0;
|
||||||
|
- bool done = false;
|
||||||
|
- wl_callback *callback = wl_display_sync(mDisplay);
|
||||||
|
- wl_callback_add_listener(callback, &sync_listener, &done);
|
||||||
|
- flushRequests();
|
||||||
|
- if (QThread::currentThread()->eventDispatcher()) {
|
||||||
|
- while (!done && ret >= 0) {
|
||||||
|
- QThread::currentThread()->eventDispatcher()->processEvents(QEventLoop::WaitForMoreEvents);
|
||||||
|
- ret = wl_display_dispatch_pending(mDisplay);
|
||||||
|
- }
|
||||||
|
- } else {
|
||||||
|
- while (!done && ret >= 0)
|
||||||
|
- ret = wl_display_dispatch(mDisplay);
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- if (ret == -1 && !done)
|
||||||
|
- wl_callback_destroy(callback);
|
||||||
|
+ wl_display_roundtrip(mDisplay);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool QWaylandDisplay::supportsWindowDecoration() const
|
||||||
|
--
|
||||||
|
2.40.1
|
||||||
|
|
||||||
31
0022-Client-Fix-opaque-region-setter.patch
Normal file
31
0022-Client-Fix-opaque-region-setter.patch
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
From 0cf12729a90380d3ef11efebfbfa9458c397d592 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Vlad Zahorodnii <vlad.zahorodnii@kde.org>
|
||||||
|
Date: Sat, 19 Feb 2022 17:01:04 +0200
|
||||||
|
Subject: [PATCH 22/51] Client: Fix opaque region setter
|
||||||
|
|
||||||
|
The rect is in the global coordinate system, while the opaque region
|
||||||
|
must be in the surface local coordinate system.
|
||||||
|
|
||||||
|
Change-Id: I75042b4d779dfd4dfe610aad1f0387879f11b048
|
||||||
|
Reviewed-by: Aleix Pol Gonzalez <aleixpol@kde.org>
|
||||||
|
(cherry picked from commit f9425f573b18c0b66fd9ad9c2805e8b8b9a3ec77)
|
||||||
|
---
|
||||||
|
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 de5af1bd..69319228 100644
|
||||||
|
--- a/src/client/qwaylandwindow.cpp
|
||||||
|
+++ b/src/client/qwaylandwindow.cpp
|
||||||
|
@@ -372,7 +372,7 @@ void QWaylandWindow::setGeometry(const QRect &rect)
|
||||||
|
mShellSurface->setWindowGeometry(windowContentGeometry());
|
||||||
|
|
||||||
|
if (isOpaque() && mMask.isEmpty())
|
||||||
|
- setOpaqueArea(rect);
|
||||||
|
+ setOpaqueArea(QRect(QPoint(0, 0), rect.size()));
|
||||||
|
}
|
||||||
|
|
||||||
|
void QWaylandWindow::resizeFromApplyConfigure(const QSize &sizeWithMargins, const QPoint &offset)
|
||||||
|
--
|
||||||
|
2.40.1
|
||||||
|
|
||||||
@ -1,31 +0,0 @@
|
|||||||
From 1ccebbab3a42690a0812e2c4c76016799bf6cf1f 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 22/30] 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.31.1
|
|
||||||
|
|
||||||
126
0023-Use-proper-dependencies-in-compile-tests.patch
Normal file
126
0023-Use-proper-dependencies-in-compile-tests.patch
Normal file
@ -0,0 +1,126 @@
|
|||||||
|
From 1ab149c13af4806ef950487e2d9db8a937645791 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Fabian Vogt <fabian@ritter-vogt.de>
|
||||||
|
Date: Fri, 4 Feb 2022 11:07:36 +0100
|
||||||
|
Subject: [PATCH 23/51] Use proper dependencies in compile tests
|
||||||
|
|
||||||
|
Use the dependencies as found by the "libraries" section instead of relying
|
||||||
|
on them being available in the default location (e.g. "-ldrm").
|
||||||
|
|
||||||
|
Additionally, VK_USE_PLATFORM_WAYLAND_KHR requires <wayland-client.h>, so
|
||||||
|
add the wayland-client dependency.
|
||||||
|
|
||||||
|
This fixes those tests if e.g. wayland-client headers need to be found through
|
||||||
|
pkgconfig.
|
||||||
|
|
||||||
|
This part of the code changed completely in Qt 6, so this is a totally
|
||||||
|
different patch and not a cherry-pick of 5fc2e1915c3a
|
||||||
|
("CMake: Fix qtwayland feature detection").
|
||||||
|
|
||||||
|
Fixes: QTBUG-100475
|
||||||
|
---
|
||||||
|
src/client/configure.json | 8 ++++----
|
||||||
|
src/compositor/configure.json | 34 +++++++++++++++++++++++++++++-----
|
||||||
|
2 files changed, 33 insertions(+), 9 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/client/configure.json b/src/client/configure.json
|
||||||
|
index 2f424580..29222357 100644
|
||||||
|
--- a/src/client/configure.json
|
||||||
|
+++ b/src/client/configure.json
|
||||||
|
@@ -149,8 +149,7 @@
|
||||||
|
"#endif"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
- "libs": "-ldrm",
|
||||||
|
- "use": "egl"
|
||||||
|
+ "use": "drm egl"
|
||||||
|
},
|
||||||
|
"vulkan-server-buffer": {
|
||||||
|
"label": "Vulkan Buffer Sharing",
|
||||||
|
@@ -168,7 +167,8 @@
|
||||||
|
"exportAllocInfo.handleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHR;",
|
||||||
|
"return 0;"
|
||||||
|
]
|
||||||
|
- }
|
||||||
|
+ },
|
||||||
|
+ "use": "wayland-client"
|
||||||
|
},
|
||||||
|
"egl_1_5-wayland": {
|
||||||
|
"label": "EGL 1.5 with Wayland Platform",
|
||||||
|
@@ -183,7 +183,7 @@
|
||||||
|
"eglGetPlatformDisplay(EGL_PLATFORM_WAYLAND_EXT, (struct wl_display *)(nullptr), nullptr);"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
- "use": "egl"
|
||||||
|
+ "use": "egl wayland-client"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
diff --git a/src/compositor/configure.json b/src/compositor/configure.json
|
||||||
|
index bcfd5215..da95d07b 100644
|
||||||
|
--- a/src/compositor/configure.json
|
||||||
|
+++ b/src/compositor/configure.json
|
||||||
|
@@ -7,6 +7,31 @@
|
||||||
|
"testDir": "../../config.tests",
|
||||||
|
|
||||||
|
"libraries": {
|
||||||
|
+ "wayland-client": {
|
||||||
|
+ "label": "Wayland client library",
|
||||||
|
+ "headers": "wayland-version.h",
|
||||||
|
+ "test": {
|
||||||
|
+ "main": [
|
||||||
|
+ "#if WAYLAND_VERSION_MAJOR < 1",
|
||||||
|
+ "# error Wayland 1.8.0 or higher required",
|
||||||
|
+ "#endif",
|
||||||
|
+ "#if WAYLAND_VERSION_MAJOR == 1",
|
||||||
|
+ "# if WAYLAND_VERSION_MINOR < 8",
|
||||||
|
+ "# error Wayland 1.8.0 or higher required",
|
||||||
|
+ "# endif",
|
||||||
|
+ "# if WAYLAND_VERSION_MINOR == 8",
|
||||||
|
+ "# if WAYLAND_VERSION_MICRO < 0",
|
||||||
|
+ "# error Wayland 1.8.0 or higher required",
|
||||||
|
+ "# endif",
|
||||||
|
+ "# endif",
|
||||||
|
+ "#endif"
|
||||||
|
+ ]
|
||||||
|
+ },
|
||||||
|
+ "sources": [
|
||||||
|
+ { "type": "pkgConfig", "args": "wayland-client" },
|
||||||
|
+ "-lwayland-client"
|
||||||
|
+ ]
|
||||||
|
+ },
|
||||||
|
"wayland-server": {
|
||||||
|
"label": "wayland-server",
|
||||||
|
"headers": "wayland-version.h",
|
||||||
|
@@ -151,8 +176,7 @@
|
||||||
|
"#endif"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
- "libs": "-ldrm",
|
||||||
|
- "use": "egl"
|
||||||
|
+ "use": "drm egl"
|
||||||
|
},
|
||||||
|
"dmabuf-client-buffer": {
|
||||||
|
"label": "Linux Client dma-buf Buffer Sharing",
|
||||||
|
@@ -176,8 +200,7 @@
|
||||||
|
"return 0;"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
- "libs": "-ldrm",
|
||||||
|
- "use": "egl"
|
||||||
|
+ "use": "drm egl"
|
||||||
|
},
|
||||||
|
"vulkan-server-buffer": {
|
||||||
|
"label": "Vulkan Buffer Sharing",
|
||||||
|
@@ -195,7 +218,8 @@
|
||||||
|
"exportAllocInfo.handleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHR;",
|
||||||
|
"return 0;"
|
||||||
|
]
|
||||||
|
- }
|
||||||
|
+ },
|
||||||
|
+ "use": "wayland-client"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
--
|
||||||
|
2.40.1
|
||||||
|
|
||||||
59
0024-Revert-Client-Remove-mWaitingForUpdateDelivery.patch
Normal file
59
0024-Revert-Client-Remove-mWaitingForUpdateDelivery.patch
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
From 16d52e9ad900a25a02ff4eae43cc7d7e43dbad8a 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/51] 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.1
|
||||||
|
|
||||||
59
0025-Fix-race-condition-on-mWaitingForUpdateDelivery.patch
Normal file
59
0025-Fix-race-condition-on-mWaitingForUpdateDelivery.patch
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
From 2a7884f0d51d4da20e675640b8d987004c9d77c5 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/51] 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.1
|
||||||
|
|
||||||
48
0026-use-poll-2-when-reading-from-clipboard.patch
Normal file
48
0026-use-poll-2-when-reading-from-clipboard.patch
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
From ddfa956f6c39c53249116b979f679b255ed4a596 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/51] 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.1
|
||||||
|
|
||||||
31
0027-Reduce-memory-leakage.patch
Normal file
31
0027-Reduce-memory-leakage.patch
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
From b981fc82eb37700353949c72d3fd6d0887c8c107 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/51] 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.1
|
||||||
|
|
||||||
32
0028-Fix-build-with-libcxx-missing-array-include.patch
Normal file
32
0028-Fix-build-with-libcxx-missing-array-include.patch
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
From 91afb601e33f492393f7b27a84aa281b55d26de2 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/51] 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.1
|
||||||
|
|
||||||
@ -1,44 +0,0 @@
|
|||||||
From d4c41797b61a5a8da47c5821711aca72e756dcbf Mon Sep 17 00:00:00 2001
|
|
||||||
From: Aleix Pol <aleixpol@kde.org>
|
|
||||||
Date: Tue, 13 Jul 2021 13:32:15 +0200
|
|
||||||
Subject: [PATCH 29/30] 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.31.1
|
|
||||||
|
|
||||||
401
0029-Only-close-popup-in-the-the-hierchary.patch
Normal file
401
0029-Only-close-popup-in-the-the-hierchary.patch
Normal file
@ -0,0 +1,401 @@
|
|||||||
|
From 76a2b1919f04152e77740b2d1601df893b8d79ba 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/51] 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 9a362b74..ead99989 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;
|
||||||
|
m_grabbing = false;
|
||||||
|
|
||||||
|
// Synthesize Qt enter/leave events for popup
|
||||||
|
@@ -403,8 +412,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
|
||||||
|
@@ -421,8 +428,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.1
|
||||||
|
|
||||||
34
0030-Check-pointer-for-null-before-use-in-ASSERT.patch
Normal file
34
0030-Check-pointer-for-null-before-use-in-ASSERT.patch
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
From b14eb8fdac3bfa2763a83541a3e4764c0eac153e Mon Sep 17 00:00:00 2001
|
||||||
|
From: Roman Genkhel <roman.genhel@lge.com>
|
||||||
|
Date: Thu, 12 Nov 2020 12:21:51 +0300
|
||||||
|
Subject: [PATCH 30/51] Check pointer for null before use in ASSERT
|
||||||
|
|
||||||
|
Task-number: QTBUG-85195
|
||||||
|
Change-Id: I331e54f6e58aa9d536351a55223610c60b3cb414
|
||||||
|
Reviewed-by: David Edmundson <davidedmundson@kde.org>
|
||||||
|
(cherry picked from commit e235e8ddb1fc3cc5ab3b70b1fb285770b2c8c9ca)
|
||||||
|
---
|
||||||
|
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 9e82c174..0a5fc15b 100644
|
||||||
|
--- a/src/client/qwaylandwindow.cpp
|
||||||
|
+++ b/src/client/qwaylandwindow.cpp
|
||||||
|
@@ -536,12 +536,12 @@ void QWaylandWindow::sendRecursiveExposeEvent()
|
||||||
|
|
||||||
|
void QWaylandWindow::attach(QWaylandBuffer *buffer, int x, int y)
|
||||||
|
{
|
||||||
|
- Q_ASSERT(!buffer->committed());
|
||||||
|
QReadLocker locker(&mSurfaceLock);
|
||||||
|
if (mSurface == nullptr)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (buffer) {
|
||||||
|
+ Q_ASSERT(!buffer->committed());
|
||||||
|
handleUpdate();
|
||||||
|
buffer->setBusy();
|
||||||
|
|
||||||
|
--
|
||||||
|
2.40.1
|
||||||
|
|
||||||
131
0031-Use-wl_surface.damage_buffer-on-the-client-side.patch
Normal file
131
0031-Use-wl_surface.damage_buffer-on-the-client-side.patch
Normal file
@ -0,0 +1,131 @@
|
|||||||
|
From 7daab1d4a36463f0904fdde539894609f8b367c1 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Paul Olav Tvete <paul.tvete@qt.io>
|
||||||
|
Date: Mon, 6 Jul 2020 14:37:35 +0200
|
||||||
|
Subject: [PATCH 31/51] Use wl_surface.damage_buffer on the client side
|
||||||
|
|
||||||
|
Prefer the newer, recommended damage_buffer when the compositor
|
||||||
|
supports it.
|
||||||
|
|
||||||
|
Fixes: QTBUG-74929
|
||||||
|
Change-Id: I9107966910b616a666931404a7b41bfac14c22c0
|
||||||
|
Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io>
|
||||||
|
(cherry picked from commit 314fd6db51277224cdc799b039ef79db1101f5cd)
|
||||||
|
---
|
||||||
|
src/client/qwaylanddisplay.cpp | 2 +-
|
||||||
|
src/client/qwaylandwindow.cpp | 16 +++++++++++++---
|
||||||
|
tests/auto/client/shared/coreprotocol.h | 2 +-
|
||||||
|
tests/auto/client/shared_old/mockcompositor.cpp | 2 +-
|
||||||
|
tests/auto/client/shared_old/mocksurface.cpp | 10 ++++++++++
|
||||||
|
tests/auto/client/shared_old/mocksurface.h | 2 ++
|
||||||
|
6 files changed, 28 insertions(+), 6 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/client/qwaylanddisplay.cpp b/src/client/qwaylanddisplay.cpp
|
||||||
|
index 1b9ec699..6898a881 100644
|
||||||
|
--- a/src/client/qwaylanddisplay.cpp
|
||||||
|
+++ b/src/client/qwaylanddisplay.cpp
|
||||||
|
@@ -493,7 +493,7 @@ void QWaylandDisplay::registry_global(uint32_t id, const QString &interface, uin
|
||||||
|
if (interface == QStringLiteral("wl_output")) {
|
||||||
|
mWaitingScreens << new QWaylandScreen(this, version, id);
|
||||||
|
} else if (interface == QStringLiteral("wl_compositor")) {
|
||||||
|
- mCompositorVersion = qMin((int)version, 3);
|
||||||
|
+ mCompositorVersion = qMin((int)version, 4);
|
||||||
|
mCompositor.init(registry, id, mCompositorVersion);
|
||||||
|
} else if (interface == QStringLiteral("wl_shm")) {
|
||||||
|
mShm.reset(new QWaylandShm(this, version, id));
|
||||||
|
diff --git a/src/client/qwaylandwindow.cpp b/src/client/qwaylandwindow.cpp
|
||||||
|
index 0a5fc15b..5b7f9df9 100644
|
||||||
|
--- a/src/client/qwaylandwindow.cpp
|
||||||
|
+++ b/src/client/qwaylandwindow.cpp
|
||||||
|
@@ -563,7 +563,11 @@ void QWaylandWindow::damage(const QRect &rect)
|
||||||
|
if (mSurface == nullptr)
|
||||||
|
return;
|
||||||
|
|
||||||
|
- mSurface->damage(rect.x(), rect.y(), rect.width(), rect.height());
|
||||||
|
+ const int s = scale();
|
||||||
|
+ if (mDisplay->compositorVersion() >= 4)
|
||||||
|
+ mSurface->damage_buffer(s * rect.x(), s * rect.y(), s * rect.width(), s * rect.height());
|
||||||
|
+ else
|
||||||
|
+ mSurface->damage(rect.x(), rect.y(), rect.width(), rect.height());
|
||||||
|
}
|
||||||
|
|
||||||
|
void QWaylandWindow::safeCommit(QWaylandBuffer *buffer, const QRegion &damage)
|
||||||
|
@@ -599,8 +603,14 @@ void QWaylandWindow::commit(QWaylandBuffer *buffer, const QRegion &damage)
|
||||||
|
return;
|
||||||
|
|
||||||
|
attachOffset(buffer);
|
||||||
|
- for (const QRect &rect: damage)
|
||||||
|
- mSurface->damage(rect.x(), rect.y(), rect.width(), rect.height());
|
||||||
|
+ if (mDisplay->compositorVersion() >= 4) {
|
||||||
|
+ const int s = scale();
|
||||||
|
+ for (const QRect &rect: damage)
|
||||||
|
+ mSurface->damage_buffer(s * rect.x(), s * rect.y(), s * rect.width(), s * rect.height());
|
||||||
|
+ } else {
|
||||||
|
+ for (const QRect &rect: damage)
|
||||||
|
+ mSurface->damage(rect.x(), rect.y(), rect.width(), rect.height());
|
||||||
|
+ }
|
||||||
|
Q_ASSERT(!buffer->committed());
|
||||||
|
buffer->setCommitted();
|
||||||
|
mSurface->commit();
|
||||||
|
diff --git a/tests/auto/client/shared/coreprotocol.h b/tests/auto/client/shared/coreprotocol.h
|
||||||
|
index a1af137a..296dbf47 100644
|
||||||
|
--- a/tests/auto/client/shared/coreprotocol.h
|
||||||
|
+++ b/tests/auto/client/shared/coreprotocol.h
|
||||||
|
@@ -158,7 +158,7 @@ class WlCompositor : public Global, public QtWaylandServer::wl_compositor
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
- explicit WlCompositor(CoreCompositor *compositor, int version = 3)
|
||||||
|
+ explicit WlCompositor(CoreCompositor *compositor, int version = 4)
|
||||||
|
: QtWaylandServer::wl_compositor(compositor->m_display, version)
|
||||||
|
, m_compositor(compositor)
|
||||||
|
{}
|
||||||
|
diff --git a/tests/auto/client/shared_old/mockcompositor.cpp b/tests/auto/client/shared_old/mockcompositor.cpp
|
||||||
|
index a415cbf5..b1d3d07d 100644
|
||||||
|
--- a/tests/auto/client/shared_old/mockcompositor.cpp
|
||||||
|
+++ b/tests/auto/client/shared_old/mockcompositor.cpp
|
||||||
|
@@ -342,7 +342,7 @@ Compositor::Compositor(MockCompositor *mockCompositor)
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
- wl_global_create(m_display, &wl_compositor_interface, 1, this, bindCompositor);
|
||||||
|
+ wl_global_create(m_display, &wl_compositor_interface, 4, this, bindCompositor);
|
||||||
|
|
||||||
|
m_data_device_manager.reset(new DataDeviceManager(this, m_display));
|
||||||
|
|
||||||
|
diff --git a/tests/auto/client/shared_old/mocksurface.cpp b/tests/auto/client/shared_old/mocksurface.cpp
|
||||||
|
index e9df5f90..c3246e4a 100644
|
||||||
|
--- a/tests/auto/client/shared_old/mocksurface.cpp
|
||||||
|
+++ b/tests/auto/client/shared_old/mocksurface.cpp
|
||||||
|
@@ -125,6 +125,16 @@ void Surface::surface_damage(Resource *resource,
|
||||||
|
Q_UNUSED(height);
|
||||||
|
}
|
||||||
|
|
||||||
|
+void Surface::surface_damage_buffer(Resource *resource,
|
||||||
|
+ int32_t x, int32_t y, int32_t width, int32_t height)
|
||||||
|
+{
|
||||||
|
+ Q_UNUSED(resource);
|
||||||
|
+ Q_UNUSED(x);
|
||||||
|
+ Q_UNUSED(y);
|
||||||
|
+ Q_UNUSED(width);
|
||||||
|
+ Q_UNUSED(height);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
void Surface::surface_frame(Resource *resource,
|
||||||
|
uint32_t callback)
|
||||||
|
{
|
||||||
|
diff --git a/tests/auto/client/shared_old/mocksurface.h b/tests/auto/client/shared_old/mocksurface.h
|
||||||
|
index 949dc23d..d176837e 100644
|
||||||
|
--- a/tests/auto/client/shared_old/mocksurface.h
|
||||||
|
+++ b/tests/auto/client/shared_old/mocksurface.h
|
||||||
|
@@ -65,6 +65,8 @@ protected:
|
||||||
|
struct wl_resource *buffer, int x, int y) override;
|
||||||
|
void surface_damage(Resource *resource,
|
||||||
|
int32_t x, int32_t y, int32_t width, int32_t height) override;
|
||||||
|
+ void surface_damage_buffer(Resource *resource,
|
||||||
|
+ int32_t x, int32_t y, int32_t width, int32_t height) override;
|
||||||
|
void surface_frame(Resource *resource,
|
||||||
|
uint32_t callback) override;
|
||||||
|
void surface_commit(Resource *resource) override;
|
||||||
|
--
|
||||||
|
2.40.1
|
||||||
|
|
||||||
116
0032-Client-clear-focus-on-touch-cancel.patch
Normal file
116
0032-Client-clear-focus-on-touch-cancel.patch
Normal file
@ -0,0 +1,116 @@
|
|||||||
|
From 152984fa2347a2f02568ac6cd9baba5bd8e4d56d Mon Sep 17 00:00:00 2001
|
||||||
|
From: David Edmundson <davidedmundson@kde.org>
|
||||||
|
Date: Fri, 5 Aug 2022 15:00:31 +0100
|
||||||
|
Subject: [PATCH 32/51] 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.1
|
||||||
|
|
||||||
39
0033-Guard-mResizeDirty-by-the-correctMutex.patch
Normal file
39
0033-Guard-mResizeDirty-by-the-correctMutex.patch
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
From 11824dcf4164898a48b0629a072370a195dcc8f1 Mon Sep 17 00:00:00 2001
|
||||||
|
From: David Edmundson <davidedmundson@kde.org>
|
||||||
|
Date: Thu, 3 Feb 2022 19:42:33 +0000
|
||||||
|
Subject: [PATCH 33/51] 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.1
|
||||||
|
|
||||||
29
0034-Fix-compile-tests.patch
Normal file
29
0034-Fix-compile-tests.patch
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
From 8e2f1b74e780b998ab682d9abbd53feeceaa819e 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 34/51] 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.1
|
||||||
|
|
||||||
40
0035-Use-CRLF-line-delimiter-for-text-uri-list-data.patch
Normal file
40
0035-Use-CRLF-line-delimiter-for-text-uri-list-data.patch
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
From a7c3f946175a78df45b1eb3301cf16a05a542d58 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 35/51] 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.1
|
||||||
|
|
||||||
43
0036-Avoid-calling-requestUpdate-from-wrong-thread.patch
Normal file
43
0036-Avoid-calling-requestUpdate-from-wrong-thread.patch
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
From 36522a8ed9f43cd49100e06040711de9c2c0c163 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 36/51] 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.1
|
||||||
|
|
||||||
@ -0,0 +1,38 @@
|
|||||||
|
From 3f0371cb22e117020e57255858e02f9237210a3b Mon Sep 17 00:00:00 2001
|
||||||
|
From: Fushan Wen <qydwhotmail@gmail.com>
|
||||||
|
Date: Sun, 18 Sep 2022 18:17:18 +0800
|
||||||
|
Subject: [PATCH 37/51] 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.1
|
||||||
|
|
||||||
@ -0,0 +1,85 @@
|
|||||||
|
From 20bef824f4b78598fbffa5ada8271e22b658f635 Mon Sep 17 00:00:00 2001
|
||||||
|
From: David Edmundson <davidedmundson@kde.org>
|
||||||
|
Date: Mon, 12 Sep 2022 13:28:08 +0100
|
||||||
|
Subject: [PATCH 38/51] 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.1
|
||||||
|
|
||||||
@ -0,0 +1,90 @@
|
|||||||
|
From 6481efa9a8fe88043d931648d72dceeeb91af64d 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 39/51] 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 4ddf9fbe..f322a8d6 100644
|
||||||
|
--- a/src/client/qwaylandwindow.cpp
|
||||||
|
+++ b/src/client/qwaylandwindow.cpp
|
||||||
|
@@ -350,8 +350,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()) {
|
||||||
|
@@ -1033,6 +1038,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 ea3d1995..487a91a6 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.1
|
||||||
|
|
||||||
53
0040-Client-Add-F_SEAL_SHRINK-seal-to-shm-backing-file.patch
Normal file
53
0040-Client-Add-F_SEAL_SHRINK-seal-to-shm-backing-file.patch
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
From 3b29b796f98721cb52c89a56e28ff8f9b830ebc5 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 40/51] 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.1
|
||||||
|
|
||||||
@ -0,0 +1,31 @@
|
|||||||
|
From 36a9d60c3ed05e2ec8faf7e81946becfaeb2f1d5 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 41/51] 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.1
|
||||||
|
|
||||||
30
0042-Client-Bump-wl_output-version.patch
Normal file
30
0042-Client-Bump-wl_output-version.patch
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
From 4293409e97c6ecfaec49b87818f9b439010187c9 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 42/51] 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.1
|
||||||
|
|
||||||
166
0043-Fix-frame-sync-related-to-unprotected-multithread-ac.patch
Normal file
166
0043-Fix-frame-sync-related-to-unprotected-multithread-ac.patch
Normal file
@ -0,0 +1,166 @@
|
|||||||
|
From 7c43759079528c33c30c4a823de7fb2dff6acd27 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Weng Xuetian <wengxt@gmail.com>
|
||||||
|
Date: Sun, 27 Nov 2022 12:44:40 -0800
|
||||||
|
Subject: [PATCH 43/51] 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.1
|
||||||
|
|
||||||
@ -0,0 +1,66 @@
|
|||||||
|
From 817655fa798fc2d640b4db006df229c335e02c3b 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 44/51] 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.1
|
||||||
|
|
||||||
26
0045-Fixes-the-build-on-CentOS.patch
Normal file
26
0045-Fixes-the-build-on-CentOS.patch
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
From 9e03f149e70896d92b51d9c25af681ddc2b5acfb Mon Sep 17 00:00:00 2001
|
||||||
|
From: Aleix Pol <aleixpol@kde.org>
|
||||||
|
Date: Mon, 19 Dec 2022 15:31:03 +0100
|
||||||
|
Subject: [PATCH 45/51] 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.1
|
||||||
|
|
||||||
@ -0,0 +1,56 @@
|
|||||||
|
From 5028633b140c013b14a487889eeef992233d4edf 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 46/51] 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.1
|
||||||
|
|
||||||
38
0047-Client-Fix-handling-of-Qt-BlankCursor.patch
Normal file
38
0047-Client-Fix-handling-of-Qt-BlankCursor.patch
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
From aeb7bf67a99fecf5f4e49ba7c49edf9c8b9db2b6 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 47/51] 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.1
|
||||||
|
|
||||||
117
0048-client-Force-a-roundtrip-when-an-XdgOutput-is-not-re.patch
Normal file
117
0048-client-Force-a-roundtrip-when-an-XdgOutput-is-not-re.patch
Normal file
@ -0,0 +1,117 @@
|
|||||||
|
From 2e4c35db38a55243bc2458dc87cc9ff6afb81586 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Marco Martin <notmart@gmail.com>
|
||||||
|
Date: Fri, 24 Feb 2023 17:40:48 +0100
|
||||||
|
Subject: [PATCH 48/51] 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.1
|
||||||
|
|
||||||
138
0049-Client-Manage-QMimeData-lifecycle.patch
Normal file
138
0049-Client-Manage-QMimeData-lifecycle.patch
Normal file
@ -0,0 +1,138 @@
|
|||||||
|
From dd8640794264449cb978765029fc4713f3fb31b9 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Tang Haixiang <tanghaixiang@uniontech.com>
|
||||||
|
Date: Thu, 22 Dec 2022 15:19:53 +0800
|
||||||
|
Subject: [PATCH 49/51] 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.1
|
||||||
|
|
||||||
@ -0,0 +1,34 @@
|
|||||||
|
From 346cebf39b90f7fe012f57e66d493634aba20f89 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Aleix Pol <aleixpol@kde.org>
|
||||||
|
Date: Mon, 6 Mar 2023 01:11:45 +0100
|
||||||
|
Subject: [PATCH 50/51] 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.1
|
||||||
|
|
||||||
41
0051-Client-Remove-flip-popup-constraints.patch
Normal file
41
0051-Client-Remove-flip-popup-constraints.patch
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
From aabaa4efd1d284f07c3cb5b8a7d62a9143701bc4 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 51/51] 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.1
|
||||||
|
|
||||||
@ -2,44 +2,75 @@
|
|||||||
%global qt_module qtwayland
|
%global qt_module qtwayland
|
||||||
|
|
||||||
Name: qt5-%{qt_module}
|
Name: qt5-%{qt_module}
|
||||||
Version: 5.15.2
|
Version: 5.15.10
|
||||||
Release: 1
|
Release: 1
|
||||||
Summary: Qt5 - Wayland platform support and QtCompositor module
|
Summary: Qt5 - Wayland platform support and QtCompositor module
|
||||||
License: LGPLv3
|
License: LGPL-3.0-only OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||||
Url: http://www.qt.io
|
Url: http://www.qt.io
|
||||||
%global majmin %(echo %{version} | cut -d. -f1-2)
|
%global majmin %(echo %{version} | cut -d. -f1-2)
|
||||||
Source0: https://download.qt.io/official_releases/qt/%{majmin}/%{version}/submodules/%{qt_module}-everywhere-src-%{version}.tar.xz
|
Source0: https://download.qt.io/official_releases/qt/%{majmin}/%{version}/submodules/%{qt_module}-everywhere-opensource-src-%{version}.tar.xz
|
||||||
|
|
||||||
Patch00: 0005-Scanner-Avoid-accessing-dangling-pointers-in-destroy.patch
|
## Upstream patches
|
||||||
Patch01: 0006-Make-setting-QT_SCALE_FACTOR-work-on-Wayland.patch
|
## repo: https://invent.kde.org/qt/qt/qtwayland
|
||||||
Patch02: 0007-Do-not-try-to-eglMakeCurrent-for-unintended-case.patch
|
## branch: kde/5.15
|
||||||
Patch03: 0008-Make-setting-QT_SCALE_FACTOR-work-on-Wayland.patch
|
## git format-patch v5.15.8-lts-lgpl
|
||||||
Patch04: 0009-Ensure-that-grabbing-is-performed-in-correct-context.patch
|
Patch1: 0001-Client-Announce-an-output-after-receiving-more-compl.patch
|
||||||
Patch05: 0010-Fix-leaked-subsurface-wayland-items.patch
|
Patch2: 0002-Fix-issue-with-repeated-window-size-changes.patch
|
||||||
Patch06: 0011-Use-qWarning-and-_exit-instead-of-qFatal-for-wayland.patch
|
Patch3: 0003-Client-Connect-drags-being-accepted-to-updating-the-.patch
|
||||||
Patch07: 0012-Fix-memory-leak-in-QWaylandGLContext.patch
|
Patch4: 0004-Client-Disconnect-registry-listener-on-destruction.patch
|
||||||
Patch08: 0013-Client-Send-set_window_geometry-only-once-configured.patch
|
Patch5: 0005-Client-Set-XdgShell-size-hints-before-the-first-comm.patch
|
||||||
Patch09: 0014-Translate-opaque-area-with-frame-margins.patch
|
Patch6: 0006-Fix-build.patch
|
||||||
Patch10: 0015-Client-Send-exposeEvent-to-parent-on-subsurface-posi.patch
|
Patch7: 0007-Fix-remove-listener.patch
|
||||||
Patch11: 0016-Get-correct-decoration-margins-region.patch
|
Patch8: 0008-Hook-up-queryKeyboardModifers.patch
|
||||||
Patch12: 0017-xdgshell-Tell-the-compositor-the-screen-we-re-expect.patch
|
Patch9: 0009-Correctly-detect-if-image-format-is-supported-by-QIm.patch
|
||||||
Patch13: 0018-Fix-compilation.patch
|
Patch10: 0010-Client-Don-t-always-recreate-frame-callbacks.patch
|
||||||
Patch14: 0019-client-Allow-QWaylandInputContext-to-accept-composed.patch
|
Patch11: 0011-Client-Always-destroy-frame-callback-in-the-actual-c.patch
|
||||||
Patch15: 0020-Client-Announce-an-output-after-receiving-more-compl.patch
|
Patch12: 0012-Wayland-client-use-wl_keyboard-to-determine-active-s.patch
|
||||||
Patch16: 0021-Fix-issue-with-repeated-window-size-changes.patch
|
Patch13: 0013-Client-do-not-empty-clipboard-when-a-new-popup-windo.patch
|
||||||
Patch17: 0022-Include-locale.h-for-setlocale-LC_CTYPE.patch
|
Patch14: 0014-Client-Implement-DataDeviceV3.patch
|
||||||
Patch18: 0023-Client-Connect-drags-being-accepted-to-updating-the-.patch
|
Patch15: 0015-Client-Delay-deletion-of-QDrag-object-until-after-we.patch
|
||||||
Patch19: 0024-Client-Disconnect-registry-listener-on-destruction.patch
|
Patch16: 0016-Client-Avoid-processing-of-events-when-showing-windo.patch
|
||||||
Patch20: 0025-Client-Set-XdgShell-size-hints-before-the-first-comm.patch
|
Patch17: 0017-Handle-registry_global-out-of-constructor.patch
|
||||||
Patch21: 0026-Fix-build.patch
|
Patch18: 0018-Connect-flushRequest-after-forceRoundTrip.patch
|
||||||
Patch22: 0027-Fix-remove-listener.patch
|
Patch19: 0019-Move-the-wayland-socket-polling-to-a-separate-event-.patch
|
||||||
Patch23: 0028-Hook-up-queryKeyboardModifers.patch
|
Patch20: 0020-Client-Remove-mWaitingForUpdateDelivery.patch
|
||||||
Patch24: 0029-Do-not-update-the-mask-if-we-do-not-have-a-surface.patch
|
Patch21: 0021-client-Simplify-round-trip-behavior.patch
|
||||||
Patch25: 0030-Correctly-detect-if-image-format-is-supported-by-QIm.patch
|
Patch22: 0022-Client-Fix-opaque-region-setter.patch
|
||||||
Patch26: qtwayland-client-expose-toplevel-window-state.patch
|
Patch23: 0023-Use-proper-dependencies-in-compile-tests.patch
|
||||||
Patch27: qtwayland-client-use-wl-keyboard-to-determine-active-state.patch
|
Patch24: 0024-Revert-Client-Remove-mWaitingForUpdateDelivery.patch
|
||||||
Patch28: qtwayland-client-do-not-empty-clipboard-when-new-popup-or-window-is-opened.patch
|
Patch25: 0025-Fix-race-condition-on-mWaitingForUpdateDelivery.patch
|
||||||
|
Patch26: 0026-use-poll-2-when-reading-from-clipboard.patch
|
||||||
|
Patch27: 0027-Reduce-memory-leakage.patch
|
||||||
|
Patch28: 0028-Fix-build-with-libcxx-missing-array-include.patch
|
||||||
|
Patch29: 0029-Only-close-popup-in-the-the-hierchary.patch
|
||||||
|
Patch30: 0030-Check-pointer-for-null-before-use-in-ASSERT.patch
|
||||||
|
Patch31: 0031-Use-wl_surface.damage_buffer-on-the-client-side.patch
|
||||||
|
Patch32: 0032-Client-clear-focus-on-touch-cancel.patch
|
||||||
|
Patch33: 0033-Guard-mResizeDirty-by-the-correctMutex.patch
|
||||||
|
Patch34: 0034-Fix-compile-tests.patch
|
||||||
|
Patch35: 0035-Use-CRLF-line-delimiter-for-text-uri-list-data.patch
|
||||||
|
Patch36: 0036-Avoid-calling-requestUpdate-from-wrong-thread.patch
|
||||||
|
Patch37: 0037-Call-finishDrag-in-QWaylandDataDevice-dragSourceCanc.patch
|
||||||
|
Patch38: 0038-Hold-surface-read-lock-throughout-QWaylandEglWindow-.patch
|
||||||
|
Patch39: 0039-Keep-toplevel-windows-in-the-top-left-corner-of-the-.patch
|
||||||
|
Patch40: 0040-Client-Add-F_SEAL_SHRINK-seal-to-shm-backing-file.patch
|
||||||
|
Patch41: 0041-Client-Call-wl_output_release-upon-QWaylandScreen-de.patch
|
||||||
|
Patch42: 0042-Client-Bump-wl_output-version.patch
|
||||||
|
Patch43: 0043-Fix-frame-sync-related-to-unprotected-multithread-ac.patch
|
||||||
|
Patch44: 0044-Client-Handle-zwp_primary_selection_device_manager_v.patch
|
||||||
|
Patch45: 0045-Fixes-the-build-on-CentOS.patch
|
||||||
|
Patch46: 0046-client-Avoid-protocol-error-with-invalid-min-max-siz.patch
|
||||||
|
Patch47: 0047-Client-Fix-handling-of-Qt-BlankCursor.patch
|
||||||
|
Patch48: 0048-client-Force-a-roundtrip-when-an-XdgOutput-is-not-re.patch
|
||||||
|
Patch49: 0049-Client-Manage-QMimeData-lifecycle.patch
|
||||||
|
Patch50: 0050-client-Do-not-cast-placeholder-screens-to-QWaylandSc.patch
|
||||||
|
Patch51: 0051-Client-Remove-flip-popup-constraints.patch
|
||||||
|
|
||||||
|
Patch102: qtwayland-decoration-support-backports-from-qt6.patch
|
||||||
|
|
||||||
|
# Upstreamable patches
|
||||||
|
|
||||||
|
# filter qml provides
|
||||||
%global __provides_exclude_from ^%{_qt5_archdatadir}/qml/.*\\.so$
|
%global __provides_exclude_from ^%{_qt5_archdatadir}/qml/.*\\.so$
|
||||||
|
|
||||||
BuildRequires: make
|
BuildRequires: make
|
||||||
@ -47,34 +78,32 @@ BuildRequires: qt5-qtbase-devel >= %{version}
|
|||||||
BuildRequires: qt5-qtbase-private-devel
|
BuildRequires: qt5-qtbase-private-devel
|
||||||
BuildRequires: qt5-qtbase-static
|
BuildRequires: qt5-qtbase-static
|
||||||
%{?_qt5:Requires: %{_qt5}%{?_isa} = %{_qt5_version}}
|
%{?_qt5:Requires: %{_qt5}%{?_isa} = %{_qt5_version}}
|
||||||
BuildRequires: qt5-qtdeclarative-devel libXext-devel
|
BuildRequires: qt5-qtdeclarative-devel
|
||||||
BuildRequires: pkgconfig(xkbcommon)
|
BuildRequires: pkgconfig(xkbcommon)
|
||||||
BuildRequires: pkgconfig(wayland-scanner) pkgconfig(wayland-server) pkgconfig(wayland-client)
|
BuildRequires: pkgconfig(wayland-scanner) pkgconfig(wayland-server) pkgconfig(wayland-client)
|
||||||
BuildRequires: pkgconfig(wayland-cursor) pkgconfig(wayland-egl)
|
BuildRequires: pkgconfig(wayland-cursor) pkgconfig(wayland-egl)
|
||||||
BuildRequires: pkgconfig(egl) pkgconfig(gl)
|
BuildRequires: pkgconfig(egl) pkgconfig(gl)
|
||||||
BuildRequires: pkgconfig(xcomposite) pkgconfig(xrender)
|
BuildRequires: pkgconfig(xcomposite) pkgconfig(xrender)
|
||||||
BuildRequires: pkgconfig(libudev) pkgconfig(libinput)
|
BuildRequires: pkgconfig(libudev) pkgconfig(libinput)
|
||||||
BuildRequires: tree
|
BuildRequires: libXext-devel
|
||||||
|
|
||||||
|
|
||||||
%package devel
|
|
||||||
Summary: Development files for %{name}
|
|
||||||
Requires: %{name}%{?_isa} = %{version}-%{release}
|
|
||||||
Requires: qt5-qtbase-devel%{?_isa}
|
|
||||||
|
|
||||||
%package help
|
|
||||||
Summary: Programming example files for %{name}
|
|
||||||
Requires: %{name}%{?_isa} = %{version}-%{release}
|
|
||||||
|
|
||||||
%description
|
%description
|
||||||
This package is a Qt 5 module that wraps the functionality of Wayland.
|
%{summary}.
|
||||||
|
|
||||||
|
%package devel
|
||||||
|
Summary: Development files for %{name}
|
||||||
|
Requires: %{name}%{?_isa} = %{version}-%{release}
|
||||||
|
Requires: qt5-qtbase-devel%{?_isa}
|
||||||
|
|
||||||
%description devel
|
%description devel
|
||||||
This package provide development files for %{name}
|
%{summary}.
|
||||||
|
|
||||||
%description help
|
%package examples
|
||||||
This package provide programming example files for %{name}
|
Summary: Programming example files for %{name}
|
||||||
|
Requires: %{name}%{?_isa} = %{version}-%{release}
|
||||||
|
|
||||||
|
%description examples
|
||||||
|
%{summary}.
|
||||||
|
|
||||||
%prep
|
%prep
|
||||||
%autosetup -n %{qt_module}-everywhere-src-%{version} -p1
|
%autosetup -n %{qt_module}-everywhere-src-%{version} -p1
|
||||||
@ -89,11 +118,11 @@ This package provide programming example files for %{name}
|
|||||||
make install INSTALL_ROOT=%{buildroot}
|
make install INSTALL_ROOT=%{buildroot}
|
||||||
|
|
||||||
pushd %{buildroot}%{_qt5_libdir}
|
pushd %{buildroot}%{_qt5_libdir}
|
||||||
for prl_file in libQt5*.prl; do
|
for prl_file in libQt5*.prl ; do
|
||||||
sed -i -e "/^QMAKE_PRL_BUILD_DIR/d" "${prl_file}"
|
sed -i -e "/^QMAKE_PRL_BUILD_DIR/d" ${prl_file}
|
||||||
if [[ -f "$(basename ${prl_file} .prl).so" ]]; then
|
if [ -f "$(basename ${prl_file} .prl).so" ]; then
|
||||||
rm -fv "$(basename ${prl_file} .prl).la"
|
rm -fv "$(basename ${prl_file} .prl).la"
|
||||||
sed -i -e "/^QMAKE_PRL_LIBS/d" "${prl_file}"
|
sed -i -e "/^QMAKE_PRL_LIBS/d" ${prl_file}
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
popd
|
popd
|
||||||
@ -106,41 +135,39 @@ popd
|
|||||||
%license LICENSE.*
|
%license LICENSE.*
|
||||||
%{_qt5_libdir}/libQt5WaylandCompositor.so.5*
|
%{_qt5_libdir}/libQt5WaylandCompositor.so.5*
|
||||||
%{_qt5_libdir}/libQt5WaylandClient.so.5*
|
%{_qt5_libdir}/libQt5WaylandClient.so.5*
|
||||||
|
|
||||||
%{_qt5_plugindir}/platforms/libqwayland-egl.so
|
|
||||||
%{_qt5_plugindir}/platforms/libqwayland-generic.so
|
|
||||||
%{_qt5_plugindir}/platforms/libqwayland-xcomposite*.so
|
|
||||||
|
|
||||||
%{_qt5_plugindir}/wayland-decoration-client/
|
%{_qt5_plugindir}/wayland-decoration-client/
|
||||||
%{_qt5_plugindir}/wayland-graphics-integration-server
|
%{_qt5_plugindir}/wayland-graphics-integration-server
|
||||||
%{_qt5_plugindir}/wayland-graphics-integration-client
|
%{_qt5_plugindir}/wayland-graphics-integration-client
|
||||||
%{_qt5_plugindir}/wayland-shell-integration
|
%{_qt5_plugindir}/wayland-shell-integration
|
||||||
|
%{_qt5_plugindir}/platforms/libqwayland-egl.so
|
||||||
|
%{_qt5_plugindir}/platforms/libqwayland-generic.so
|
||||||
|
%{_qt5_plugindir}/platforms/libqwayland-xcomposite-egl.so
|
||||||
|
%{_qt5_plugindir}/platforms/libqwayland-xcomposite-glx.so
|
||||||
%{_qt5_qmldir}/QtWayland/
|
%{_qt5_qmldir}/QtWayland/
|
||||||
|
|
||||||
%files devel
|
%files devel
|
||||||
%{_qt5_archdatadir}/mkspecs/modules/*.pri
|
|
||||||
%{_qt5_bindir}/qtwaylandscanner
|
%{_qt5_bindir}/qtwaylandscanner
|
||||||
|
|
||||||
%{_qt5_headerdir}/QtWaylandCompositor/
|
%{_qt5_headerdir}/QtWaylandCompositor/
|
||||||
%{_qt5_headerdir}/QtWaylandClient/
|
%{_qt5_headerdir}/QtWaylandClient/
|
||||||
|
|
||||||
%{_qt5_libdir}/cmake/Qt5WaylandCompositor/Qt5WaylandCompositorConfig*.cmake
|
|
||||||
%{_qt5_libdir}/libQt5WaylandCompositor.prl
|
|
||||||
%{_qt5_libdir}/libQt5WaylandCompositor.so
|
%{_qt5_libdir}/libQt5WaylandCompositor.so
|
||||||
%{_qt5_libdir}/libQt5WaylandClient.prl
|
|
||||||
%{_qt5_libdir}/libQt5WaylandClient.so
|
%{_qt5_libdir}/libQt5WaylandClient.so
|
||||||
|
%{_qt5_libdir}/libQt5WaylandCompositor.prl
|
||||||
|
%{_qt5_libdir}/libQt5WaylandClient.prl
|
||||||
|
%{_qt5_libdir}/cmake/Qt5WaylandCompositor/Qt5WaylandCompositorConfig*.cmake
|
||||||
%{_qt5_libdir}/pkgconfig/*.pc
|
%{_qt5_libdir}/pkgconfig/*.pc
|
||||||
|
%{_qt5_archdatadir}/mkspecs/modules/*.pri
|
||||||
|
%{_qt5_libdir}/cmake/Qt5WaylandCompositor/
|
||||||
%{_qt5_libdir}/cmake/Qt5Gui/Qt5Gui_*.cmake
|
%{_qt5_libdir}/cmake/Qt5Gui/Qt5Gui_*.cmake
|
||||||
%{_qt5_libdir}/cmake/Qt5WaylandClient/
|
%{_qt5_libdir}/cmake/Qt5WaylandClient/
|
||||||
%{_qt5_libdir}/cmake/Qt5WaylandCompositor/
|
|
||||||
|
|
||||||
%files help
|
%files examples
|
||||||
%{_qt5_examplesdir}/wayland/
|
%{_qt5_examplesdir}/wayland/
|
||||||
|
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Mon Aug 21 2023 peijiankang <peijiankang@kylinos.cn> - 5.15.10-1
|
||||||
|
- update to upstream version 5.15.10
|
||||||
|
|
||||||
* Wed Oct 13 2021 peijiankang <peijiankang@kylinos.cn> - 5.15.2-1
|
* Wed Oct 13 2021 peijiankang <peijiankang@kylinos.cn> - 5.15.2-1
|
||||||
- update to upstream version 5.15.2
|
- update to upstream version 5.15.2
|
||||||
|
|
||||||
|
|||||||
@ -1,33 +1,69 @@
|
|||||||
From d533901938a996367d7b6f87b0214f5a17098aed Mon Sep 17 00:00:00 2001
|
diff --git a/src/client/qwaylandabstractdecoration_p.h b/src/client/qwaylandabstractdecoration_p.h
|
||||||
From: Jan Grulich <jgrulich@redhat.com>
|
index 81c8e17..61cbde7 100644
|
||||||
Date: Tue, 23 Mar 2021 16:03:22 +0100
|
--- a/src/client/qwaylandabstractdecoration_p.h
|
||||||
Subject: [PATCH] Client: expose toplevel window state
|
+++ b/src/client/qwaylandabstractdecoration_p.h
|
||||||
|
@@ -82,6 +82,12 @@ class Q_WAYLAND_CLIENT_EXPORT QWaylandAbstractDecoration : public QObject
|
||||||
QWaylandWindow has only basic information about window state, like if
|
Q_OBJECT
|
||||||
it's active or maximized, but it has no information about tiling, which
|
Q_DECLARE_PRIVATE(QWaylandAbstractDecoration)
|
||||||
can be useful for client-side decorations. We also need to bump version
|
public:
|
||||||
of xdg-shell protocol we support, because additional states are not in
|
+ enum MarginsType {
|
||||||
the version currently supported by QtWayland. It shouldn't be a problem
|
+ Full,
|
||||||
to increase the version as the new version adds just these additional
|
+ ShadowsExcluded,
|
||||||
window states.
|
+ ShadowsOnly
|
||||||
|
+ };
|
||||||
Change-Id: I4c46516d9c7296c69ea51a022b3bdb4ca06bef8d
|
+
|
||||||
Reviewed-by: David Edmundson <davidedmundson@kde.org>
|
QWaylandAbstractDecoration();
|
||||||
---
|
~QWaylandAbstractDecoration() override;
|
||||||
src/client/qwaylandwindow.cpp | 15 +++++++++++++++
|
|
||||||
src/client/qwaylandwindow_p.h | 16 ++++++++++++++++
|
@@ -91,7 +97,8 @@ public:
|
||||||
.../xdg-shell/qwaylandxdgshell.cpp | 16 +++++++++++++++-
|
void update();
|
||||||
.../xdg-shell/qwaylandxdgshell_p.h | 3 ++-
|
bool isDirty() const;
|
||||||
4 files changed, 48 insertions(+), 2 deletions(-)
|
|
||||||
|
- virtual QMargins margins() const = 0;
|
||||||
|
+ virtual QMargins margins(MarginsType marginsType = Full) const = 0;
|
||||||
|
+
|
||||||
|
QWindow *window() const;
|
||||||
|
const QImage &contentImage();
|
||||||
|
|
||||||
diff --git a/src/client/qwaylandwindow.cpp b/src/client/qwaylandwindow.cpp
|
diff --git a/src/client/qwaylandwindow.cpp b/src/client/qwaylandwindow.cpp
|
||||||
index c35ccab15..65a914976 100644
|
index ec232cd..54b27f1 100644
|
||||||
--- a/src/client/qwaylandwindow.cpp
|
--- a/src/client/qwaylandwindow.cpp
|
||||||
+++ b/src/client/qwaylandwindow.cpp
|
+++ b/src/client/qwaylandwindow.cpp
|
||||||
@@ -1107,6 +1107,21 @@ bool QWaylandWindow::setMouseGrabEnabled(bool grab)
|
@@ -383,6 +383,16 @@ void QWaylandWindow::setGeometry(const QRect &r)
|
||||||
return true;
|
void QWaylandWindow::resizeFromApplyConfigure(const QSize &sizeWithMargins, const QPoint &offset)
|
||||||
|
{
|
||||||
|
QMargins margins = frameMargins();
|
||||||
|
+
|
||||||
|
+ // Exclude shadows from margins once they are excluded from window geometry
|
||||||
|
+ // 1) First resizeFromApplyConfigure() call will have sizeWithMargins equal to surfaceSize()
|
||||||
|
+ // which has full margins (shadows included).
|
||||||
|
+ // 2) Following resizeFromApplyConfigure() calls should have sizeWithMargins equal to
|
||||||
|
+ // windowContentGeometry() which excludes shadows, therefore in this case we have to
|
||||||
|
+ // exclude them too in order not to accidentally apply smaller size to the window.
|
||||||
|
+ if (mWindowDecoration && (sizeWithMargins != surfaceSize()))
|
||||||
|
+ margins = mWindowDecoration->margins(QWaylandAbstractDecoration::ShadowsExcluded);
|
||||||
|
+
|
||||||
|
int widthWithoutMargins = qMax(sizeWithMargins.width() - (margins.left() + margins.right()), 1);
|
||||||
|
int heightWithoutMargins = qMax(sizeWithMargins.height() - (margins.top() + margins.bottom()), 1);
|
||||||
|
QRect geometry(windowGeometry().topLeft(), QSize(widthWithoutMargins, heightWithoutMargins));
|
||||||
|
@@ -710,7 +720,12 @@ QSize QWaylandWindow::surfaceSize() const
|
||||||
|
*/
|
||||||
|
QRect QWaylandWindow::windowContentGeometry() const
|
||||||
|
{
|
||||||
|
- return QRect(QPoint(), surfaceSize());
|
||||||
|
+ QMargins shadowMargins;
|
||||||
|
+
|
||||||
|
+ if (mWindowDecoration)
|
||||||
|
+ shadowMargins = mWindowDecoration->margins(QWaylandAbstractDecoration::ShadowsOnly);
|
||||||
|
+
|
||||||
|
+ return QRect(QPoint(shadowMargins.left(), shadowMargins.top()), surfaceSize().shrunkBy(shadowMargins));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
@@ -1111,6 +1126,16 @@ Qt::WindowStates QWaylandWindow::windowStates() const
|
||||||
|
return mLastReportedWindowStates;
|
||||||
|
}
|
||||||
|
|
||||||
+QWaylandWindow::ToplevelWindowTilingStates QWaylandWindow::toplevelWindowTilingStates() const
|
+QWaylandWindow::ToplevelWindowTilingStates QWaylandWindow::toplevelWindowTilingStates() const
|
||||||
+{
|
+{
|
||||||
+ return mLastReportedToplevelWindowTilingStates;
|
+ return mLastReportedToplevelWindowTilingStates;
|
||||||
@ -37,23 +73,18 @@ index c35ccab15..65a914976 100644
|
|||||||
+{
|
+{
|
||||||
+ mLastReportedToplevelWindowTilingStates = states;
|
+ mLastReportedToplevelWindowTilingStates = states;
|
||||||
+}
|
+}
|
||||||
+
|
|
||||||
+Qt::WindowStates QWaylandWindow::windowStates() const
|
|
||||||
+{
|
|
||||||
+ return mLastReportedWindowStates;
|
|
||||||
+}
|
|
||||||
+
|
+
|
||||||
void QWaylandWindow::handleWindowStatesChanged(Qt::WindowStates states)
|
void QWaylandWindow::handleWindowStatesChanged(Qt::WindowStates states)
|
||||||
{
|
{
|
||||||
createDecoration();
|
createDecoration();
|
||||||
diff --git a/src/client/qwaylandwindow_p.h b/src/client/qwaylandwindow_p.h
|
diff --git a/src/client/qwaylandwindow_p.h b/src/client/qwaylandwindow_p.h
|
||||||
index 5f134568b..1d743f4e4 100644
|
index 1907f10..33a3b83 100644
|
||||||
--- a/src/client/qwaylandwindow_p.h
|
--- a/src/client/qwaylandwindow_p.h
|
||||||
+++ b/src/client/qwaylandwindow_p.h
|
+++ b/src/client/qwaylandwindow_p.h
|
||||||
@@ -95,6 +95,15 @@ class Q_WAYLAND_CLIENT_EXPORT QWaylandWindow : public QObject, public QPlatformW
|
@@ -95,6 +95,15 @@ public:
|
||||||
Vulkan
|
Vulkan
|
||||||
};
|
};
|
||||||
|
|
||||||
+ enum ToplevelWindowTilingState {
|
+ enum ToplevelWindowTilingState {
|
||||||
+ WindowNoState = 0,
|
+ WindowNoState = 0,
|
||||||
+ WindowTiledLeft = 1,
|
+ WindowTiledLeft = 1,
|
||||||
@ -65,56 +96,81 @@ index 5f134568b..1d743f4e4 100644
|
|||||||
+
|
+
|
||||||
QWaylandWindow(QWindow *window, QWaylandDisplay *display);
|
QWaylandWindow(QWindow *window, QWaylandDisplay *display);
|
||||||
~QWaylandWindow() override;
|
~QWaylandWindow() override;
|
||||||
|
|
||||||
@@ -145,6 +154,10 @@ class Q_WAYLAND_CLIENT_EXPORT QWaylandWindow : public QObject, public QPlatformW
|
@@ -148,6 +157,9 @@ public:
|
||||||
void handleContentOrientationChange(Qt::ScreenOrientation orientation) override;
|
void handleContentOrientationChange(Qt::ScreenOrientation orientation) override;
|
||||||
void setOrientationMask(Qt::ScreenOrientations mask);
|
void setOrientationMask(Qt::ScreenOrientations mask);
|
||||||
|
|
||||||
+ ToplevelWindowTilingStates toplevelWindowTilingStates() const;
|
+ ToplevelWindowTilingStates toplevelWindowTilingStates() const;
|
||||||
+ void handleToplevelWindowTilingStatesChanged(ToplevelWindowTilingStates states);
|
+ void handleToplevelWindowTilingStatesChanged(ToplevelWindowTilingStates states);
|
||||||
+
|
+
|
||||||
+ Qt::WindowStates windowStates() const;
|
|
||||||
void setWindowState(Qt::WindowStates states) override;
|
void setWindowState(Qt::WindowStates states) override;
|
||||||
void setWindowFlags(Qt::WindowFlags flags) override;
|
void setWindowFlags(Qt::WindowFlags flags) override;
|
||||||
void handleWindowStatesChanged(Qt::WindowStates states);
|
void handleWindowStatesChanged(Qt::WindowStates states);
|
||||||
@@ -260,6 +273,7 @@ public slots:
|
@@ -260,6 +272,7 @@ protected:
|
||||||
QRegion mMask;
|
QRegion mMask;
|
||||||
QRegion mOpaqueArea;
|
QRegion mOpaqueArea;
|
||||||
Qt::WindowStates mLastReportedWindowStates = Qt::WindowNoState;
|
Qt::WindowStates mLastReportedWindowStates = Qt::WindowNoState;
|
||||||
+ ToplevelWindowTilingStates mLastReportedToplevelWindowTilingStates = WindowNoState;
|
+ ToplevelWindowTilingStates mLastReportedToplevelWindowTilingStates = WindowNoState;
|
||||||
|
|
||||||
QWaylandShmBackingStore *mBackingStore = nullptr;
|
QWaylandShmBackingStore *mBackingStore = nullptr;
|
||||||
QWaylandBuffer *mQueuedBuffer = nullptr;
|
QWaylandBuffer *mQueuedBuffer = nullptr;
|
||||||
@@ -295,6 +309,8 @@ public slots:
|
@@ -296,6 +309,8 @@ private:
|
||||||
friend class QWaylandSubSurface;
|
friend class QWaylandSubSurface;
|
||||||
};
|
};
|
||||||
|
|
||||||
+Q_DECLARE_OPERATORS_FOR_FLAGS(QWaylandWindow::ToplevelWindowTilingStates)
|
+Q_DECLARE_OPERATORS_FOR_FLAGS(QWaylandWindow::ToplevelWindowTilingStates)
|
||||||
+
|
+
|
||||||
inline QIcon QWaylandWindow::windowIcon() const
|
inline QIcon QWaylandWindow::windowIcon() const
|
||||||
{
|
{
|
||||||
return mWindowIcon;
|
return mWindowIcon;
|
||||||
|
diff --git a/src/plugins/decorations/bradient/main.cpp b/src/plugins/decorations/bradient/main.cpp
|
||||||
|
index e75fda3..72dda67 100644
|
||||||
|
--- a/src/plugins/decorations/bradient/main.cpp
|
||||||
|
+++ b/src/plugins/decorations/bradient/main.cpp
|
||||||
|
@@ -72,7 +72,7 @@ class Q_WAYLAND_CLIENT_EXPORT QWaylandBradientDecoration : public QWaylandAbstra
|
||||||
|
public:
|
||||||
|
QWaylandBradientDecoration();
|
||||||
|
protected:
|
||||||
|
- QMargins margins() const override;
|
||||||
|
+ QMargins margins(MarginsType marginsType = Full) const override;
|
||||||
|
void paint(QPaintDevice *device) override;
|
||||||
|
bool handleMouse(QWaylandInputDevice *inputDevice, const QPointF &local, const QPointF &global,Qt::MouseButtons b,Qt::KeyboardModifiers mods) override;
|
||||||
|
bool handleTouch(QWaylandInputDevice *inputDevice, const QPointF &local, const QPointF &global, Qt::TouchPointState state, Qt::KeyboardModifiers mods) override;
|
||||||
|
@@ -129,8 +129,11 @@ QRectF QWaylandBradientDecoration::minimizeButtonRect() const
|
||||||
|
(margins().top() - BUTTON_WIDTH) / 2, BUTTON_WIDTH, BUTTON_WIDTH);
|
||||||
|
}
|
||||||
|
|
||||||
|
-QMargins QWaylandBradientDecoration::margins() const
|
||||||
|
+QMargins QWaylandBradientDecoration::margins(MarginsType marginsType) const
|
||||||
|
{
|
||||||
|
+ if (marginsType == ShadowsOnly)
|
||||||
|
+ return QMargins();
|
||||||
|
+
|
||||||
|
return QMargins(3, 30, 3, 3);
|
||||||
|
}
|
||||||
|
|
||||||
diff --git a/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp b/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp
|
diff --git a/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp b/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp
|
||||||
index 965bc261d..5d9a21f81 100644
|
index 2666df2..8d8ac85 100644
|
||||||
--- a/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp
|
--- a/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp
|
||||||
+++ b/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp
|
+++ b/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp
|
||||||
@@ -94,6 +94,7 @@ void QWaylandXdgSurface::Toplevel::applyConfigure()
|
@@ -88,6 +88,7 @@ void QWaylandXdgSurface::Toplevel::applyConfigure()
|
||||||
// TODO: none of the other plugins send WindowActive either, but is it on purpose?
|
&& !m_xdgSurface->m_window->display()->isKeyboardAvailable())
|
||||||
Qt::WindowStates statesWithoutActive = m_pending.states & ~Qt::WindowActive;
|
m_xdgSurface->m_window->display()->handleWindowDeactivated(m_xdgSurface->m_window);
|
||||||
|
|
||||||
+ m_xdgSurface->m_window->handleToplevelWindowTilingStatesChanged(m_toplevelStates);
|
+ m_xdgSurface->m_window->handleToplevelWindowTilingStatesChanged(m_toplevelStates);
|
||||||
m_xdgSurface->m_window->handleWindowStatesChanged(statesWithoutActive);
|
m_xdgSurface->m_window->handleWindowStatesChanged(m_pending.states);
|
||||||
|
|
||||||
if (m_pending.size.isEmpty()) {
|
if (m_pending.size.isEmpty()) {
|
||||||
@@ -126,6 +127,7 @@ void QWaylandXdgSurface::Toplevel::xdg_toplevel_configure(int32_t width, int32_t
|
@@ -120,6 +121,7 @@ void QWaylandXdgSurface::Toplevel::xdg_toplevel_configure(int32_t width, int32_t
|
||||||
size_t numStates = states->size / sizeof(uint32_t);
|
size_t numStates = states->size / sizeof(uint32_t);
|
||||||
|
|
||||||
m_pending.states = Qt::WindowNoState;
|
m_pending.states = Qt::WindowNoState;
|
||||||
+ m_toplevelStates = QWaylandWindow::WindowNoState;
|
+ m_toplevelStates = QWaylandWindow::WindowNoState;
|
||||||
|
|
||||||
for (size_t i = 0; i < numStates; i++) {
|
for (size_t i = 0; i < numStates; i++) {
|
||||||
switch (xdgStates[i]) {
|
switch (xdgStates[i]) {
|
||||||
@@ -138,6 +140,18 @@ void QWaylandXdgSurface::Toplevel::xdg_toplevel_configure(int32_t width, int32_t
|
@@ -132,6 +134,18 @@ void QWaylandXdgSurface::Toplevel::xdg_toplevel_configure(int32_t width, int32_t
|
||||||
case XDG_TOPLEVEL_STATE_FULLSCREEN:
|
case XDG_TOPLEVEL_STATE_FULLSCREEN:
|
||||||
m_pending.states |= Qt::WindowFullScreen;
|
m_pending.states |= Qt::WindowFullScreen;
|
||||||
break;
|
break;
|
||||||
@ -133,9 +189,9 @@ index 965bc261d..5d9a21f81 100644
|
|||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -469,7 +483,7 @@ void QWaylandXdgSurface::xdg_surface_configure(uint32_t serial)
|
@@ -458,7 +472,7 @@ void QWaylandXdgSurface::xdg_surface_configure(uint32_t serial)
|
||||||
}
|
}
|
||||||
|
|
||||||
QWaylandXdgShell::QWaylandXdgShell(QWaylandDisplay *display, uint32_t id, uint32_t availableVersion)
|
QWaylandXdgShell::QWaylandXdgShell(QWaylandDisplay *display, uint32_t id, uint32_t availableVersion)
|
||||||
- : QtWayland::xdg_wm_base(display->wl_registry(), id, qMin(availableVersion, 1u))
|
- : QtWayland::xdg_wm_base(display->wl_registry(), id, qMin(availableVersion, 1u))
|
||||||
+ : QtWayland::xdg_wm_base(display->wl_registry(), id, qMin(availableVersion, 2u))
|
+ : QtWayland::xdg_wm_base(display->wl_registry(), id, qMin(availableVersion, 2u))
|
||||||
@ -143,30 +199,30 @@ index 965bc261d..5d9a21f81 100644
|
|||||||
{
|
{
|
||||||
display->addRegistryListener(&QWaylandXdgShell::handleRegistryGlobal, this);
|
display->addRegistryListener(&QWaylandXdgShell::handleRegistryGlobal, this);
|
||||||
diff --git a/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell_p.h b/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell_p.h
|
diff --git a/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell_p.h b/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell_p.h
|
||||||
index 5aeec2eb9..e3a90c547 100644
|
index 0c98be3..d791213 100644
|
||||||
--- a/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell_p.h
|
--- a/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell_p.h
|
||||||
+++ b/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell_p.h
|
+++ b/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell_p.h
|
||||||
@@ -58,6 +58,7 @@
|
@@ -58,6 +58,7 @@
|
||||||
|
|
||||||
#include <QtWaylandClient/qtwaylandclientglobal.h>
|
#include <QtWaylandClient/qtwaylandclientglobal.h>
|
||||||
#include <QtWaylandClient/private/qwaylandshellsurface_p.h>
|
#include <QtWaylandClient/private/qwaylandshellsurface_p.h>
|
||||||
+#include <QtWaylandClient/private/qwaylandwindow_p.h>
|
+#include <QtWaylandClient/private/qwaylandwindow_p.h>
|
||||||
|
|
||||||
#include <QtCore/QSize>
|
#include <QtCore/QSize>
|
||||||
#include <QtGui/QRegion>
|
#include <QtGui/QRegion>
|
||||||
@@ -69,7 +70,6 @@ class QWindow;
|
@@ -69,7 +70,6 @@ class QWindow;
|
||||||
namespace QtWaylandClient {
|
namespace QtWaylandClient {
|
||||||
|
|
||||||
class QWaylandDisplay;
|
class QWaylandDisplay;
|
||||||
-class QWaylandWindow;
|
-class QWaylandWindow;
|
||||||
class QWaylandInputDevice;
|
class QWaylandInputDevice;
|
||||||
class QWaylandXdgShell;
|
class QWaylandXdgShell;
|
||||||
|
|
||||||
@@ -125,6 +125,7 @@ class Q_WAYLAND_CLIENT_EXPORT QWaylandXdgSurface : public QWaylandShellSurface,
|
@@ -123,6 +123,7 @@ private:
|
||||||
QSize size = {0, 0};
|
QSize size = {0, 0};
|
||||||
Qt::WindowStates states = Qt::WindowNoState;
|
Qt::WindowStates states = Qt::WindowNoState;
|
||||||
} m_pending, m_applied;
|
} m_pending, m_applied;
|
||||||
+ QWaylandWindow::ToplevelWindowTilingStates m_toplevelStates = QWaylandWindow::WindowNoState;
|
+ QWaylandWindow::ToplevelWindowTilingStates m_toplevelStates = QWaylandWindow::WindowNoState;
|
||||||
QSize m_normalSize;
|
QSize m_normalSize;
|
||||||
|
|
||||||
QWaylandXdgSurface *m_xdgSurface = nullptr;
|
QWaylandXdgSurface *m_xdgSurface = nullptr;
|
||||||
BIN
qtwayland-everywhere-opensource-src-5.15.10.tar.xz
Normal file
BIN
qtwayland-everywhere-opensource-src-5.15.10.tar.xz
Normal file
Binary file not shown.
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user